Merge pull request #34342 from coolljt0725/fallback_to_naive_diff

Fallback to use naive diff driver if enable CONFIG_OVERLAY_FS_REDIRECT_DIR
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 79ff089..58ed550 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -14,6 +14,8 @@
 daemon/logger/awslogs/**                @samuelkarp  
 hack/**                                 @dnephin @tianon
 hack/integration-cli-on-swarm/**        @AkihiroSuda
+integration-cli/**                      @dnephin @vdemeester
+integration/**                          @dnephin @vdemeester
 pkg/testutil/**                         @dnephin
 plugin/**                               @cpuguy83
 project/**                              @thaJeztah
diff --git a/.gitignore b/.gitignore
index 943e7f3..93a6df4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,7 @@
 *.exe
 *.exe~
 *.orig
-*.test
+test.main
 .*.swp
 .DS_Store
 # a .bashrc may be added to customize the build environment
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bbedc49..e9db48f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2284,7 +2284,7 @@
 - Use mock for search tests.
 - Update to double-dash everywhere.
 - Move .dockerenv parsing to lxc driver.
-- Move all bind-mounts in the container inside the namespace.
+- Move all bind mounts in the container inside the namespace.
 - Don't use separate bind mount for container.
 - Always symlink /dev/ptmx for libcontainer.
 - Don't kill by pid for other drivers.
@@ -2719,7 +2719,7 @@
 + Implement `docker log -f` to stream logs
 + Add env variable to disable kernel version warning
 + Add -format to `docker inspect`
-+ Support bind-mount for files
++ Support bind mount for files
 - Fix bridge creation on RHEL
 - Fix image size calculation
 - Make sure iptables are called even if the bridge already exists
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 917214c..c55e13b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -155,10 +155,11 @@
 	your intentions, and name it XXXX-something where XXXX is the number of the
 	issue.
 
-Submit unit tests for your changes. Go has a great test framework built in; use
-it! Take a look at existing tests for inspiration. [Run the full test
-suite](https://docs.docker.com/opensource/project/test-and-docs/) on your branch before
-submitting a pull request.
+Submit tests for your changes. See [TESTING.md](./TESTING.md) for details.
+
+If your changes need integration tests, write them against the API. The `cli`
+integration tests are slowly either migrated to API tests or moved away as unit
+tests in `docker/cli` and end-to-end tests for docker.
 
 Update the documentation when creating or modifying features. Test your
 documentation changes for clarity, concision, and correctness, as well as a
@@ -251,10 +252,9 @@
 high majority of submissions should have a single commit, so if in doubt: squash
 down to one.
 
-After every commit, [make sure the test suite passes]
-(https://docs.docker.com/opensource/project/test-and-docs/). Include documentation
-changes in the same pull request so that a revert would remove all traces of
-the feature or fix.
+After every commit, [make sure the test suite passes](./TESTING.md). Include
+documentation changes in the same pull request so that a revert would remove
+all traces of the feature or fix.
 
 Include an issue reference like `Closes #XXXX` or `Fixes #XXXX` in commits that
 close an issue. Including references automatically closes the issue on a merge.
diff --git a/Dockerfile b/Dockerfile
index 33e88dc..3d153b6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,7 +9,7 @@
 # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
 #
 # # Run the test suite:
-# docker run -e DOCKER_GITCOMMIT=foo --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
+# docker run -e DOCKER_GITCOMMIT=foo --privileged docker hack/make.sh test-unit test-integration test-docker-py
 #
 # # Publish a release:
 # docker run --privileged \
@@ -23,7 +23,7 @@
 # the case. Therefore, you don't have to disable it anymore.
 #
 
-FROM debian:jessie
+FROM debian:stretch
 
 # allow replacing httpredir or deb mirror
 ARG APT_MIRROR=deb.debian.org
@@ -51,57 +51,35 @@
 	less \
 	libapparmor-dev \
 	libcap-dev \
+	libdevmapper-dev \
 	libnl-3-dev \
 	libprotobuf-c0-dev \
 	libprotobuf-dev \
-	libsystemd-journal-dev \
+	libseccomp-dev \
+	libsystemd-dev \
 	libtool \
+	libudev-dev \
 	mercurial \
 	net-tools \
 	pkg-config \
 	protobuf-compiler \
 	protobuf-c-compiler \
+	python-backports.ssl-match-hostname \
 	python-dev \
 	python-mock \
 	python-pip \
+	python-requests \
+	python-setuptools \
 	python-websocket \
+	python-wheel \
 	tar \
+	thin-provisioning-tools \
 	vim \
 	vim-common \
 	xfsprogs \
 	zip \
 	--no-install-recommends \
 	&& pip install awscli==1.10.15
-# Get lvm2 source for compiling statically
-ENV LVM2_VERSION 2.02.103
-RUN mkdir -p /usr/local/lvm2 \
-	&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
-		| tar -xzC /usr/local/lvm2 --strip-components=1
-# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
-
-# Compile and install lvm2
-RUN cd /usr/local/lvm2 \
-	&& ./configure \
-		--build="$(gcc -print-multiarch)" \
-		--enable-static_link \
-	&& make device-mapper \
-	&& make install_device-mapper
-# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
-
-# Install seccomp: the version shipped upstream is too old
-ENV SECCOMP_VERSION 2.3.2
-RUN set -x \
-	&& export SECCOMP_PATH="$(mktemp -d)" \
-	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
-		| tar -xzC "$SECCOMP_PATH" --strip-components=1 \
-	&& ( \
-		cd "$SECCOMP_PATH" \
-		&& ./configure --prefix=/usr/local \
-		&& make \
-		&& make install \
-		&& ldconfig \
-	) \
-	&& rm -rf "$SECCOMP_PATH"
 
 # Install Go
 # IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines
@@ -115,17 +93,6 @@
 ENV PATH /go/bin:/usr/local/go/bin:$PATH
 ENV GOPATH /go
 
-# Dependency for golint
-ENV GO_TOOLS_COMMIT 823804e1ae08dbb14eb807afc7db9993bc9e3cc3
-RUN git clone https://github.com/golang/tools.git /go/src/golang.org/x/tools \
-	&& (cd /go/src/golang.org/x/tools && git checkout -q $GO_TOOLS_COMMIT)
-
-# Grab Go's lint tool
-ENV GO_LINT_COMMIT 32a87160691b3c96046c0c678fe57c5bef761456
-RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint \
-	&& (cd /go/src/github.com/golang/lint && git checkout -q $GO_LINT_COMMIT) \
-	&& go install -v github.com/golang/lint/golint
-
 # Install CRIU for checkpoint/restore support
 ENV CRIU_VERSION 2.12.1
 # Install dependancy packages specific to criu
@@ -168,9 +135,6 @@
 # Get the "docker-py" source so we can run their integration tests
 ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
 # To run integration tests docker-pycreds is required.
-# Before running the integration tests conftest.py is
-# loaded which results in loads auth.py that
-# imports the docker-pycreds module.
 RUN git clone https://github.com/docker/docker-py.git /docker-py \
 	&& cd /docker-py \
 	&& git checkout -q $DOCKER_PY_COMMIT \
@@ -215,7 +179,7 @@
 # Please edit hack/dockerfile/install-binaries.sh to update them.
 COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
 COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
-RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli
+RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli gometalinter
 ENV PATH=/usr/local/cli:$PATH
 
 # Activate bash completion and include Docker's completion if mounted with DOCKER_BASH_COMPLETION_PATH
@@ -227,3 +191,6 @@
 
 # Upload docker source
 COPY . /go/src/github.com/docker/docker
+
+# Options for hack/validate/gometalinter
+ENV GOMETALINTER_OPTS="--deadline 2m"
diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64
index cabcda2..8396d57 100644
--- a/Dockerfile.aarch64
+++ b/Dockerfile.aarch64
@@ -9,20 +9,26 @@
 # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
 #
 # # Run the test suite:
-# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
+# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
 #
 # Note: AppArmor used to mess with privileged mode, but this is no longer
 # the case. Therefore, you don't have to disable it anymore.
 #
 
-FROM aarch64/ubuntu:xenial
+FROM arm64v8/debian:stretch
+
+# allow replacing httpredir or deb mirror
+ARG APT_MIRROR=deb.debian.org
+RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list
 
 # Packaged dependencies
 RUN apt-get update && apt-get install -y \
 	apparmor \
+	apt-utils \
 	aufs-tools \
 	automake \
 	bash-completion \
+	bsdmainutils \
 	btrfs-tools \
 	build-essential \
 	cmake \
@@ -32,71 +38,44 @@
 	g++ \
 	gcc \
 	git \
+	golang \
 	iptables \
 	jq \
+	less \
 	libapparmor-dev \
-	libc6-dev \
 	libcap-dev \
+	libdevmapper-dev \
+	libnl-3-dev \
+	libprotobuf-c0-dev \
+	libprotobuf-dev \
+	libseccomp-dev \
 	libsystemd-dev \
-	libyaml-dev \
+	libtool \
+	libudev-dev \
 	mercurial \
 	net-tools \
-	parallel \
 	pkg-config \
+	protobuf-compiler \
+	protobuf-c-compiler \
+	python-backports.ssl-match-hostname \
 	python-dev \
 	python-mock \
 	python-pip \
+	python-requests \
 	python-setuptools \
 	python-websocket \
-	golang-go \
-	iproute2 \
-	iputils-ping \
+	python-wheel \
+	tar \
+	thin-provisioning-tools \
+	vim \
 	vim-common \
+	xfsprogs \
+	zip \
 	--no-install-recommends
 
-# Get lvm2 source for compiling statically
-ENV LVM2_VERSION 2.02.103
-RUN mkdir -p /usr/local/lvm2 \
-	&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
-		| tar -xzC /usr/local/lvm2 --strip-components=1
-# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
-
-# Fix platform enablement in lvm2 to support aarch64 properly
-RUN set -e \
-	&& for f in config.guess config.sub; do \
-		curl -fsSL -o "/usr/local/lvm2/autoconf/$f" "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=$f;hb=HEAD"; \
-	done
-# "arch.c:78:2: error: #error the arch code needs to know about your machine type"
-
-# Compile and install lvm2
-RUN cd /usr/local/lvm2 \
-	&& ./configure \
-		--build="$(gcc -print-multiarch)" \
-		--enable-static_link \
-	&& make device-mapper \
-	&& make install_device-mapper
-# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
-
-# Install seccomp: the version shipped upstream is too old
-ENV SECCOMP_VERSION 2.3.2
-RUN set -x \
-	&& export SECCOMP_PATH="$(mktemp -d)" \
-	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
-		| tar -xzC "$SECCOMP_PATH" --strip-components=1 \
-	&& ( \
-		cd "$SECCOMP_PATH" \
-		&& ./configure --prefix=/usr/local \
-		&& make \
-		&& make install \
-		&& ldconfig \
-	) \
-	&& rm -rf "$SECCOMP_PATH"
-
 # Install Go
 # We don't have official binary golang 1.7.5 tarballs for ARM64, either for Go or
-# bootstrap, so we use golang-go (1.6) as bootstrap to build Go from source code.
-# We don't use the official ARMv6 released binaries as a GOROOT_BOOTSTRAP, because
-# not all ARM64 platforms support 32-bit mode. 32-bit mode is optional for ARMv8.
+# bootstrap, so we use Debian golang (1.7) as bootstrap to build Go from source code.
 # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
 ENV GO_VERSION 1.8.3
 RUN mkdir /usr/src/go && curl -fsSL https://golang.org/dl/go${GO_VERSION}.src.tar.gz | tar -v -C /usr/src/go -xz --strip-components=1 \
@@ -106,17 +85,6 @@
 ENV PATH /go/bin:/usr/src/go/bin:$PATH
 ENV GOPATH /go
 
-# Dependency for golint
-ENV GO_TOOLS_COMMIT 823804e1ae08dbb14eb807afc7db9993bc9e3cc3
-RUN git clone https://github.com/golang/tools.git /go/src/golang.org/x/tools \
-	&& (cd /go/src/golang.org/x/tools && git checkout -q $GO_TOOLS_COMMIT)
-
-# Grab Go's lint tool
-ENV GO_LINT_COMMIT 32a87160691b3c96046c0c678fe57c5bef761456
-RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint \
-	&& (cd /go/src/github.com/golang/lint && git checkout -q $GO_LINT_COMMIT) \
-	&& go install -v github.com/golang/lint/golint
-
 # Only install one version of the registry, because old version which support
 # schema1 manifests is not working on ARM64, we should skip integration-cli
 # tests for schema1 manifests on ARM64.
@@ -143,13 +111,10 @@
 
 # Get the "docker-py" source so we can run their integration tests
 ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
-# Before running the integration tests conftest.py is
-# loaded which results in loads auth.py that
-# imports the docker-pycreds module.
+# To run integration tests docker-pycreds is required.
 RUN git clone https://github.com/docker/docker-py.git /docker-py \
 	&& cd /docker-py \
 	&& git checkout -q $DOCKER_PY_COMMIT \
-	&& pip install wheel \
 	&& pip install docker-pycreds==0.2.1 \
 	&& pip install -r test-requirements.txt
 
@@ -192,7 +157,7 @@
 # Please edit hack/dockerfile/install-binaries.sh to update them.
 COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
 COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
-RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli
+RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli gometalinter
 ENV PATH=/usr/local/cli:$PATH
 
 # Wrap all commands in the "docker-in-docker" script to allow nested containers
@@ -200,3 +165,6 @@
 
 # Upload docker source
 COPY . /go/src/github.com/docker/docker
+
+# Options for hack/validate/gometalinter
+ENV GOMETALINTER_OPTS="--deadline 4m -j2"
diff --git a/Dockerfile.armhf b/Dockerfile.armhf
index dd1f536..5cd257a 100644
--- a/Dockerfile.armhf
+++ b/Dockerfile.armhf
@@ -9,13 +9,13 @@
 # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
 #
 # # Run the test suite:
-# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
+# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
 #
 # Note: AppArmor used to mess with privileged mode, but this is no longer
 # the case. Therefore, you don't have to disable it anymore.
 #
 
-FROM armhf/debian:jessie
+FROM arm32v7/debian:stretch
 
 # allow replacing httpredir or deb mirror
 ARG APT_MIRROR=deb.debian.org
@@ -39,36 +39,28 @@
 	net-tools \
 	libapparmor-dev \
 	libcap-dev \
-	libsystemd-journal-dev \
+	libdevmapper-dev \
+	libseccomp-dev \
+	libsystemd-dev \
 	libtool \
+	libudev-dev \
 	mercurial \
 	pkg-config \
+	python-backports.ssl-match-hostname \
 	python-dev \
 	python-mock \
 	python-pip \
+	python-requests \
+	python-setuptools \
 	python-websocket \
+	python-wheel \
 	xfsprogs \
 	tar \
+	thin-provisioning-tools \
 	vim-common \
 	--no-install-recommends \
 	&& pip install awscli==1.10.15
 
-# Get lvm2 source for compiling statically
-ENV LVM2_VERSION 2.02.103
-RUN mkdir -p /usr/local/lvm2 \
-	&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
-		| tar -xzC /usr/local/lvm2 --strip-components=1
-# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
-
-# Compile and install lvm2
-RUN cd /usr/local/lvm2 \
-	&& ./configure \
-		--build="$(gcc -print-multiarch)" \
-		--enable-static_link \
-	&& make device-mapper \
-	&& make install_device-mapper
-# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
-
 # Install Go
 # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
 ENV GO_VERSION 1.8.3
@@ -81,32 +73,6 @@
 ENV GOARCH arm
 ENV GOARM 7
 
-# Dependency for golint
-ENV GO_TOOLS_COMMIT 823804e1ae08dbb14eb807afc7db9993bc9e3cc3
-RUN git clone https://github.com/golang/tools.git /go/src/golang.org/x/tools \
-	&& (cd /go/src/golang.org/x/tools && git checkout -q $GO_TOOLS_COMMIT)
-
-# Grab Go's lint tool
-ENV GO_LINT_COMMIT 32a87160691b3c96046c0c678fe57c5bef761456
-RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint \
-	&& (cd /go/src/github.com/golang/lint && git checkout -q $GO_LINT_COMMIT) \
-	&& go install -v github.com/golang/lint/golint
-
-# Install seccomp: the version shipped upstream is too old
-ENV SECCOMP_VERSION 2.3.2
-RUN set -x \
-	&& export SECCOMP_PATH="$(mktemp -d)" \
-	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
-		| tar -xzC "$SECCOMP_PATH" --strip-components=1 \
-	&& ( \
-		cd "$SECCOMP_PATH" \
-		&& ./configure --prefix=/usr/local \
-		&& make \
-		&& make install \
-		&& ldconfig \
-	) \
-	&& rm -rf "$SECCOMP_PATH"
-
 # Install two versions of the registry. The first is an older version that
 # only supports schema1 manifests. The second is a newer version that supports
 # both. This allows integration-cli tests to cover push/pull with both schema1
@@ -138,9 +104,11 @@
 
 # Get the "docker-py" source so we can run their integration tests
 ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
+# To run integration tests docker-pycreds is required.
 RUN git clone https://github.com/docker/docker-py.git /docker-py \
 	&& cd /docker-py \
 	&& git checkout -q $DOCKER_PY_COMMIT \
+	&& pip install docker-pycreds==0.2.1 \
 	&& pip install -r test-requirements.txt
 
 # Set user.email so crosbymichael's in-container merge commits go smoothly
@@ -173,10 +141,13 @@
 # Please edit hack/dockerfile/install-binaries.sh to update them.
 COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
 COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
-RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli
+RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli gometalinter
 ENV PATH=/usr/local/cli:$PATH
 
 ENTRYPOINT ["hack/dind"]
 
 # Upload docker source
 COPY . /go/src/github.com/docker/docker
+
+# Options for hack/validate/gometalinter
+ENV GOMETALINTER_OPTS="--deadline 10m -j2"
diff --git a/Dockerfile.e2e b/Dockerfile.e2e
new file mode 100644
index 0000000..3d700fa
--- /dev/null
+++ b/Dockerfile.e2e
@@ -0,0 +1,70 @@
+## Step 1: Build tests
+FROM golang:1.8.3-alpine3.6 as builder
+
+RUN apk add --update \
+    bash \
+    build-base \
+    curl \
+    lvm2-dev \
+    jq \
+    && rm -rf /var/cache/apk/*
+
+RUN mkdir -p /go/src/github.com/docker/docker/
+WORKDIR /go/src/github.com/docker/docker/
+
+# Generate frozen images
+COPY contrib/download-frozen-image-v2.sh contrib/download-frozen-image-v2.sh
+RUN contrib/download-frozen-image-v2.sh /output/docker-frozen-images \
+  buildpack-deps:jessie@sha256:85b379ec16065e4fe4127eb1c5fb1bcc03c559bd36dbb2e22ff496de55925fa6 \
+  busybox:latest@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f \
+  debian:jessie@sha256:72f784399fd2719b4cb4e16ef8e369a39dc67f53d978cd3e2e7bf4e502c7b793 \
+  hello-world:latest@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
+
+# Download Docker CLI binary
+COPY hack/dockerfile hack/dockerfile
+RUN hack/dockerfile/install-binaries.sh dockercli
+
+# Set tag and add sources
+ARG DOCKER_GITCOMMIT
+ENV DOCKER_GITCOMMIT=$DOCKER_GITCOMMIT
+ADD . .
+
+# Build DockerSuite.TestBuild* dependency
+RUN CGO_ENABLED=0 go build -o /output/httpserver github.com/docker/docker/contrib/httpserver
+
+# Build the integration tests and copy the resulting binaries to /output/tests
+RUN hack/make.sh build-integration-test-binary
+RUN mkdir -p /output/tests && find . -name test.main -exec cp --parents '{}' /output/tests \;
+
+## Step 2: Generate testing image
+FROM alpine:3.6 as runner
+
+# GNU tar is used for generating the emptyfs image
+RUN apk add --update \
+    bash \
+    ca-certificates \
+    g++ \
+    git \
+    iptables \
+    tar \
+    xz \
+    && rm -rf /var/cache/apk/*
+
+# Add an unprivileged user to be used for tests which need it
+RUN addgroup docker && adduser -D -G docker unprivilegeduser -s /bin/ash
+
+COPY contrib/httpserver/Dockerfile /tests/contrib/httpserver/Dockerfile
+COPY contrib/syscall-test /tests/contrib/syscall-test
+COPY integration-cli/fixtures /tests/integration-cli/fixtures
+
+COPY hack/test/e2e-run.sh /scripts/run.sh
+COPY hack/make/.ensure-emptyfs /scripts/ensure-emptyfs.sh
+
+COPY --from=builder /output/docker-frozen-images /docker-frozen-images
+COPY --from=builder /output/httpserver /tests/contrib/httpserver/httpserver
+COPY --from=builder /output/tests /tests
+COPY --from=builder /usr/local/bin/docker /usr/bin/docker
+
+ENV DOCKER_REMOTE_DAEMON=1 DOCKER_INTEGRATION_DAEMON_DEST=/
+
+ENTRYPOINT ["/scripts/run.sh"]
diff --git a/Dockerfile.ppc64le b/Dockerfile.ppc64le
index 43b84e4..5aca09a 100644
--- a/Dockerfile.ppc64le
+++ b/Dockerfile.ppc64le
@@ -9,13 +9,13 @@
 # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
 #
 # # Run the test suite:
-# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
+# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
 #
 # Note: AppArmor used to mess with privileged mode, but this is no longer
 # the case. Therefore, you don't have to disable it anymore.
 #
 
-FROM ppc64le/debian:jessie
+FROM ppc64le/debian:stretch
 
 # allow replacing httpredir or deb mirror
 ARG APT_MIRROR=deb.debian.org
@@ -40,58 +40,27 @@
 	net-tools \
 	libapparmor-dev \
 	libcap-dev \
-	libsystemd-journal-dev \
+	libdevmapper-dev \
+	libseccomp-dev \
+	libsystemd-dev \
 	libtool \
+	libudev-dev \
 	mercurial \
 	pkg-config \
+	python-backports.ssl-match-hostname \
 	python-dev \
 	python-mock \
 	python-pip \
+	python-requests \
+	python-setuptools \
 	python-websocket \
+	python-wheel \
 	xfsprogs \
 	tar \
+	thin-provisioning-tools \
 	vim-common \
 	--no-install-recommends
 
-# Get lvm2 source for compiling statically
-ENV LVM2_VERSION 2.02.103
-RUN mkdir -p /usr/local/lvm2 \
-	&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
-		| tar -xzC /usr/local/lvm2 --strip-components=1
-# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
-
-# Fix platform enablement in lvm2 to support ppc64le properly
-RUN set -e \
-	&& for f in config.guess config.sub; do \
-		curl -fsSL -o "/usr/local/lvm2/autoconf/$f" "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=$f;hb=HEAD"; \
-	done
-# "arch.c:78:2: error: #error the arch code needs to know about your machine type"
-
-# Compile and install lvm2
-RUN cd /usr/local/lvm2 \
-	&& ./configure \
-		--build="$(gcc -print-multiarch)" \
-		--enable-static_link \
-	&& make device-mapper \
-	&& make install_device-mapper
-# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
-
-# Install seccomp: the version shipped upstream is too old
-ENV SECCOMP_VERSION 2.3.2
-RUN set -x \
-        && export SECCOMP_PATH="$(mktemp -d)" \
-        && curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
-                | tar -xzC "$SECCOMP_PATH" --strip-components=1 \
-        && ( \
-                cd "$SECCOMP_PATH" \
-                && ./configure --prefix=/usr/local \
-                && make \
-                && make install \
-                && ldconfig \
-        ) \
-        && rm -rf "$SECCOMP_PATH"
-
-
 # Install Go
 # NOTE: official ppc64le go binaries weren't available until go 1.6.4 and 1.7.4
 # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
@@ -102,17 +71,6 @@
 ENV PATH /go/bin:/usr/local/go/bin:$PATH
 ENV GOPATH /go
 
-# Dependency for golint
-ENV GO_TOOLS_COMMIT 823804e1ae08dbb14eb807afc7db9993bc9e3cc3
-RUN git clone https://github.com/golang/tools.git /go/src/golang.org/x/tools \
-	&& (cd /go/src/golang.org/x/tools && git checkout -q $GO_TOOLS_COMMIT)
-
-# Grab Go's lint tool
-ENV GO_LINT_COMMIT 32a87160691b3c96046c0c678fe57c5bef761456
-RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint \
-	&& (cd /go/src/github.com/golang/lint && git checkout -q $GO_LINT_COMMIT) \
-	&& go install -v github.com/golang/lint/golint
-
 # Install two versions of the registry. The first is an older version that
 # only supports schema1 manifests. The second is a newer version that supports
 # both. This allows integration-cli tests to cover push/pull with both schema1
@@ -144,9 +102,11 @@
 
 # Get the "docker-py" source so we can run their integration tests
 ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
+# To run integration tests docker-pycreds is required.
 RUN git clone https://github.com/docker/docker-py.git /docker-py \
 	&& cd /docker-py \
 	&& git checkout -q $DOCKER_PY_COMMIT \
+	&& pip install docker-pycreds==0.2.1 \
 	&& pip install -r test-requirements.txt
 
 # Set user.email so crosbymichael's in-container merge commits go smoothly
@@ -179,7 +139,7 @@
 # Please edit hack/dockerfile/install-binaries.sh to update them.
 COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
 COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
-RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli
+RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli gometalinter
 ENV PATH=/usr/local/cli:$PATH
 
 # Wrap all commands in the "docker-in-docker" script to allow nested containers
diff --git a/Dockerfile.s390x b/Dockerfile.s390x
index 35ec683..32712ca 100644
--- a/Dockerfile.s390x
+++ b/Dockerfile.s390x
@@ -9,13 +9,13 @@
 # docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
 #
 # # Run the test suite:
-# docker run --privileged docker hack/make.sh test-unit test-integration-cli test-docker-py
+# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py
 #
 # Note: AppArmor used to mess with privileged mode, but this is no longer
 # the case. Therefore, you don't have to disable it anymore.
 #
 
-FROM s390x/debian:jessie
+FROM s390x/debian:stretch
 
 # Packaged dependencies
 RUN apt-get update && apt-get install -y \
@@ -36,57 +36,27 @@
 	net-tools \
 	libapparmor-dev \
 	libcap-dev \
-	libsystemd-journal-dev \
+	libdevmapper-dev \
+	libseccomp-dev \
+	libsystemd-dev \
 	libtool \
+	libudev-dev \
 	mercurial \
 	pkg-config \
+	python-backports.ssl-match-hostname \
 	python-dev \
 	python-mock \
 	python-pip \
+	python-requests \
+	python-setuptools \
 	python-websocket \
+	python-wheel \
 	xfsprogs \
 	tar \
+	thin-provisioning-tools \
 	vim-common \
 	--no-install-recommends
 
-# Install seccomp: the version shipped upstream is too old
-ENV SECCOMP_VERSION 2.3.2
-RUN set -x \
-	&& export SECCOMP_PATH="$(mktemp -d)" \
-	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
-		| tar -xzC "$SECCOMP_PATH" --strip-components=1 \
-	&& ( \
-		cd "$SECCOMP_PATH" \
-		&& ./configure --prefix=/usr/local \
-		&& make \
-		&& make install \
-		&& ldconfig \
-	) \
-	&& rm -rf "$SECCOMP_PATH"
-
-# Get lvm2 source for compiling statically
-ENV LVM2_VERSION 2.02.103
-RUN mkdir -p /usr/local/lvm2 \
-	&& curl -fsSL "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${LVM2_VERSION}.tgz" \
-		| tar -xzC /usr/local/lvm2 --strip-components=1
-# See https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
-
-# Fix platform enablement in lvm2 to support s390x properly
-RUN set -e \
-	&& for f in config.guess config.sub; do \
-		curl -fsSL -o "/usr/local/lvm2/autoconf/$f" "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=$f;hb=HEAD"; \
-	done
-# "arch.c:78:2: error: #error the arch code needs to know about your machine type"
-
-# Compile and install lvm2
-RUN cd /usr/local/lvm2 \
-	&& ./configure \
-		--build="$(gcc -print-multiarch)" \
-		--enable-static_link \
-	&& make device-mapper \
-	&& make install_device-mapper
-# See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
-
 # IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
 ENV GO_VERSION 1.8.3
 RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-s390x.tar.gz" \
@@ -95,17 +65,6 @@
 ENV PATH /go/bin:/usr/local/go/bin:$PATH
 ENV GOPATH /go
 
-# Dependency for golint
-ENV GO_TOOLS_COMMIT 823804e1ae08dbb14eb807afc7db9993bc9e3cc3
-RUN git clone https://github.com/golang/tools.git /go/src/golang.org/x/tools \
-	&& (cd /go/src/golang.org/x/tools && git checkout -q $GO_TOOLS_COMMIT)
-
-# Grab Go's lint tool
-ENV GO_LINT_COMMIT 32a87160691b3c96046c0c678fe57c5bef761456
-RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint \
-	&& (cd /go/src/github.com/golang/lint && git checkout -q $GO_LINT_COMMIT) \
-	&& go install -v github.com/golang/lint/golint
-
 # Install two versions of the registry. The first is an older version that
 # only supports schema1 manifests. The second is a newer version that supports
 # both. This allows integration-cli tests to cover push/pull with both schema1
@@ -137,9 +96,11 @@
 
 # Get the "docker-py" source so we can run their integration tests
 ENV DOCKER_PY_COMMIT a962578e515185cf06506050b2200c0b81aa84ef
+# To run integration tests docker-pycreds is required.
 RUN git clone https://github.com/docker/docker-py.git /docker-py \
 	&& cd /docker-py \
 	&& git checkout -q $DOCKER_PY_COMMIT \
+	&& pip install docker-pycreds==0.2.1 \
 	&& pip install -r test-requirements.txt
 
 # Set user.email so crosbymichael's in-container merge commits go smoothly
@@ -172,7 +133,7 @@
 # Please edit hack/dockerfile/install-binaries.sh to update them.
 COPY hack/dockerfile/binaries-commits /tmp/binaries-commits
 COPY hack/dockerfile/install-binaries.sh /tmp/install-binaries.sh
-RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli
+RUN /tmp/install-binaries.sh tomlv vndr runc containerd tini proxy dockercli gometalinter
 ENV PATH=/usr/local/cli:$PATH
 
 # Wrap all commands in the "docker-in-docker" script to allow nested containers
diff --git a/Dockerfile.simple b/Dockerfile.simple
index b4682d4..5995093 100644
--- a/Dockerfile.simple
+++ b/Dockerfile.simple
@@ -1,11 +1,11 @@
 # docker build -t docker:simple -f Dockerfile.simple .
 # docker run --rm docker:simple hack/make.sh dynbinary
 # docker run --rm --privileged docker:simple hack/dind hack/make.sh test-unit
-# docker run --rm --privileged -v /var/lib/docker docker:simple hack/dind hack/make.sh dynbinary test-integration-cli
+# docker run --rm --privileged -v /var/lib/docker docker:simple hack/dind hack/make.sh dynbinary test-integration
 
 # This represents the bare minimum required to build and test Docker.
 
-FROM debian:jessie
+FROM debian:stretch
 
 # allow replacing httpredir or deb mirror
 ARG APT_MIRROR=deb.debian.org
@@ -23,6 +23,7 @@
 		git \
 		libapparmor-dev \
 		libdevmapper-dev \
+		libseccomp-dev \
 		ca-certificates \
 		e2fsprogs \
 		iptables \
@@ -34,21 +35,6 @@
 		vim-common \
 	&& rm -rf /var/lib/apt/lists/*
 
-# Install seccomp: the version shipped upstream is too old
-ENV SECCOMP_VERSION 2.3.2
-RUN set -x \
-	&& export SECCOMP_PATH="$(mktemp -d)" \
-	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
-		| tar -xzC "$SECCOMP_PATH" --strip-components=1 \
-	&& ( \
-		cd "$SECCOMP_PATH" \
-		&& ./configure --prefix=/usr/local \
-		&& make \
-		&& make install \
-		&& ldconfig \
-	) \
-	&& rm -rf "$SECCOMP_PATH"
-
 # Install Go
 # IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines
 #            will need updating, to avoid errors. Ping #docker-maintainers on IRC
diff --git a/Dockerfile.windows b/Dockerfile.windows
index 8f8ee60..0c62c94 100644
--- a/Dockerfile.windows
+++ b/Dockerfile.windows
@@ -132,8 +132,8 @@
 # Important notes:
 # ---------------
 #
-# Don't attempt to use a bind-mount to pass a local directory as the bundles target
-# directory. It does not work (golang attempts for follow a mapped folder incorrectly). 
+# Don't attempt to use a bind mount to pass a local directory as the bundles target
+# directory. It does not work (golang attempts for follow a mapped folder incorrectly).
 # Instead, use docker cp as per the example.
 #
 # go.zip is not removed from the image as it is used by the Windows CI servers
diff --git a/Makefile b/Makefile
index 0d99606..7d50afa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.PHONY: all binary dynbinary build cross deb help init-go-pkg-cache install manpages rpm run shell test test-docker-py test-integration-cli test-unit tgz validate win
+.PHONY: all binary dynbinary build cross deb help init-go-pkg-cache install manpages rpm run shell test test-docker-py test-integration test-unit validate win
 
 # set the graph driver as the current graphdriver if not set
 DOCKER_GRAPHDRIVER := $(if $(DOCKER_GRAPHDRIVER),$(DOCKER_GRAPHDRIVER),$(shell docker info 2>&1 | grep "Storage Driver" | sed 's/.*: //'))
@@ -35,6 +35,7 @@
 	-e DOCKER_REMAP_ROOT \
 	-e DOCKER_STORAGE_OPTS \
 	-e DOCKER_USERLANDPROXY \
+	-e TEST_INTEGRATION_DIR \
 	-e TESTDIRS \
 	-e TESTFLAGS \
 	-e TIMEOUT \
@@ -43,7 +44,8 @@
 	-e NO_PROXY \
 	-e http_proxy \
 	-e https_proxy \
-	-e no_proxy
+	-e no_proxy \
+	-e VERSION
 # note: we _cannot_ add "-e DOCKER_BUILDTAGS" here because even if it's unset in the shell, that would shadow the "ENV DOCKER_BUILDTAGS" set in our Dockerfile, which is very important for our official builds
 
 # to allow `make BIND_DIR=. shell` or `make BIND_DIR= test`
@@ -110,7 +112,7 @@
 	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary
 
 build: bundles init-go-pkg-cache
-	$(warning The docker client CLI has moved to github.com/docker/cli. By default, it is built from the git sha specified in hack/dockerfile/binaries-commits. For a dev-test cycle involving the CLI, run:${\n} DOCKER_CLI_PATH=/host/path/to/cli/binary make shell ${\n} then change the cli and compile into a binary at the same location.${\n})
+	$(warning The docker client CLI has moved to github.com/docker/cli. For a dev-test cycle involving the CLI, run:${\n} DOCKER_CLI_PATH=/host/path/to/cli/binary make shell ${\n} then change the cli and compile into a binary at the same location.${\n})
 	docker build ${BUILD_APT_MIRROR} ${DOCKER_BUILD_ARGS} -t "$(DOCKER_IMAGE)" -f "$(DOCKERFILE)" .
 
 bundles:
@@ -149,19 +151,18 @@
 	$(DOCKER_RUN_DOCKER) bash
 
 test: build ## run the unit, integration and docker-py tests
-	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-unit test-integration-cli test-docker-py
+	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary cross test-unit test-integration test-docker-py
 
 test-docker-py: build ## run the docker-py tests
 	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-docker-py
 
-test-integration-cli: build ## run the integration tests
-	$(DOCKER_RUN_DOCKER) hack/make.sh build-integration-test-binary dynbinary test-integration-cli
+test-integration-cli: test-integration ## (DEPRECATED) use test-integration
+
+test-integration: build ## run the integration tests
+	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary test-integration
 
 test-unit: build ## run the unit tests
-	$(DOCKER_RUN_DOCKER) hack/make.sh test-unit
-
-tgz: build ## build the archives (.zip on windows and .tgz\notherwise) containing the binaries
-	$(DOCKER_RUN_DOCKER) hack/make.sh dynbinary binary cross tgz
+	$(DOCKER_RUN_DOCKER) hack/test/unit
 
 validate: build ## validate DCO, Seccomp profile generation, gofmt,\n./pkg/ isolation, golint, tests, tomls, go vet and vendor
 	$(DOCKER_RUN_DOCKER) hack/validate/all
diff --git a/TESTING.md b/TESTING.md
new file mode 100644
index 0000000..20f7c92
--- /dev/null
+++ b/TESTING.md
@@ -0,0 +1,71 @@
+# Testing
+
+This document contains the Moby code testing guidelines. It should answer any 
+questions you may have as an aspiring Moby contributor.
+
+## Test suites
+
+Moby has two test suites (and one legacy test suite):
+
+* Unit tests - use standard `go test` and
+  [testify](https://github.com/stretchr/testify) assertions. They are located in
+  the package they test. Unit tests should be fast and test only their own 
+  package.
+* API integration tests - use standard `go test` and
+  [testify](https://github.com/stretchr/testify) assertions. They are located in
+  `./integration/<component>` directories, where `component` is: container,
+  image, volume, etc. These tests perform HTTP requests to an API endpoint and
+  check the HTTP response and daemon state after the call.
+
+The legacy test suite `integration-cli/` is deprecated. No new tests will be 
+added to this suite. Any tests in this suite which require updates should be 
+ported to either the unit test suite or the new API integration test suite.
+
+## Writing new tests
+
+Most code changes will fall into one of the following categories.
+
+### Writing tests for new features
+
+New code should be covered by unit tests. If the code is difficult to test with
+a unit tests then that is a good sign that it should be refactored to make it
+easier to reuse and maintain. Consider accepting unexported interfaces instead
+of structs so that fakes can be provided for dependencies.
+
+If the new feature includes a completely new API endpoint then a new API 
+integration test should be added to cover the success case of that endpoint.
+
+If the new feature does not include a completely new API endpoint consider 
+adding the new API fields to the existing test for that endpoint. A new 
+integration test should **not** be added for every new API field or API error 
+case. Error cases should be handled by unit tests.
+
+### Writing tests for bug fixes
+
+Bugs fixes should include a unit test case which exercises the bug.
+
+A bug fix may also include new assertions in an existing integration tests for the
+API endpoint.
+
+## Running tests
+
+To run the unit test suite:
+
+```
+make test-unit
+```
+
+or `hack/test/unit` from inside a `BINDDIR=. make shell` container or properly
+configured environment.
+
+The following environment variables may be used to run a subset of tests:
+
+* `TESTDIRS` - paths to directories to be tested, defaults to `./...`
+* `TESTFLAGS` - flags passed to `go test`, to run tests which match a pattern
+  use `TESTFLAGS="-test.run TestNameOrPrefix"`
+
+To run the integration test suite:
+
+```
+make test-integration
+```
diff --git a/api/common.go b/api/common.go
index 859daf6..d0229e0 100644
--- a/api/common.go
+++ b/api/common.go
@@ -1,65 +1,11 @@
 package api
 
-import (
-	"encoding/json"
-	"encoding/pem"
-	"fmt"
-	"os"
-	"path/filepath"
-
-	"github.com/docker/docker/pkg/ioutils"
-	"github.com/docker/docker/pkg/system"
-	"github.com/docker/libtrust"
-)
-
 // Common constants for daemon and client.
 const (
 	// DefaultVersion of Current REST API
-	DefaultVersion string = "1.31"
+	DefaultVersion string = "1.34"
 
 	// NoBaseImageSpecifier is the symbol used by the FROM
 	// command to specify that no base image is to be used.
 	NoBaseImageSpecifier string = "scratch"
 )
-
-// LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
-// otherwise generates a new one
-func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
-	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700, "")
-	if err != nil {
-		return nil, err
-	}
-	trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
-	if err == libtrust.ErrKeyFileDoesNotExist {
-		trustKey, err = libtrust.GenerateECP256PrivateKey()
-		if err != nil {
-			return nil, fmt.Errorf("Error generating key: %s", err)
-		}
-		encodedKey, err := serializePrivateKey(trustKey, filepath.Ext(trustKeyPath))
-		if err != nil {
-			return nil, fmt.Errorf("Error serializing key: %s", err)
-		}
-		if err := ioutils.AtomicWriteFile(trustKeyPath, encodedKey, os.FileMode(0600)); err != nil {
-			return nil, fmt.Errorf("Error saving key file: %s", err)
-		}
-	} else if err != nil {
-		return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
-	}
-	return trustKey, nil
-}
-
-func serializePrivateKey(key libtrust.PrivateKey, ext string) (encoded []byte, err error) {
-	if ext == ".json" || ext == ".jwk" {
-		encoded, err = json.Marshal(key)
-		if err != nil {
-			return nil, fmt.Errorf("unable to encode private key JWK: %s", err)
-		}
-	} else {
-		pemBlock, err := key.PEMBlock()
-		if err != nil {
-			return nil, fmt.Errorf("unable to encode private key PEM: %s", err)
-		}
-		encoded = pem.EncodeToMemory(pemBlock)
-	}
-	return
-}
diff --git a/api/common_test.go b/api/common_test.go
deleted file mode 100644
index f466616..0000000
--- a/api/common_test.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package api
-
-import (
-	"io/ioutil"
-	"path/filepath"
-	"testing"
-
-	"os"
-)
-
-// LoadOrCreateTrustKey
-func TestLoadOrCreateTrustKeyInvalidKeyFile(t *testing.T) {
-	tmpKeyFolderPath, err := ioutil.TempDir("", "api-trustkey-test")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpKeyFolderPath)
-
-	tmpKeyFile, err := ioutil.TempFile(tmpKeyFolderPath, "keyfile")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if _, err := LoadOrCreateTrustKey(tmpKeyFile.Name()); err == nil {
-		t.Fatal("expected an error, got nothing.")
-	}
-
-}
-
-func TestLoadOrCreateTrustKeyCreateKey(t *testing.T) {
-	tmpKeyFolderPath, err := ioutil.TempDir("", "api-trustkey-test")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpKeyFolderPath)
-
-	// Without the need to create the folder hierarchy
-	tmpKeyFile := filepath.Join(tmpKeyFolderPath, "keyfile")
-
-	if key, err := LoadOrCreateTrustKey(tmpKeyFile); err != nil || key == nil {
-		t.Fatalf("expected a new key file, got : %v and %v", err, key)
-	}
-
-	if _, err := os.Stat(tmpKeyFile); err != nil {
-		t.Fatalf("Expected to find a file %s, got %v", tmpKeyFile, err)
-	}
-
-	// With the need to create the folder hierarchy as tmpKeyFie is in a path
-	// where some folders do not exist.
-	tmpKeyFile = filepath.Join(tmpKeyFolderPath, "folder/hierarchy/keyfile")
-
-	if key, err := LoadOrCreateTrustKey(tmpKeyFile); err != nil || key == nil {
-		t.Fatalf("expected a new key file, got : %v and %v", err, key)
-	}
-
-	if _, err := os.Stat(tmpKeyFile); err != nil {
-		t.Fatalf("Expected to find a file %s, got %v", tmpKeyFile, err)
-	}
-
-	// With no path at all
-	defer os.Remove("keyfile")
-	if key, err := LoadOrCreateTrustKey("keyfile"); err != nil || key == nil {
-		t.Fatalf("expected a new key file, got : %v and %v", err, key)
-	}
-
-	if _, err := os.Stat("keyfile"); err != nil {
-		t.Fatalf("Expected to find a file keyfile, got %v", err)
-	}
-}
-
-func TestLoadOrCreateTrustKeyLoadValidKey(t *testing.T) {
-	tmpKeyFile := filepath.Join("fixtures", "keyfile")
-
-	if key, err := LoadOrCreateTrustKey(tmpKeyFile); err != nil || key == nil {
-		t.Fatalf("expected a key file, got : %v and %v", err, key)
-	}
-}
diff --git a/api/errdefs/defs.go b/api/errdefs/defs.go
new file mode 100644
index 0000000..4987c62
--- /dev/null
+++ b/api/errdefs/defs.go
@@ -0,0 +1,54 @@
+package errdefs
+
+// ErrNotFound signals that the requested object doesn't exist
+type ErrNotFound interface {
+	NotFound()
+}
+
+// ErrInvalidParameter signals that the user input is invalid
+type ErrInvalidParameter interface {
+	InvalidParameter()
+}
+
+// ErrConflict signals that some internal state conflicts with the requested action and can't be performed.
+// A change in state should be able to clear this error.
+type ErrConflict interface {
+	Conflict()
+}
+
+// ErrUnauthorized is used to signify that the user is not authorized to perform a specific action
+type ErrUnauthorized interface {
+	Unauthorized()
+}
+
+// ErrUnavailable signals that the requested action/subsystem is not available.
+type ErrUnavailable interface {
+	Unavailable()
+}
+
+// ErrForbidden signals that the requested action cannot be performed under any circumstances.
+// When a ErrForbidden is returned, the caller should never retry the action.
+type ErrForbidden interface {
+	Forbidden()
+}
+
+// ErrSystem signals that some internal error occurred.
+// An example of this would be a failed mount request.
+type ErrSystem interface {
+	ErrSystem()
+}
+
+// ErrNotModified signals that an action can't be performed because it's already in the desired state
+type ErrNotModified interface {
+	NotModified()
+}
+
+// ErrNotImplemented signals that the requested action/feature is not implemented on the system as configured.
+type ErrNotImplemented interface {
+	NotImplemented()
+}
+
+// ErrUnknown signals that the kind of error that occurred is not known.
+type ErrUnknown interface {
+	Unknown()
+}
diff --git a/api/errdefs/doc.go b/api/errdefs/doc.go
new file mode 100644
index 0000000..065346a
--- /dev/null
+++ b/api/errdefs/doc.go
@@ -0,0 +1,8 @@
+// Package errdefs defines a set of error interfaces that packages should use for communicating classes of errors.
+// Errors that cross the package boundary should implement one (and only one) of these interfaces.
+//
+// Packages should not reference these interfaces directly, only implement them.
+// To check if a particular error implements one of these interfaces, there are helper
+// functions provided (e.g. `Is<SomeError>`) which can be used rather than asserting the interfaces directly.
+// If you must assert on these interfaces, be sure to check the causal chain (`err.Cause()`).
+package errdefs
diff --git a/api/errdefs/is.go b/api/errdefs/is.go
new file mode 100644
index 0000000..ce574cd
--- /dev/null
+++ b/api/errdefs/is.go
@@ -0,0 +1,86 @@
+package errdefs
+
+type causer interface {
+	Cause() error
+}
+
+func getImplementer(err error) error {
+	switch e := err.(type) {
+	case
+		ErrNotFound,
+		ErrInvalidParameter,
+		ErrConflict,
+		ErrUnauthorized,
+		ErrUnavailable,
+		ErrForbidden,
+		ErrSystem,
+		ErrNotModified,
+		ErrNotImplemented,
+		ErrUnknown:
+		return e
+	case causer:
+		return getImplementer(e.Cause())
+	default:
+		return err
+	}
+}
+
+// IsNotFound returns if the passed in error is a ErrNotFound
+func IsNotFound(err error) bool {
+	_, ok := getImplementer(err).(ErrNotFound)
+	return ok
+}
+
+// IsInvalidParameter returns if the passed in error is an ErrInvalidParameter
+func IsInvalidParameter(err error) bool {
+	_, ok := getImplementer(err).(ErrInvalidParameter)
+	return ok
+}
+
+// IsConflict returns if the passed in error is a ErrConflict
+func IsConflict(err error) bool {
+	_, ok := getImplementer(err).(ErrConflict)
+	return ok
+}
+
+// IsUnauthorized returns if the the passed in error is an ErrUnauthorized
+func IsUnauthorized(err error) bool {
+	_, ok := getImplementer(err).(ErrUnauthorized)
+	return ok
+}
+
+// IsUnavailable returns if the passed in error is an ErrUnavailable
+func IsUnavailable(err error) bool {
+	_, ok := getImplementer(err).(ErrUnavailable)
+	return ok
+}
+
+// IsForbidden returns if the passed in error is a ErrForbidden
+func IsForbidden(err error) bool {
+	_, ok := getImplementer(err).(ErrForbidden)
+	return ok
+}
+
+// IsSystem returns if the passed in error is a ErrSystem
+func IsSystem(err error) bool {
+	_, ok := getImplementer(err).(ErrSystem)
+	return ok
+}
+
+// IsNotModified returns if the passed in error is a NotModified error
+func IsNotModified(err error) bool {
+	_, ok := getImplementer(err).(ErrNotModified)
+	return ok
+}
+
+// IsNotImplemented returns if the passed in error is a ErrNotImplemented
+func IsNotImplemented(err error) bool {
+	_, ok := getImplementer(err).(ErrNotImplemented)
+	return ok
+}
+
+// IsUnknown returns if the passed in error is an ErrUnknown
+func IsUnknown(err error) bool {
+	_, ok := getImplementer(err).(ErrUnknown)
+	return ok
+}
diff --git a/api/errors/errors.go b/api/errors/errors.go
deleted file mode 100644
index 39d52e1..0000000
--- a/api/errors/errors.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package errors
-
-import "net/http"
-
-// apiError is an error wrapper that also
-// holds information about response status codes.
-type apiError struct {
-	error
-	statusCode int
-}
-
-// HTTPErrorStatusCode returns a status code.
-func (e apiError) HTTPErrorStatusCode() int {
-	return e.statusCode
-}
-
-// NewErrorWithStatusCode allows you to associate
-// a specific HTTP Status Code to an error.
-// The server will take that code and set
-// it as the response status.
-func NewErrorWithStatusCode(err error, code int) error {
-	return apiError{err, code}
-}
-
-// NewBadRequestError creates a new API error
-// that has the 400 HTTP status code associated to it.
-func NewBadRequestError(err error) error {
-	return NewErrorWithStatusCode(err, http.StatusBadRequest)
-}
-
-// NewRequestForbiddenError creates a new API error
-// that has the 403 HTTP status code associated to it.
-func NewRequestForbiddenError(err error) error {
-	return NewErrorWithStatusCode(err, http.StatusForbidden)
-}
-
-// NewRequestNotFoundError creates a new API error
-// that has the 404 HTTP status code associated to it.
-func NewRequestNotFoundError(err error) error {
-	return NewErrorWithStatusCode(err, http.StatusNotFound)
-}
-
-// NewRequestConflictError creates a new API error
-// that has the 409 HTTP status code associated to it.
-func NewRequestConflictError(err error) error {
-	return NewErrorWithStatusCode(err, http.StatusConflict)
-}
diff --git a/api/errors/errors_test.go b/api/errors/errors_test.go
deleted file mode 100644
index 1d6a596..0000000
--- a/api/errors/errors_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package errors
-
-import (
-	"fmt"
-	"github.com/stretchr/testify/assert"
-	"net/http"
-	"testing"
-)
-
-func newError(errorname string) error {
-
-	return fmt.Errorf("test%v", errorname)
-}
-
-func TestErrors(t *testing.T) {
-	errmsg := newError("apiError")
-	err := apiError{
-		error:      errmsg,
-		statusCode: 0,
-	}
-	assert.Equal(t, err.HTTPErrorStatusCode(), err.statusCode)
-
-	errmsg = newError("ErrorWithStatusCode")
-	errcode := 1
-	serr := NewErrorWithStatusCode(errmsg, errcode)
-	apierr, ok := serr.(apiError)
-	if !ok {
-		t.Fatal("excepted err is apiError type")
-	}
-	assert.Equal(t, errcode, apierr.statusCode)
-
-	errmsg = newError("NewBadRequestError")
-	baderr := NewBadRequestError(errmsg)
-	apierr, ok = baderr.(apiError)
-	if !ok {
-		t.Fatal("excepted err is apiError type")
-	}
-	assert.Equal(t, http.StatusBadRequest, apierr.statusCode)
-
-	errmsg = newError("RequestForbiddenError")
-	ferr := NewRequestForbiddenError(errmsg)
-	apierr, ok = ferr.(apiError)
-	if !ok {
-		t.Fatal("excepted err is apiError type")
-	}
-	assert.Equal(t, http.StatusForbidden, apierr.statusCode)
-
-	errmsg = newError("RequestNotFoundError")
-	nerr := NewRequestNotFoundError(errmsg)
-	apierr, ok = nerr.(apiError)
-	if !ok {
-		t.Fatal("excepted err is apiError type")
-	}
-	assert.Equal(t, http.StatusNotFound, apierr.statusCode)
-
-	errmsg = newError("RequestConflictError")
-	cerr := NewRequestConflictError(errmsg)
-	apierr, ok = cerr.(apiError)
-	if !ok {
-		t.Fatal("excepted err is apiError type")
-	}
-	assert.Equal(t, http.StatusConflict, apierr.statusCode)
-
-}
diff --git a/api/server/httputils/errors.go b/api/server/httputils/errors.go
index 82da21c..05a842c 100644
--- a/api/server/httputils/errors.go
+++ b/api/server/httputils/errors.go
@@ -1,32 +1,20 @@
 package httputils
 
 import (
+	"fmt"
 	"net/http"
-	"strings"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/api/errdefs"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/gorilla/mux"
+	"github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 )
 
-// httpStatusError is an interface
-// that errors with custom status codes
-// implement to tell the api layer
-// which response status to set.
-type httpStatusError interface {
-	HTTPErrorStatusCode() int
-}
-
-// inputValidationError is an interface
-// that errors generated by invalid
-// inputs can implement to tell the
-// api layer to set a 400 status code
-// in the response.
-type inputValidationError interface {
-	IsValidationError() bool
+type causer interface {
+	Cause() error
 }
 
 // GetHTTPErrorStatusCode retrieves status code from error message.
@@ -37,49 +25,44 @@
 	}
 
 	var statusCode int
-	errMsg := err.Error()
 
-	switch e := err.(type) {
-	case httpStatusError:
-		statusCode = e.HTTPErrorStatusCode()
-	case inputValidationError:
+	// Stop right there
+	// Are you sure you should be adding a new error class here? Do one of the existing ones work?
+
+	// Note that the below functions are already checking the error causal chain for matches.
+	switch {
+	case errdefs.IsNotFound(err):
+		statusCode = http.StatusNotFound
+	case errdefs.IsInvalidParameter(err):
 		statusCode = http.StatusBadRequest
+	case errdefs.IsConflict(err):
+		statusCode = http.StatusConflict
+	case errdefs.IsUnauthorized(err):
+		statusCode = http.StatusUnauthorized
+	case errdefs.IsUnavailable(err):
+		statusCode = http.StatusServiceUnavailable
+	case errdefs.IsForbidden(err):
+		statusCode = http.StatusForbidden
+	case errdefs.IsNotModified(err):
+		statusCode = http.StatusNotModified
+	case errdefs.IsNotImplemented(err):
+		statusCode = http.StatusNotImplemented
+	case errdefs.IsSystem(err) || errdefs.IsUnknown(err):
+		statusCode = http.StatusInternalServerError
 	default:
 		statusCode = statusCodeFromGRPCError(err)
 		if statusCode != http.StatusInternalServerError {
 			return statusCode
 		}
 
-		// FIXME: this is brittle and should not be necessary, but we still need to identify if
-		// there are errors falling back into this logic.
-		// If we need to differentiate between different possible error types,
-		// we should create appropriate error types that implement the httpStatusError interface.
-		errStr := strings.ToLower(errMsg)
-
-		for _, status := range []struct {
-			keyword string
-			code    int
-		}{
-			{"not found", http.StatusNotFound},
-			{"cannot find", http.StatusNotFound},
-			{"no such", http.StatusNotFound},
-			{"bad parameter", http.StatusBadRequest},
-			{"no command", http.StatusBadRequest},
-			{"conflict", http.StatusConflict},
-			{"impossible", http.StatusNotAcceptable},
-			{"wrong login/password", http.StatusUnauthorized},
-			{"unauthorized", http.StatusUnauthorized},
-			{"hasn't been activated", http.StatusForbidden},
-			{"this node", http.StatusServiceUnavailable},
-			{"needs to be unlocked", http.StatusServiceUnavailable},
-			{"certificates have expired", http.StatusServiceUnavailable},
-			{"repository does not exist", http.StatusNotFound},
-		} {
-			if strings.Contains(errStr, status.keyword) {
-				statusCode = status.code
-				break
-			}
+		if e, ok := err.(causer); ok {
+			return GetHTTPErrorStatusCode(e.Cause())
 		}
+
+		logrus.WithFields(logrus.Fields{
+			"module":     "api",
+			"error_type": fmt.Sprintf("%T", err),
+		}).Debugf("FIXME: Got an API for which error does not match any expected type!!!: %+v", err)
 	}
 
 	if statusCode == 0 {
@@ -133,6 +116,9 @@
 	case codes.Unavailable: // code 14
 		return http.StatusServiceUnavailable
 	default:
+		if e, ok := err.(causer); ok {
+			return statusCodeFromGRPCError(e.Cause())
+		}
 		// codes.Canceled(1)
 		// codes.Unknown(2)
 		// codes.DeadlineExceeded(4)
diff --git a/api/server/httputils/form.go b/api/server/httputils/form.go
index 78bd379..1ce822e 100644
--- a/api/server/httputils/form.go
+++ b/api/server/httputils/form.go
@@ -1,9 +1,7 @@
 package httputils
 
 import (
-	"errors"
 	"net/http"
-	"path/filepath"
 	"strconv"
 	"strings"
 )
@@ -49,6 +47,16 @@
 	Path string
 }
 
+type badParameterError struct {
+	param string
+}
+
+func (e badParameterError) Error() string {
+	return "bad parameter: " + e.param + "cannot be empty"
+}
+
+func (e badParameterError) InvalidParameter() {}
+
 // ArchiveFormValues parses form values and turns them into ArchiveOptions.
 // It fails if the archive name and path are not in the request.
 func ArchiveFormValues(r *http.Request, vars map[string]string) (ArchiveOptions, error) {
@@ -57,14 +65,12 @@
 	}
 
 	name := vars["name"]
-	path := filepath.FromSlash(r.Form.Get("path"))
-
-	switch {
-	case name == "":
-		return ArchiveOptions{}, errors.New("bad parameter: 'name' cannot be empty")
-	case path == "":
-		return ArchiveOptions{}, errors.New("bad parameter: 'path' cannot be empty")
+	if name == "" {
+		return ArchiveOptions{}, badParameterError{"name"}
 	}
-
+	path := r.Form.Get("path")
+	if path == "" {
+		return ArchiveOptions{}, badParameterError{"path"}
+	}
 	return ArchiveOptions{name, path}, nil
 }
diff --git a/api/server/httputils/httputils.go b/api/server/httputils/httputils.go
index 92cb67c..57eeb4b 100644
--- a/api/server/httputils/httputils.go
+++ b/api/server/httputils/httputils.go
@@ -1,13 +1,13 @@
 package httputils
 
 import (
-	"fmt"
 	"io"
 	"mime"
 	"net/http"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -43,6 +43,20 @@
 	}
 }
 
+type validationError struct {
+	cause error
+}
+
+func (e validationError) Error() string {
+	return e.cause.Error()
+}
+
+func (e validationError) Cause() error {
+	return e.cause
+}
+
+func (e validationError) InvalidParameter() {}
+
 // CheckForJSON makes sure that the request's Content-Type is application/json.
 func CheckForJSON(r *http.Request) error {
 	ct := r.Header.Get("Content-Type")
@@ -58,7 +72,7 @@
 	if matchesContentType(ct, "application/json") {
 		return nil
 	}
-	return fmt.Errorf("Content-Type specified (%s) must be 'application/json'", ct)
+	return validationError{errors.Errorf("Content-Type specified (%s) must be 'application/json'", ct)}
 }
 
 // ParseForm ensures the request form is parsed even with invalid content types.
@@ -68,7 +82,7 @@
 		return nil
 	}
 	if err := r.ParseForm(); err != nil && !strings.HasPrefix(err.Error(), "mime:") {
-		return err
+		return validationError{err}
 	}
 	return nil
 }
diff --git a/api/server/httputils/write_log_stream.go b/api/server/httputils/write_log_stream.go
index fd024e1..d7a49a1 100644
--- a/api/server/httputils/write_log_stream.go
+++ b/api/server/httputils/write_log_stream.go
@@ -11,26 +11,19 @@
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/pkg/ioutils"
-	"github.com/docker/docker/pkg/jsonlog"
+	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/docker/docker/pkg/stdcopy"
 )
 
 // WriteLogStream writes an encoded byte stream of log messages from the
 // messages channel, multiplexing them with a stdcopy.Writer if mux is true
-func WriteLogStream(ctx context.Context, w io.Writer, msgs <-chan *backend.LogMessage, config *types.ContainerLogsOptions, mux bool) {
+func WriteLogStream(_ context.Context, w io.Writer, msgs <-chan *backend.LogMessage, config *types.ContainerLogsOptions, mux bool) {
 	wf := ioutils.NewWriteFlusher(w)
 	defer wf.Close()
 
 	wf.Flush()
 
-	// this might seem like doing below is clear:
-	//   var outStream io.Writer = wf
-	// however, this GREATLY DISPLEASES golint, and if you do that, it will
-	// fail CI. we need outstream to be type writer because if we mux streams,
-	// we will need to reassign all of the streams to be stdwriters, which only
-	// conforms to the io.Writer interface.
-	var outStream io.Writer
-	outStream = wf
+	outStream := io.Writer(wf)
 	errStream := outStream
 	sysErrStream := errStream
 	if mux {
@@ -56,11 +49,7 @@
 			logLine = append(logLine, msg.Line...)
 		}
 		if config.Timestamps {
-			// TODO(dperny) the format is defined in
-			// daemon/logger/logger.go as logger.TimeFormat. importing
-			// logger is verboten (not part of backend) so idk if just
-			// importing the same thing from jsonlog is good enough
-			logLine = append([]byte(msg.Timestamp.Format(jsonlog.RFC3339NanoFixed)+" "), logLine...)
+			logLine = append([]byte(msg.Timestamp.Format(jsonmessage.RFC3339NanoFixed)+" "), logLine...)
 		}
 		if msg.Source == "stdout" && config.ShowStdout {
 			outStream.Write(logLine)
diff --git a/api/server/middleware.go b/api/server/middleware.go
index 537ce80..653d554 100644
--- a/api/server/middleware.go
+++ b/api/server/middleware.go
@@ -1,9 +1,9 @@
 package server
 
 import (
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/server/middleware"
+	"github.com/sirupsen/logrus"
 )
 
 // handlerWithGlobalMiddlewares wraps the handler function for a request with
diff --git a/api/server/middleware/cors.go b/api/server/middleware/cors.go
index ea725db..8ee19a3 100644
--- a/api/server/middleware/cors.go
+++ b/api/server/middleware/cors.go
@@ -3,7 +3,7 @@
 import (
 	"net/http"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/api/server/middleware/debug.go b/api/server/middleware/debug.go
index a9a94e7..7b867f1 100644
--- a/api/server/middleware/debug.go
+++ b/api/server/middleware/debug.go
@@ -7,9 +7,9 @@
 	"net/http"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/pkg/ioutils"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/api/server/middleware/version.go b/api/server/middleware/version.go
index 390a7f0..ef35c72 100644
--- a/api/server/middleware/version.go
+++ b/api/server/middleware/version.go
@@ -5,7 +5,6 @@
 	"net/http"
 	"runtime"
 
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types/versions"
 	"golang.org/x/net/context"
 )
@@ -28,6 +27,16 @@
 	}
 }
 
+type versionUnsupportedError struct {
+	version, minVersion string
+}
+
+func (e versionUnsupportedError) Error() string {
+	return fmt.Sprintf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", e.version, e.minVersion)
+}
+
+func (e versionUnsupportedError) InvalidParameter() {}
+
 // WrapHandler returns a new handler function wrapping the previous one in the request chain.
 func (v VersionMiddleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@@ -37,13 +46,14 @@
 		}
 
 		if versions.LessThan(apiVersion, v.minVersion) {
-			return errors.NewBadRequestError(fmt.Errorf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", apiVersion, v.minVersion))
+			return versionUnsupportedError{apiVersion, v.minVersion}
 		}
 
 		header := fmt.Sprintf("Docker/%s (%s)", v.serverVersion, runtime.GOOS)
 		w.Header().Set("Server", header)
 		w.Header().Set("API-Version", v.defaultVersion)
 		w.Header().Set("OSType", runtime.GOOS)
+		// nolint: golint
 		ctx = context.WithValue(ctx, "api-version", apiVersion)
 		return handler(ctx, w, r, vars)
 	}
diff --git a/api/server/router/build/build_routes.go b/api/server/router/build/build_routes.go
index baa1da3..2c9a947 100644
--- a/api/server/router/build/build_routes.go
+++ b/api/server/router/build/build_routes.go
@@ -12,8 +12,6 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
-	apierrors "github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
@@ -24,9 +22,18 @@
 	"github.com/docker/docker/pkg/streamformatter"
 	units "github.com/docker/go-units"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
+type invalidIsolationError string
+
+func (e invalidIsolationError) Error() string {
+	return fmt.Sprintf("Unsupported isolation: %q", string(e))
+}
+
+func (e invalidIsolationError) InvalidParameter() {}
+
 func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBuildOptions, error) {
 	version := httputils.VersionFromContext(ctx)
 	options := &types.ImageBuildOptions{}
@@ -71,20 +78,20 @@
 
 	if i := container.Isolation(r.FormValue("isolation")); i != "" {
 		if !container.Isolation.IsValid(i) {
-			return nil, fmt.Errorf("Unsupported isolation: %q", i)
+			return nil, invalidIsolationError(i)
 		}
 		options.Isolation = i
 	}
 
 	if runtime.GOOS != "windows" && options.SecurityOpt != nil {
-		return nil, fmt.Errorf("The daemon on this platform does not support setting security options on build")
+		return nil, validationError{fmt.Errorf("The daemon on this platform does not support setting security options on build")}
 	}
 
 	var buildUlimits = []*units.Ulimit{}
 	ulimitsJSON := r.FormValue("ulimits")
 	if ulimitsJSON != "" {
 		if err := json.Unmarshal([]byte(ulimitsJSON), &buildUlimits); err != nil {
-			return nil, err
+			return nil, errors.Wrap(validationError{err}, "error reading ulimit settings")
 		}
 		options.Ulimits = buildUlimits
 	}
@@ -105,7 +112,7 @@
 	if buildArgsJSON != "" {
 		var buildArgs = map[string]*string{}
 		if err := json.Unmarshal([]byte(buildArgsJSON), &buildArgs); err != nil {
-			return nil, err
+			return nil, errors.Wrap(validationError{err}, "error reading build args")
 		}
 		options.BuildArgs = buildArgs
 	}
@@ -114,7 +121,7 @@
 	if labelsJSON != "" {
 		var labels = map[string]string{}
 		if err := json.Unmarshal([]byte(labelsJSON), &labels); err != nil {
-			return nil, err
+			return nil, errors.Wrap(validationError{err}, "error reading labels")
 		}
 		options.Labels = labels
 	}
@@ -140,6 +147,16 @@
 	return httputils.WriteJSON(w, http.StatusOK, report)
 }
 
+type validationError struct {
+	cause error
+}
+
+func (e validationError) Error() string {
+	return e.cause.Error()
+}
+
+func (e validationError) InvalidParameter() {}
+
 func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	var (
 		notVerboseBuffer = bytes.NewBuffer(nil)
@@ -173,8 +190,7 @@
 	buildOptions.AuthConfigs = getAuthConfigs(r.Header)
 
 	if buildOptions.Squash && !br.daemon.HasExperimental() {
-		return apierrors.NewBadRequestError(
-			errors.New("squash is only supported with experimental mode"))
+		return validationError{errors.New("squash is only supported with experimental mode")}
 	}
 
 	out := io.Writer(output)
diff --git a/api/server/router/container/backend.go b/api/server/router/container/backend.go
index d51ed81..8a32f26 100644
--- a/api/server/router/container/backend.go
+++ b/api/server/router/container/backend.go
@@ -18,7 +18,7 @@
 	ContainerExecCreate(name string, config *types.ExecConfig) (string, error)
 	ContainerExecInspect(id string) (*backend.ExecInspect, error)
 	ContainerExecResize(name string, height, width int) error
-	ContainerExecStart(ctx context.Context, name string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) error
+	ContainerExecStart(ctx context.Context, name string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error
 	ExecExists(name string) (bool, error)
 }
 
@@ -51,7 +51,7 @@
 type monitorBackend interface {
 	ContainerChanges(name string) ([]archive.Change, error)
 	ContainerInspect(name string, size bool, version string) (interface{}, error)
-	ContainerLogs(ctx context.Context, name string, config *types.ContainerLogsOptions) (<-chan *backend.LogMessage, error)
+	ContainerLogs(ctx context.Context, name string, config *types.ContainerLogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error)
 	ContainerStats(ctx context.Context, name string, config *backend.ContainerStatsConfig) error
 	ContainerTop(name string, psArgs string) (*container.ContainerTopOKBody, error)
 
diff --git a/api/server/router/container/container.go b/api/server/router/container/container.go
index 24c3224..90ae6dc 100644
--- a/api/server/router/container/container.go
+++ b/api/server/router/container/container.go
@@ -6,13 +6,19 @@
 )
 
 type validationError struct {
-	error
+	cause error
 }
 
-func (validationError) IsValidationError() bool {
-	return true
+func (e validationError) Error() string {
+	return e.cause.Error()
 }
 
+func (e validationError) Cause() error {
+	return e.cause
+}
+
+func (e validationError) InvalidParameter() {}
+
 // containerRouter is a router to talk with the container controller
 type containerRouter struct {
 	backend Backend
diff --git a/api/server/router/container/container_routes.go b/api/server/router/container/container_routes.go
index 96b1010..95bbe0e 100644
--- a/api/server/router/container/container_routes.go
+++ b/api/server/router/container/container_routes.go
@@ -8,8 +8,7 @@
 	"strconv"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api"
+	"github.com/docker/docker/api/errdefs"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
@@ -19,6 +18,8 @@
 	containerpkg "github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/signal"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/net/websocket"
 )
@@ -27,7 +28,7 @@
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 	}
-	filter, err := filters.FromParam(r.Form.Get("filters"))
+	filter, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
@@ -69,7 +70,7 @@
 	config := &backend.ContainerStatsConfig{
 		Stream:    stream,
 		OutStream: w,
-		Version:   string(httputils.VersionFromContext(ctx)),
+		Version:   httputils.VersionFromContext(ctx),
 	}
 
 	return s.backend.ContainerStats(ctx, vars["name"], config)
@@ -87,7 +88,7 @@
 	// with the appropriate status code.
 	stdout, stderr := httputils.BoolValue(r, "stdout"), httputils.BoolValue(r, "stderr")
 	if !(stdout || stderr) {
-		return fmt.Errorf("Bad parameters: you must choose at least one stream")
+		return validationError{errors.New("Bad parameters: you must choose at least one stream")}
 	}
 
 	containerName := vars["name"]
@@ -101,19 +102,7 @@
 		Details:    httputils.BoolValue(r, "details"),
 	}
 
-	// doesn't matter what version the client is on, we're using this internally only
-	// also do we need size? i'm thinking no we don't
-	raw, err := s.backend.ContainerInspect(containerName, false, api.DefaultVersion)
-	if err != nil {
-		return err
-	}
-	container, ok := raw.(*types.ContainerJSON)
-	if !ok {
-		// %T prints the type. handy!
-		return fmt.Errorf("expected container to be *types.ContainerJSON but got %T", raw)
-	}
-
-	msgs, err := s.backend.ContainerLogs(ctx, containerName, logsConfig)
+	msgs, tty, err := s.backend.ContainerLogs(ctx, containerName, logsConfig)
 	if err != nil {
 		return err
 	}
@@ -122,7 +111,7 @@
 	// this is the point of no return for writing a response. once we call
 	// WriteLogStream, the response has been started and errors will be
 	// returned in band by WriteLogStream
-	httputils.WriteLogStream(ctx, w, msgs, logsConfig, !container.Config.Tty)
+	httputils.WriteLogStream(ctx, w, msgs, logsConfig, !tty)
 	return nil
 }
 
@@ -130,6 +119,14 @@
 	return s.backend.ContainerExport(vars["name"], w)
 }
 
+type bodyOnStartError struct{}
+
+func (bodyOnStartError) Error() string {
+	return "starting container with non-empty request body was deprecated since API v1.22 and removed in v1.24"
+}
+
+func (bodyOnStartError) InvalidParameter() {}
+
 func (s *containerRouter) postContainersStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	// If contentLength is -1, we can assumed chunked encoding
 	// or more technically that the length is unknown
@@ -143,7 +140,7 @@
 	// A non-nil json object is at least 7 characters.
 	if r.ContentLength > 7 || r.ContentLength == -1 {
 		if versions.GreaterThanOrEqualTo(version, "1.24") {
-			return validationError{fmt.Errorf("starting container with non-empty request body was deprecated since v1.10 and removed in v1.12")}
+			return bodyOnStartError{}
 		}
 
 		if err := httputils.CheckForJSON(r); err != nil {
@@ -193,10 +190,6 @@
 	return nil
 }
 
-type errContainerIsRunning interface {
-	ContainerIsRunning() bool
-}
-
 func (s *containerRouter) postContainersKill(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
@@ -209,14 +202,14 @@
 	if sigStr := r.Form.Get("signal"); sigStr != "" {
 		var err error
 		if sig, err = signal.ParseSignal(sigStr); err != nil {
-			return err
+			return validationError{err}
 		}
 	}
 
 	if err := s.backend.ContainerKill(name, uint64(sig)); err != nil {
 		var isStopped bool
-		if e, ok := err.(errContainerIsRunning); ok {
-			isStopped = !e.ContainerIsRunning()
+		if errdefs.IsConflict(err) {
+			isStopped = true
 		}
 
 		// Return error that's not caused because the container is stopped.
@@ -224,7 +217,7 @@
 		// to keep backwards compatibility.
 		version := httputils.VersionFromContext(ctx)
 		if versions.GreaterThanOrEqualTo(version, "1.20") || !isStopped {
-			return fmt.Errorf("Cannot kill container %s: %v", name, err)
+			return errors.Wrapf(err, "Cannot kill container: %s", name)
 		}
 	}
 
@@ -458,11 +451,11 @@
 
 	height, err := strconv.Atoi(r.Form.Get("h"))
 	if err != nil {
-		return err
+		return validationError{err}
 	}
 	width, err := strconv.Atoi(r.Form.Get("w"))
 	if err != nil {
-		return err
+		return validationError{err}
 	}
 
 	return s.backend.ContainerResize(vars["name"], height, width)
@@ -480,7 +473,7 @@
 
 	hijacker, ok := w.(http.Hijacker)
 	if !ok {
-		return fmt.Errorf("error attaching to container %s, hijack connection missing", containerName)
+		return validationError{errors.Errorf("error attaching to container %s, hijack connection missing", containerName)}
 	}
 
 	setupStreams := func() (io.ReadCloser, io.Writer, io.Writer, error) {
@@ -595,9 +588,9 @@
 		return err
 	}
 
-	pruneFilters, err := filters.FromParam(r.Form.Get("filters"))
+	pruneFilters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
-		return err
+		return validationError{err}
 	}
 
 	pruneReport, err := s.backend.ContainersPrune(ctx, pruneFilters)
diff --git a/api/server/router/container/copy.go b/api/server/router/container/copy.go
index 5cfe8d7..356775f 100644
--- a/api/server/router/container/copy.go
+++ b/api/server/router/container/copy.go
@@ -3,11 +3,8 @@
 import (
 	"encoding/base64"
 	"encoding/json"
-	"fmt"
 	"io"
 	"net/http"
-	"os"
-	"strings"
 
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types"
@@ -15,6 +12,14 @@
 	"golang.org/x/net/context"
 )
 
+type pathError struct{}
+
+func (pathError) Error() string {
+	return "Path cannot be empty"
+}
+
+func (pathError) InvalidParameter() {}
+
 // postContainersCopy is deprecated in favor of getContainersArchive.
 func (s *containerRouter) postContainersCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	// Deprecated since 1.8, Errors out since 1.12
@@ -33,18 +38,11 @@
 	}
 
 	if cfg.Resource == "" {
-		return fmt.Errorf("Path cannot be empty")
+		return pathError{}
 	}
 
 	data, err := s.backend.ContainerCopy(vars["name"], cfg.Resource)
 	if err != nil {
-		if strings.Contains(strings.ToLower(err.Error()), "no such container") {
-			w.WriteHeader(http.StatusNotFound)
-			return nil
-		}
-		if os.IsNotExist(err) {
-			return fmt.Errorf("Could not find the file %s in container %s", cfg.Resource, vars["name"])
-		}
 		return err
 	}
 	defer data.Close()
diff --git a/api/server/router/container/exec.go b/api/server/router/container/exec.go
index 1134a0e..aa2ebb1 100644
--- a/api/server/router/container/exec.go
+++ b/api/server/router/container/exec.go
@@ -7,11 +7,11 @@
 	"net/http"
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/pkg/stdcopy"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -24,6 +24,14 @@
 	return httputils.WriteJSON(w, http.StatusOK, eConfig)
 }
 
+type execCommandError struct{}
+
+func (execCommandError) Error() string {
+	return "No exec command specified"
+}
+
+func (execCommandError) InvalidParameter() {}
+
 func (s *containerRouter) postContainerExecCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
@@ -39,7 +47,7 @@
 	}
 
 	if len(execConfig.Cmd) == 0 {
-		return fmt.Errorf("No exec command specified")
+		return execCommandError{}
 	}
 
 	// Register an instance of Exec in container.
@@ -129,11 +137,11 @@
 	}
 	height, err := strconv.Atoi(r.Form.Get("h"))
 	if err != nil {
-		return err
+		return validationError{err}
 	}
 	width, err := strconv.Atoi(r.Form.Get("w"))
 	if err != nil {
-		return err
+		return validationError{err}
 	}
 
 	return s.backend.ContainerExecResize(vars["name"], height, width)
diff --git a/api/server/router/experimental.go b/api/server/router/experimental.go
index ac31f04..4045de5 100644
--- a/api/server/router/experimental.go
+++ b/api/server/router/experimental.go
@@ -1,19 +1,13 @@
 package router
 
 import (
-	"errors"
 	"net/http"
 
 	"golang.org/x/net/context"
 
-	apierrors "github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/server/httputils"
 )
 
-var (
-	errExperimentalFeature = errors.New("This experimental feature is disabled by default. Start the Docker daemon in experimental mode in order to enable it.")
-)
-
 // ExperimentalRoute defines an experimental API route that can be enabled or disabled.
 type ExperimentalRoute interface {
 	Route
@@ -39,8 +33,16 @@
 	r.handler = experimentalHandler
 }
 
+type notImplementedError struct{}
+
+func (notImplementedError) Error() string {
+	return "This experimental feature is disabled by default. Start the Docker daemon in experimental mode in order to enable it."
+}
+
+func (notImplementedError) NotImplemented() {}
+
 func experimentalHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	return apierrors.NewErrorWithStatusCode(errExperimentalFeature, http.StatusNotImplemented)
+	return notImplementedError{}
 }
 
 // Handler returns returns the APIFunc to let the server wrap it in middlewares.
diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go
index 9b99a58..7214f4e 100644
--- a/api/server/router/image/image_routes.go
+++ b/api/server/router/image/image_routes.go
@@ -3,7 +3,6 @@
 import (
 	"encoding/base64"
 	"encoding/json"
-	"fmt"
 	"io"
 	"net/http"
 	"runtime"
@@ -20,6 +19,7 @@
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/registry"
+	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 )
 
@@ -66,9 +66,7 @@
 		return err
 	}
 
-	return httputils.WriteJSON(w, http.StatusCreated, &types.IDResponse{
-		ID: string(imgID),
-	})
+	return httputils.WriteJSON(w, http.StatusCreated, &types.IDResponse{ID: imgID})
 }
 
 // Creates an image from Pull or from Import
@@ -161,6 +159,20 @@
 	return nil
 }
 
+type validationError struct {
+	cause error
+}
+
+func (e validationError) Error() string {
+	return e.cause.Error()
+}
+
+func (e validationError) Cause() error {
+	return e.cause
+}
+
+func (validationError) InvalidParameter() {}
+
 func (s *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	metaHeaders := map[string][]string{}
 	for k, v := range r.Header {
@@ -184,7 +196,7 @@
 	} else {
 		// the old format is supported for compatibility if there was no authConfig header
 		if err := json.NewDecoder(r.Body).Decode(authConfig); err != nil {
-			return fmt.Errorf("Bad parameters and missing X-Registry-Auth: %v", err)
+			return errors.Wrap(validationError{err}, "Bad parameters and missing X-Registry-Auth")
 		}
 	}
 
@@ -246,6 +258,14 @@
 	return nil
 }
 
+type missingImageError struct{}
+
+func (missingImageError) Error() string {
+	return "image name cannot be blank"
+}
+
+func (missingImageError) InvalidParameter() {}
+
 func (s *imageRouter) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
@@ -254,7 +274,7 @@
 	name := vars["name"]
 
 	if strings.TrimSpace(name) == "" {
-		return fmt.Errorf("image name cannot be blank")
+		return missingImageError{}
 	}
 
 	force := httputils.BoolValue(r, "force")
@@ -282,7 +302,7 @@
 		return err
 	}
 
-	imageFilters, err := filters.FromParam(r.Form.Get("filters"))
+	imageFilters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
@@ -365,7 +385,7 @@
 		return err
 	}
 
-	pruneFilters, err := filters.FromParam(r.Form.Get("filters"))
+	pruneFilters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
diff --git a/api/server/router/network/filter.go b/api/server/router/network/filter.go
index afe4e23..6a5fce6 100644
--- a/api/server/router/network/filter.go
+++ b/api/server/router/network/filter.go
@@ -1,8 +1,6 @@
 package network
 
 import (
-	"fmt"
-
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/runconfig"
@@ -24,11 +22,19 @@
 			}
 		}
 	default:
-		return nil, fmt.Errorf("Invalid filter: 'type'='%s'", netType)
+		return nil, invalidFilter(netType)
 	}
 	return retNws, nil
 }
 
+type invalidFilter string
+
+func (e invalidFilter) Error() string {
+	return "Invalid filter: 'type'='" + string(e) + "'"
+}
+
+func (e invalidFilter) InvalidParameter() {}
+
 // filterNetworks filters network list according to user specified filter
 // and returns user chosen networks
 func filterNetworks(nws []types.NetworkResource, filter filters.Args) ([]types.NetworkResource, error) {
@@ -39,27 +45,27 @@
 
 	displayNet := []types.NetworkResource{}
 	for _, nw := range nws {
-		if filter.Include("driver") {
+		if filter.Contains("driver") {
 			if !filter.ExactMatch("driver", nw.Driver) {
 				continue
 			}
 		}
-		if filter.Include("name") {
+		if filter.Contains("name") {
 			if !filter.Match("name", nw.Name) {
 				continue
 			}
 		}
-		if filter.Include("id") {
+		if filter.Contains("id") {
 			if !filter.Match("id", nw.ID) {
 				continue
 			}
 		}
-		if filter.Include("label") {
+		if filter.Contains("label") {
 			if !filter.MatchKVList("label", nw.Labels) {
 				continue
 			}
 		}
-		if filter.Include("scope") {
+		if filter.Contains("scope") {
 			if !filter.ExactMatch("scope", nw.Scope) {
 				continue
 			}
@@ -67,7 +73,7 @@
 		displayNet = append(displayNet, nw)
 	}
 
-	if filter.Include("type") {
+	if filter.Contains("type") {
 		typeNet := []types.NetworkResource{}
 		errFilter := filter.WalkValues("type", func(fval string) error {
 			passList, err := filterNetworkByType(displayNet, fval)
diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go
index 6f2041e..ebf4bf6 100644
--- a/api/server/router/network/network_routes.go
+++ b/api/server/router/network/network_routes.go
@@ -2,21 +2,21 @@
 
 import (
 	"encoding/json"
-	"fmt"
 	"net/http"
 	"strconv"
 	"strings"
 
 	"golang.org/x/net/context"
 
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/libnetwork"
+	netconst "github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/networkdb"
+	"github.com/pkg/errors"
 )
 
 var (
@@ -37,7 +37,7 @@
 	}
 
 	filter := r.Form.Get("filters")
-	netFilters, err := filters.FromParam(filter)
+	netFilters, err := filters.FromJSON(filter)
 	if err != nil {
 		return err
 	}
@@ -82,6 +82,24 @@
 	return httputils.WriteJSON(w, http.StatusOK, list)
 }
 
+type invalidRequestError struct {
+	cause error
+}
+
+func (e invalidRequestError) Error() string {
+	return e.cause.Error()
+}
+
+func (e invalidRequestError) InvalidParameter() {}
+
+type ambigousResultsError string
+
+func (e ambigousResultsError) Error() string {
+	return "network " + string(e) + " is ambiguous"
+}
+
+func (ambigousResultsError) InvalidParameter() {}
+
 func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
@@ -94,8 +112,7 @@
 	)
 	if v := r.URL.Query().Get("verbose"); v != "" {
 		if verbose, err = strconv.ParseBool(v); err != nil {
-			err = fmt.Errorf("invalid value for verbose: %s", v)
-			return errors.NewBadRequestError(err)
+			return errors.Wrapf(invalidRequestError{err}, "invalid value for verbose: %s", v)
 		}
 	}
 	scope := r.URL.Query().Get("scope")
@@ -135,6 +152,17 @@
 		}
 	}
 
+	nwk, err := n.cluster.GetNetwork(term)
+	if err == nil {
+		// If the get network is passed with a specific network ID / partial network ID
+		// or if the get network was passed with a network name and scope as swarm
+		// return the network. Skipped using isMatchingScope because it is true if the scope
+		// is not set which would be case if the client API v1.30
+		if strings.HasPrefix(nwk.ID, term) || (netconst.SwarmScope == scope) {
+			return httputils.WriteJSON(w, http.StatusOK, nwk)
+		}
+	}
+
 	nr, _ := n.cluster.GetNetworks()
 	for _, network := range nr {
 		if network.ID == term && isMatchingScope(network.Scope, scope) {
@@ -165,7 +193,7 @@
 		}
 	}
 	if len(listByFullName) > 1 {
-		return fmt.Errorf("network %s is ambiguous (%d matches found based on name)", term, len(listByFullName))
+		return errors.Wrapf(ambigousResultsError(term), "%d matches found based on name", len(listByFullName))
 	}
 
 	// Find based on partial ID, returns true only if no duplicates
@@ -175,7 +203,7 @@
 		}
 	}
 	if len(listByPartialID) > 1 {
-		return fmt.Errorf("network %s is ambiguous (%d matches found based on ID prefix)", term, len(listByPartialID))
+		return errors.Wrapf(ambigousResultsError(term), "%d matches found based on ID prefix", len(listByPartialID))
 	}
 
 	return libnetwork.ErrNoSuchNetwork(term)
@@ -397,7 +425,9 @@
 		for _, ip4Info := range ipv4Info {
 			iData := network.IPAMConfig{}
 			iData.Subnet = ip4Info.IPAMData.Pool.String()
-			iData.Gateway = ip4Info.IPAMData.Gateway.IP.String()
+			if ip4Info.IPAMData.Gateway != nil {
+				iData.Gateway = ip4Info.IPAMData.Gateway.IP.String()
+			}
 			r.IPAM.Config = append(r.IPAM.Config, iData)
 		}
 	}
@@ -459,7 +489,7 @@
 		return err
 	}
 
-	pruneFilters, err := filters.FromParam(r.Form.Get("filters"))
+	pruneFilters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
diff --git a/api/server/router/plugin/plugin_routes.go b/api/server/router/plugin/plugin_routes.go
index 79e3cf5..d74a01f 100644
--- a/api/server/router/plugin/plugin_routes.go
+++ b/api/server/router/plugin/plugin_routes.go
@@ -290,7 +290,7 @@
 		return err
 	}
 
-	pluginFilters, err := filters.FromParam(r.Form.Get("filters"))
+	pluginFilters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
diff --git a/api/server/router/session/session_routes.go b/api/server/router/session/session_routes.go
index ef9753c..bccd764 100644
--- a/api/server/router/session/session_routes.go
+++ b/api/server/router/session/session_routes.go
@@ -3,14 +3,27 @@
 import (
 	"net/http"
 
-	apierrors "github.com/docker/docker/api/errors"
 	"golang.org/x/net/context"
 )
 
+type invalidRequest struct {
+	cause error
+}
+
+func (e invalidRequest) Error() string {
+	return e.cause.Error()
+}
+
+func (e invalidRequest) Cause() error {
+	return e.cause
+}
+
+func (e invalidRequest) InvalidParameter() {}
+
 func (sr *sessionRouter) startSession(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	err := sr.backend.HandleHTTPRequest(ctx, w, r)
 	if err != nil {
-		return apierrors.NewBadRequestError(err)
+		return invalidRequest{err}
 	}
 	return nil
 }
diff --git a/api/server/router/swarm/cluster_routes.go b/api/server/router/swarm/cluster_routes.go
index 91461da..5b6c19d 100644
--- a/api/server/router/swarm/cluster_routes.go
+++ b/api/server/router/swarm/cluster_routes.go
@@ -6,14 +6,14 @@
 	"net/http"
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/server/httputils"
 	basictypes "github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/filters"
 	types "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/versions"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -57,6 +57,20 @@
 	return httputils.WriteJSON(w, http.StatusOK, swarm)
 }
 
+type invalidRequestError struct {
+	err error
+}
+
+func (e invalidRequestError) Error() string {
+	return e.err.Error()
+}
+
+func (e invalidRequestError) Cause() error {
+	return e.err
+}
+
+func (e invalidRequestError) InvalidParameter() {}
+
 func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	var swarm types.Spec
 	if err := json.NewDecoder(r.Body).Decode(&swarm); err != nil {
@@ -67,7 +81,7 @@
 	version, err := strconv.ParseUint(rawVersion, 10, 64)
 	if err != nil {
 		err := fmt.Errorf("invalid swarm version '%s': %v", rawVersion, err)
-		return errors.NewBadRequestError(err)
+		return invalidRequestError{err}
 	}
 
 	var flags types.UpdateFlags
@@ -76,7 +90,7 @@
 		rot, err := strconv.ParseBool(value)
 		if err != nil {
 			err := fmt.Errorf("invalid value for rotateWorkerToken: %s", value)
-			return errors.NewBadRequestError(err)
+			return invalidRequestError{err}
 		}
 
 		flags.RotateWorkerToken = rot
@@ -86,7 +100,7 @@
 		rot, err := strconv.ParseBool(value)
 		if err != nil {
 			err := fmt.Errorf("invalid value for rotateManagerToken: %s", value)
-			return errors.NewBadRequestError(err)
+			return invalidRequestError{err}
 		}
 
 		flags.RotateManagerToken = rot
@@ -95,7 +109,7 @@
 	if value := r.URL.Query().Get("rotateManagerUnlockKey"); value != "" {
 		rot, err := strconv.ParseBool(value)
 		if err != nil {
-			return errors.NewBadRequestError(fmt.Errorf("invalid value for rotateManagerUnlockKey: %s", value))
+			return invalidRequestError{fmt.Errorf("invalid value for rotateManagerUnlockKey: %s", value)}
 		}
 
 		flags.RotateManagerUnlockKey = rot
@@ -137,9 +151,9 @@
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 	}
-	filter, err := filters.FromParam(r.Form.Get("filters"))
+	filter, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
-		return err
+		return invalidRequestError{err}
 	}
 
 	services, err := sr.backend.GetServices(basictypes.ServiceListOptions{Filters: filter})
@@ -158,7 +172,7 @@
 		insertDefaults, err = strconv.ParseBool(value)
 		if err != nil {
 			err := fmt.Errorf("invalid value for insertDefaults: %s", value)
-			return errors.NewBadRequestError(err)
+			return errors.Wrapf(invalidRequestError{err}, "invalid value for insertDefaults: %s", value)
 		}
 	}
 
@@ -204,7 +218,7 @@
 	version, err := strconv.ParseUint(rawVersion, 10, 64)
 	if err != nil {
 		err := fmt.Errorf("invalid service version '%s': %v", rawVersion, err)
-		return errors.NewBadRequestError(err)
+		return invalidRequestError{err}
 	}
 
 	var flags basictypes.ServiceUpdateOptions
@@ -263,7 +277,7 @@
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 	}
-	filter, err := filters.FromParam(r.Form.Get("filters"))
+	filter, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
@@ -297,7 +311,7 @@
 	version, err := strconv.ParseUint(rawVersion, 10, 64)
 	if err != nil {
 		err := fmt.Errorf("invalid node version '%s': %v", rawVersion, err)
-		return errors.NewBadRequestError(err)
+		return invalidRequestError{err}
 	}
 
 	if err := sr.backend.UpdateNode(vars["id"], version, node); err != nil {
@@ -325,7 +339,7 @@
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 	}
-	filter, err := filters.FromParam(r.Form.Get("filters"))
+	filter, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
@@ -353,7 +367,7 @@
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 	}
-	filters, err := filters.FromParam(r.Form.Get("filters"))
+	filters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
@@ -403,28 +417,24 @@
 func (sr *swarmRouter) updateSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	var secret types.SecretSpec
 	if err := json.NewDecoder(r.Body).Decode(&secret); err != nil {
-		return errors.NewBadRequestError(err)
+		return invalidRequestError{err}
 	}
 
 	rawVersion := r.URL.Query().Get("version")
 	version, err := strconv.ParseUint(rawVersion, 10, 64)
 	if err != nil {
-		return errors.NewBadRequestError(fmt.Errorf("invalid secret version"))
+		return invalidRequestError{fmt.Errorf("invalid secret version")}
 	}
 
 	id := vars["id"]
-	if err := sr.backend.UpdateSecret(id, version, secret); err != nil {
-		return err
-	}
-
-	return nil
+	return sr.backend.UpdateSecret(id, version, secret)
 }
 
 func (sr *swarmRouter) getConfigs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 	}
-	filters, err := filters.FromParam(r.Form.Get("filters"))
+	filters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
@@ -474,19 +484,15 @@
 func (sr *swarmRouter) updateConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	var config types.ConfigSpec
 	if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
-		return errors.NewBadRequestError(err)
+		return invalidRequestError{err}
 	}
 
 	rawVersion := r.URL.Query().Get("version")
 	version, err := strconv.ParseUint(rawVersion, 10, 64)
 	if err != nil {
-		return errors.NewBadRequestError(fmt.Errorf("invalid config version"))
+		return invalidRequestError{fmt.Errorf("invalid config version")}
 	}
 
 	id := vars["id"]
-	if err := sr.backend.UpdateConfig(id, version, config); err != nil {
-		return err
-	}
-
-	return nil
+	return sr.backend.UpdateConfig(id, version, config)
 }
diff --git a/api/server/router/swarm/helpers.go b/api/server/router/swarm/helpers.go
index 7d29442..2c411f7 100644
--- a/api/server/router/swarm/helpers.go
+++ b/api/server/router/swarm/helpers.go
@@ -2,6 +2,7 @@
 
 import (
 	"fmt"
+	"io"
 	"net/http"
 
 	"github.com/docker/docker/api/server/httputils"
@@ -12,7 +13,7 @@
 
 // swarmLogs takes an http response, request, and selector, and writes the logs
 // specified by the selector to the response
-func (sr *swarmRouter) swarmLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, selector *backend.LogSelector) error {
+func (sr *swarmRouter) swarmLogs(ctx context.Context, w io.Writer, r *http.Request, selector *backend.LogSelector) error {
 	// Args are validated before the stream starts because when it starts we're
 	// sending HTTP 200 by writing an empty chunk of data to tell the client that
 	// daemon is going to stream. By sending this initial HTTP 200 we can't report
diff --git a/api/server/router/system/system_routes.go b/api/server/router/system/system_routes.go
index 30fb000..62060a4 100644
--- a/api/server/router/system/system_routes.go
+++ b/api/server/router/system/system_routes.go
@@ -6,9 +6,7 @@
 	"net/http"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api"
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/events"
@@ -18,6 +16,7 @@
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/pkg/ioutils"
 	pkgerrors "github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -85,6 +84,16 @@
 	return httputils.WriteJSON(w, http.StatusOK, du)
 }
 
+type invalidRequestError struct {
+	Err error
+}
+
+func (e invalidRequestError) Error() string {
+	return e.Err.Error()
+}
+
+func (e invalidRequestError) InvalidParameter() {}
+
 func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 	if err := httputils.ParseForm(r); err != nil {
 		return err
@@ -105,7 +114,7 @@
 	)
 	if !until.IsZero() {
 		if until.Before(since) {
-			return errors.NewBadRequestError(fmt.Errorf("`since` time (%s) cannot be after `until` time (%s)", r.Form.Get("since"), r.Form.Get("until")))
+			return invalidRequestError{fmt.Errorf("`since` time (%s) cannot be after `until` time (%s)", r.Form.Get("since"), r.Form.Get("until"))}
 		}
 
 		now := time.Now()
@@ -118,7 +127,7 @@
 		}
 	}
 
-	ef, err := filters.FromParam(r.Form.Get("filters"))
+	ef, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
diff --git a/api/server/router/volume/volume_routes.go b/api/server/router/volume/volume_routes.go
index f0f4901..bfff51a 100644
--- a/api/server/router/volume/volume_routes.go
+++ b/api/server/router/volume/volume_routes.go
@@ -72,7 +72,7 @@
 		return err
 	}
 
-	pruneFilters, err := filters.FromParam(r.Form.Get("filters"))
+	pruneFilters, err := filters.FromJSON(r.Form.Get("filters"))
 	if err != nil {
 		return err
 	}
diff --git a/api/server/server.go b/api/server/server.go
index e0f2d89..bf3774b 100644
--- a/api/server/server.go
+++ b/api/server/server.go
@@ -2,19 +2,17 @@
 
 import (
 	"crypto/tls"
-	"fmt"
 	"net"
 	"net/http"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/server/httputils"
 	"github.com/docker/docker/api/server/middleware"
 	"github.com/docker/docker/api/server/router"
 	"github.com/docker/docker/api/server/router/debug"
 	"github.com/docker/docker/dockerversion"
 	"github.com/gorilla/mux"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -25,7 +23,6 @@
 // Config provides the configuration for the API server
 type Config struct {
 	Logging     bool
-	EnableCors  bool
 	CorsHeaders string
 	Version     string
 	SocketGroup string
@@ -158,6 +155,14 @@
 	}
 }
 
+type pageNotFoundError struct{}
+
+func (pageNotFoundError) Error() string {
+	return "page not found"
+}
+
+func (pageNotFoundError) NotFound() {}
+
 // createMux initializes the main router the server uses.
 func (s *Server) createMux() *mux.Router {
 	m := mux.NewRouter()
@@ -180,8 +185,7 @@
 		m.Path("/debug" + r.Path()).Handler(f)
 	}
 
-	err := errors.NewRequestNotFoundError(fmt.Errorf("page not found"))
-	notFoundHandler := httputils.MakeErrorHandler(err)
+	notFoundHandler := httputils.MakeErrorHandler(pageNotFoundError{})
 	m.HandleFunc(versionMatcher+"/{path:.*}", notFoundHandler)
 	m.NotFoundHandler = notFoundHandler
 
diff --git a/api/swagger.yaml b/api/swagger.yaml
index fbada93..590b378 100644
--- a/api/swagger.yaml
+++ b/api/swagger.yaml
@@ -19,10 +19,10 @@
 consumes:
   - "application/json"
   - "text/plain"
-basePath: "/v1.31"
+basePath: "/v1.34"
 info:
   title: "Docker Engine API"
-  version: "1.31"
+  version: "1.34"
   x-logo:
     url: "https://docs.docker.com/images/logo-docker-main.png"
   description: |
@@ -44,7 +44,7 @@
 
     The API is usually changed in each release of Docker, so API calls are versioned to ensure that clients don't break.
 
-    For Docker Engine 17.06, the API version is 1.30. To lock to this version, you prefix the URL with `/v1.30`. For example, calling `/info` is the same as calling `/v1.30/info`.
+    For Docker Engine 17.10, the API version is 1.33. To lock to this version, you prefix the URL with `/v1.33`. For example, calling `/info` is the same as calling `/v1.33/info`.
 
     Engine releases in the near future should support this version of the API, so your client will continue to work even if it is talking to a newer Engine.
 
@@ -52,10 +52,13 @@
 
     The API uses an open schema model, which means server may add extra properties to responses. Likewise, the server will ignore any extra query parameters and request body properties. When you write clients, you need to ignore additional properties in responses to ensure they do not break when talking to newer Docker daemons.
 
-    This documentation is for version 1.31 of the API. Use this table to find documentation for previous versions of the API:
+    This documentation is for version 1.34 of the API. Use this table to find documentation for previous versions of the API:
 
     Docker version  | API version | Changes
     ----------------|-------------|---------
+    17.10.x | [1.33](https://docs.docker.com/engine/api/v1.33/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-33-api-changes)
+    17.09.x | [1.32](https://docs.docker.com/engine/api/v1.32/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-32-api-changes)
+    17.07.x | [1.31](https://docs.docker.com/engine/api/v1.31/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-31-api-changes)
     17.06.x | [1.30](https://docs.docker.com/engine/api/v1.30/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-30-api-changes)
     17.05.x | [1.29](https://docs.docker.com/engine/api/v1.29/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-29-api-changes)
     17.04.x | [1.28](https://docs.docker.com/engine/api/v1.28/) | [API changes](https://docs.docker.com/engine/api/version-history/#v1-28-api-changes)
@@ -143,6 +146,10 @@
     x-displayName: "Secrets"
     description: |
       Secrets are sensitive data that can be used by services. Swarm mode must be enabled for these endpoints to work.
+  - name: "Config"
+    x-displayName: "Configs"
+    description: |
+      Configs are application configurations that can be used by services. Swarm mode must be enabled for these endpoints to work.
   # System things
   - name: "Plugin"
     x-displayName: "Plugins"
@@ -300,6 +307,7 @@
           Mode:
             description: "The permission mode for the tmpfs mount in an integer."
             type: "integer"
+
   RestartPolicy:
     description: |
       The behavior to apply when the container exits. The default is not to restart.
@@ -399,6 +407,7 @@
       CpusetCpus:
         description: "CPUs in which to allow execution (e.g., `0-3`, `0,1`)"
         type: "string"
+        example: "0-3"
       CpusetMems:
         description: "Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems."
         type: "string"
@@ -493,14 +502,16 @@
       NanoCPUs:
         type: "integer"
         format: "int64"
+        example: 4000000000
       MemoryBytes:
         type: "integer"
         format: "int64"
+        example: 8272408576
       GenericResources:
         $ref: "#/definitions/GenericResources"
 
   GenericResources:
-    description: "User defined Resources, can be either Integer resources (e.g: SSD=3) or String resources (e.g: GPU={UUID1, UUID2})"
+    description: "User-defined resources can be either Integer resources (e.g, `SSD=3`) or String resources (e.g, `GPU=UUID1`)"
     type: "array"
     items:
       type: "object"
@@ -520,6 +531,16 @@
             Value:
               type: "integer"
               format: "int64"
+    example:
+      - DiscreteResourceSpec:
+          Kind: "SSD"
+          Value: 3
+      - NamedResourceSpec:
+          Kind: "GPU"
+          Value: "UUID1"
+      - NamedResourceSpec:
+          Kind: "GPU"
+          Value: "UUID2"
 
   HealthConfig:
     description: "A test to perform to check that the container is healthy."
@@ -562,7 +583,7 @@
               A list of volume bindings for this container. Each volume binding is a string in one of these forms:
 
               - `host-src:container-dest` to bind-mount a host path into the container. Both `host-src`, and `container-dest` must be an _absolute_ path.
-              - `host-src:container-dest:ro` to make the bind-mount read-only inside the container. Both `host-src`, and `container-dest` must be an _absolute_ path.
+              - `host-src:container-dest:ro` to make the bind mount read-only inside the container. Both `host-src`, and `container-dest` must be an _absolute_ path.
               - `volume-name:container-dest` to bind-mount a volume managed by a volume driver into the container. `container-dest` must be an _absolute_ path.
               - `volume-name:container-dest:ro` to mount the volume read-only inside the container.  `container-dest` must be an _absolute_ path.
             items:
@@ -664,7 +685,17 @@
               type: "string"
           IpcMode:
             type: "string"
-            description: "IPC namespace to use for the container."
+            description: |
+                    IPC sharing mode for the container. Possible values are:
+
+                    - `"none"`: own private IPC namespace, with /dev/shm not mounted
+                    - `"private"`: own private IPC namespace
+                    - `"shareable"`: own private IPC namespace, with a possibility to share it with other containers
+                    - `"container:<name|id>"`: join another (shareable) container's IPC namespace
+                    - `"host"`: use the host system's IPC namespace
+
+                    If not specified, daemon default is used, which can either be `"private"`
+                    or `"shareable"`, depending on daemon version and configuration.
           Cgroup:
             type: "string"
             description: "Cgroup to use for the container."
@@ -676,6 +707,7 @@
           OomScoreAdj:
             type: "integer"
             description: "An integer value containing the score given to the container in order to tune OOM killer preferences."
+            example: 500
           PidMode:
             type: "string"
             description: |
@@ -867,26 +899,223 @@
         items:
           type: "string"
 
-  NetworkConfig:
-    description: "TODO: check is correct"
+  NetworkSettings:
+    description: "NetworkSettings exposes the network settings in the API"
     type: "object"
     properties:
       Bridge:
+        description: Name of the network'a bridge (for example, `docker0`).
         type: "string"
-      Gateway:
+        example: "docker0"
+      SandboxID:
+        description: SandboxID uniquely represents a container's network stack.
         type: "string"
-      Address:
+        example: "9d12daf2c33f5959c8bf90aa513e4f65b561738661003029ec84830cd503a0c3"
+      HairpinMode:
+        description: |
+          Indicates if hairpin NAT should be enabled on the virtual interface.
+        type: "boolean"
+        example: false
+      LinkLocalIPv6Address:
+        description: IPv6 unicast address using the link-local prefix.
         type: "string"
-      IPPrefixLen:
+        example: "fe80::42:acff:fe11:1"
+      LinkLocalIPv6PrefixLen:
+        description: Prefix length of the IPv6 unicast address.
         type: "integer"
-      MacAddress:
-        type: "string"
-      PortMapping:
-        type: "string"
+        example: "64"
       Ports:
+        $ref: "#/definitions/PortMap"
+      SandboxKey:
+        description: SandboxKey identifies the sandbox
+        type: "string"
+        example: "/var/run/docker/netns/8ab54b426c38"
+
+      # TODO is SecondaryIPAddresses actually used?
+      SecondaryIPAddresses:
+        description: ""
         type: "array"
         items:
-          $ref: "#/definitions/Port"
+          $ref: "#/definitions/Address"
+        x-nullable: true
+
+      # TODO is SecondaryIPv6Addresses actually used?
+      SecondaryIPv6Addresses:
+        description: ""
+        type: "array"
+        items:
+          $ref: "#/definitions/Address"
+        x-nullable: true
+
+      # TODO properties below are part of DefaultNetworkSettings, which is
+      # marked as deprecated since Docker 1.9 and to be removed in Docker v17.12
+      EndpointID:
+        description: |
+          EndpointID uniquely represents a service endpoint in a Sandbox.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "string"
+        example: "b88f5b905aabf2893f3cbc4ee42d1ea7980bbc0a92e2c8922b1e1795298afb0b"
+      Gateway:
+        description: |
+          Gateway address for the default "bridge" network.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "string"
+        example: "172.17.0.1"
+      GlobalIPv6Address:
+        description: |
+          Global IPv6 address for the default "bridge" network.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "string"
+        example: "2001:db8::5689"
+      GlobalIPv6PrefixLen:
+        description: |
+          Mask length of the global IPv6 address.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "integer"
+        example: 64
+      IPAddress:
+        description: |
+          IPv4 address for the default "bridge" network.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "string"
+        example: "172.17.0.4"
+      IPPrefixLen:
+        description: |
+          Mask length of the IPv4 address.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "integer"
+        example: 16
+      IPv6Gateway:
+        description: |
+          IPv6 gateway address for this network.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "string"
+        example: "2001:db8:2::100"
+      MacAddress:
+        description: |
+          MAC address for the container on the default "bridge" network.
+
+          <p><br /></p>
+
+          > **Deprecated**: This field is only propagated when attached to the
+          > default "bridge" network. Use the information from the "bridge"
+          > network inside the `Networks` map instead, which contains the same
+          > information. This field was deprecated in Docker 1.9 and is scheduled
+          > to be removed in Docker 17.12.0
+        type: "string"
+        example: "02:42:ac:11:00:04"
+      Networks:
+        description: |
+          Information about all networks that the container is connected to.
+        type: "object"
+        additionalProperties:
+          $ref: "#/definitions/EndpointSettings"
+
+  Address:
+    description: Address represents an IPv4 or IPv6 IP address.
+    type: "object"
+    properties:
+      Addr:
+        description: IP address.
+        type: "string"
+      PrefixLen:
+        description: Mask length of the IP address.
+        type: "integer"
+
+  PortMap:
+    description: |
+      PortMap describes the mapping of container ports to host ports, using the
+      container's port-number and protocol as key in the format `<port>/<protocol>`,
+      for example, `80/udp`.
+
+      If a container's port is mapped for both `tcp` and `udp`, two separate
+      entries are added to the mapping table.
+    type: "object"
+    additionalProperties:
+      type: "array"
+      items:
+        $ref: "#/definitions/PortBinding"
+    example:
+      "443/tcp":
+        - HostIp: "127.0.0.1"
+          HostPort: "4443"
+      "80/tcp":
+        - HostIp: "0.0.0.0"
+          HostPort: "80"
+        - HostIp: "0.0.0.0"
+          HostPort: "8080"
+      "80/udp":
+        - HostIp: "0.0.0.0"
+          HostPort: "80"
+      "53/udp":
+        - HostIp: "0.0.0.0"
+          HostPort: "53"
+      "2377/tcp": null
+
+  PortBinding:
+    description: |
+      PortBinding represents a binding between a host IP address and a host
+      port.
+    type: "object"
+    x-nullable: true
+    properties:
+      HostIp:
+        description: "Host IP address that the container's port is mapped to."
+        type: "string"
+        example: "127.0.0.1"
+      HostPort:
+        description: "Host port number that the container's port is mapped to."
+        type: "string"
+        example: "4443"
 
   GraphDriverData:
     description: "Information about a container's graph driver."
@@ -1249,6 +1478,7 @@
           type: "object"
           additionalProperties:
             type: "string"
+
   NetworkContainer:
     type: "object"
     properties:
@@ -1304,6 +1534,7 @@
         type: "string"
       progressDetail:
         $ref: "#/definitions/ProgressDetail"
+
   ErrorDetail:
     type: "object"
     properties:
@@ -1311,6 +1542,7 @@
         type: "integer"
       message:
         type: "string"
+
   ProgressDetail:
     type: "object"
     properties:
@@ -1345,45 +1577,102 @@
     description: "Configuration for a network endpoint."
     type: "object"
     properties:
+      # Configurations
       IPAMConfig:
-        description: "IPAM configurations for the endpoint"
-        type: "object"
-        properties:
-          IPv4Address:
-            type: "string"
-          IPv6Address:
-            type: "string"
-          LinkLocalIPs:
-            type: "array"
-            items:
-              type: "string"
+        $ref: "#/definitions/EndpointIPAMConfig"
       Links:
         type: "array"
         items:
           type: "string"
+        example:
+          - "container_1"
+          - "container_2"
       Aliases:
         type: "array"
         items:
           type: "string"
+        example:
+          - "server_x"
+          - "server_y"
+
+      # Operational data
       NetworkID:
+        description: |
+          Unique ID of the network.
         type: "string"
+        example: "08754567f1f40222263eab4102e1c733ae697e8e354aa9cd6e18d7402835292a"
       EndpointID:
+        description: |
+          Unique ID for the service endpoint in a Sandbox.
         type: "string"
+        example: "b88f5b905aabf2893f3cbc4ee42d1ea7980bbc0a92e2c8922b1e1795298afb0b"
       Gateway:
+        description: |
+          Gateway address for this network.
         type: "string"
+        example: "172.17.0.1"
       IPAddress:
+        description: |
+          IPv4 address.
         type: "string"
+        example: "172.17.0.4"
       IPPrefixLen:
+        description: |
+          Mask length of the IPv4 address.
         type: "integer"
+        example: 16
       IPv6Gateway:
+        description: |
+          IPv6 gateway address.
         type: "string"
+        example: "2001:db8:2::100"
       GlobalIPv6Address:
+        description: |
+          Global IPv6 address.
         type: "string"
+        example: "2001:db8::5689"
       GlobalIPv6PrefixLen:
+        description: |
+          Mask length of the global IPv6 address.
         type: "integer"
         format: "int64"
+        example: 64
       MacAddress:
+        description: |
+          MAC address for the endpoint on this network.
         type: "string"
+        example: "02:42:ac:11:00:04"
+      DriverOpts:
+        description: |
+          DriverOpts is a mapping of driver options and values. These options
+          are passed directly to the driver and are driver specific.
+        type: "object"
+        x-nullable: true
+        additionalProperties:
+          type: "string"
+        example:
+          com.example.some-label: "some-value"
+          com.example.some-other-label: "some-other-value"
+
+  EndpointIPAMConfig:
+    description: |
+      EndpointIPAMConfig represents an endpoint's IPAM configuration.
+    type: "object"
+    x-nullable: true
+    properties:
+      IPv4Address:
+        type: "string"
+        example: "172.20.30.33"
+      IPv6Address:
+        type: "string"
+        example: "2001:db8:abcd::3033"
+      LinkLocalIPs:
+        type: "array"
+        items:
+          type: "string"
+        example:
+          - "169.254.34.68"
+          - "fe80::3468"
 
   PluginMount:
     type: "object"
@@ -1393,25 +1682,33 @@
       Name:
         type: "string"
         x-nullable: false
+        example: "some-mount"
       Description:
         type: "string"
         x-nullable: false
+        example: "This is a mount that's used by the plugin."
       Settable:
         type: "array"
         items:
           type: "string"
       Source:
         type: "string"
+        example: "/var/lib/docker/plugins/"
       Destination:
         type: "string"
         x-nullable: false
+        example: "/mnt/state"
       Type:
         type: "string"
         x-nullable: false
+        example: "bind"
       Options:
         type: "array"
         items:
           type: "string"
+        example:
+          - "rbind"
+          - "rw"
 
   PluginDevice:
     type: "object"
@@ -1430,6 +1727,7 @@
           type: "string"
       Path:
         type: "string"
+        example: "/dev/fuse"
 
   PluginEnv:
     type: "object"
@@ -1471,13 +1769,16 @@
     properties:
       Id:
         type: "string"
+        example: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078"
       Name:
         type: "string"
         x-nullable: false
+        example: "tiborvass/sample-volume-plugin"
       Enabled:
-        description: "True when the plugin is running. False when the plugin is not running, only installed."
+        description: "True if the plugin is running. False if the plugin is not running, only installed."
         type: "boolean"
         x-nullable: false
+        example: true
       Settings:
         description: "Settings that can be modified by users."
         type: "object"
@@ -1492,6 +1793,8 @@
             type: "array"
             items:
               type: "string"
+            example:
+              - "DEBUG=0"
           Args:
             type: "array"
             items:
@@ -1504,6 +1807,7 @@
         description: "plugin remote reference used to push/pull the plugin"
         type: "string"
         x-nullable: false
+        example: "localhost:5000/tiborvass/sample-volume-plugin:latest"
       Config:
         description: "The config of a plugin."
         type: "object"
@@ -1527,12 +1831,15 @@
             description: "Docker Version used to create the plugin"
             type: "string"
             x-nullable: false
+            example: "17.06.0-ce"
           Description:
             type: "string"
             x-nullable: false
+            example: "A sample volume plugin for Docker"
           Documentation:
             type: "string"
             x-nullable: false
+            example: "https://docs.docker.com/engine/extend/plugins/"
           Interface:
             description: "The interface between Docker and the plugin"
             x-nullable: false
@@ -1543,16 +1850,23 @@
                 type: "array"
                 items:
                   $ref: "#/definitions/PluginInterfaceType"
+                example:
+                  - "docker.volumedriver/1.0"
               Socket:
                 type: "string"
                 x-nullable: false
+                example: "plugins.sock"
           Entrypoint:
             type: "array"
             items:
               type: "string"
+            example:
+              - "/usr/bin/sample-volume-plugin"
+              - "/data"
           WorkDir:
             type: "string"
             x-nullable: false
+            example: "/bin/"
           User:
             type: "object"
             x-nullable: false
@@ -1560,9 +1874,11 @@
               UID:
                 type: "integer"
                 format: "uint32"
+                example: 1000
               GID:
                 type: "integer"
                 format: "uint32"
+                example: 1000
           Network:
             type: "object"
             x-nullable: false
@@ -1571,6 +1887,7 @@
               Type:
                 x-nullable: false
                 type: "string"
+                example: "host"
           Linux:
             type: "object"
             x-nullable: false
@@ -1580,9 +1897,13 @@
                 type: "array"
                 items:
                   type: "string"
+                example:
+                  - "CAP_SYS_ADMIN"
+                  - "CAP_SYSLOG"
               AllowAllDevices:
                 type: "boolean"
                 x-nullable: false
+                example: false
               Devices:
                 type: "array"
                 items:
@@ -1590,12 +1911,15 @@
           PropagatedMount:
             type: "string"
             x-nullable: false
+            example: "/mnt/volumes"
           IpcHost:
             type: "boolean"
             x-nullable: false
+            example: false
           PidHost:
             type: "boolean"
             x-nullable: false
+            example: false
           Mounts:
             type: "array"
             items:
@@ -1604,6 +1928,11 @@
             type: "array"
             items:
               $ref: "#/definitions/PluginEnv"
+            example:
+              - Name: "DEBUG"
+                Description: "If set, prints debug messages"
+                Settable: null
+                Value: "0"
           Args:
             type: "object"
             x-nullable: false
@@ -1612,9 +1941,11 @@
               Name:
                 x-nullable: false
                 type: "string"
+                example: "args"
               Description:
                 x-nullable: false
                 type: "string"
+                example: "command line arguments"
               Settable:
                 type: "array"
                 items:
@@ -1628,50 +1959,14 @@
             properties:
               type:
                 type: "string"
+                example: "layers"
               diff_ids:
                 type: "array"
                 items:
                   type: "string"
-    example:
-      Id: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078"
-      Name: "tiborvass/sample-volume-plugin"
-      Tag: "latest"
-      Active: true
-      Settings:
-        Env:
-          - "DEBUG=0"
-        Args: null
-        Devices: null
-      Config:
-        Description: "A sample volume plugin for Docker"
-        Documentation: "https://docs.docker.com/engine/extend/plugins/"
-        Interface:
-          Types:
-            - "docker.volumedriver/1.0"
-          Socket: "plugins.sock"
-        Entrypoint:
-          - "/usr/bin/sample-volume-plugin"
-          - "/data"
-        WorkDir: ""
-        User: {}
-        Network:
-          Type: ""
-        Linux:
-          Capabilities: null
-          AllowAllDevices: false
-          Devices: null
-        Mounts: null
-        PropagatedMount: "/data"
-        Env:
-          - Name: "DEBUG"
-            Description: "If set, prints debug messages"
-            Settable: null
-            Value: "0"
-        Args:
-          Name: "args"
-          Description: "command line arguments"
-          Settable: null
-          Value: []
+                example:
+                  - "sha256:675532206fbf3030b8458f88d6e26d4eb1577688a25efec97154c94e8b6b4887"
+                  - "sha256:e216a057b1cb1efc11f8a268f37ef62083e70b1b38323ba252e25ac88904a7e8"
 
   ObjectVersion:
     description: |
@@ -1686,7 +1981,8 @@
     properties:
       Index:
         type: "integer"
-        format: "int64"
+        format: "uint64"
+        example: 373531
 
   NodeSpec:
     type: "object"
@@ -1694,6 +1990,7 @@
       Name:
         description: "Name for the node."
         type: "string"
+        example: "my-node"
       Labels:
         description: "User-defined key/value metadata."
         type: "object"
@@ -1705,6 +2002,7 @@
         enum:
           - "worker"
           - "manager"
+        example: "manager"
       Availability:
         description: "Availability of the node."
         type: "string"
@@ -1712,125 +2010,140 @@
           - "active"
           - "pause"
           - "drain"
+        example: "active"
     example:
       Availability: "active"
       Name: "node-name"
       Role: "manager"
       Labels:
         foo: "bar"
+
   Node:
     type: "object"
     properties:
       ID:
         type: "string"
+        example: "24ifsmvkjbyhk"
       Version:
         $ref: "#/definitions/ObjectVersion"
       CreatedAt:
+        description: |
+          Date and time at which the node was added to the swarm in
+          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
         type: "string"
         format: "dateTime"
+        example: "2016-08-18T10:44:24.496525531Z"
       UpdatedAt:
+        description: |
+          Date and time at which the node was last updated in
+          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
         type: "string"
         format: "dateTime"
+        example: "2017-08-09T07:09:37.632105588Z"
       Spec:
         $ref: "#/definitions/NodeSpec"
       Description:
-        type: "object"
-        properties:
-          Hostname:
-            type: "string"
-          Platform:
-            type: "object"
-            properties:
-              Architecture:
-                type: "string"
-              OS:
-                type: "string"
-          Resources:
-            $ref: "#/definitions/ResourceObject"
-          Engine:
-            type: "object"
-            properties:
-              EngineVersion:
-                type: "string"
-              Labels:
-                type: "object"
-                additionalProperties:
-                  type: "string"
-              Plugins:
-                type: "array"
-                items:
-                  type: "object"
-                  properties:
-                    Type:
-                      type: "string"
-                    Name:
-                      type: "string"
-          TLSInfo:
-            $ref: "#/definitions/SwarmSpec"
-    example:
-      ID: "24ifsmvkjbyhk"
-      Version:
-        Index: 8
-      CreatedAt: "2016-06-07T20:31:11.853781916Z"
-      UpdatedAt: "2016-06-07T20:31:11.999868824Z"
-      Spec:
-        Name: "my-node"
-        Role: "manager"
-        Availability: "active"
-        Labels:
-          foo: "bar"
-      Description:
-        Hostname: "bf3067039e47"
-        Platform:
-          Architecture: "x86_64"
-          OS: "linux"
-        Resources:
-          NanoCPUs: 4000000000
-          MemoryBytes: 8272408576
-          GenericResources:
-            - DiscreteResourceSpec:
-                Kind: "SSD"
-                Value: 3
-            - NamedResourceSpec:
-                Kind: "GPU"
-                Value: "UUID1"
-            - NamedResourceSpec:
-                Kind: "GPU"
-                Value: "UUID2"
-        Engine:
-          EngineVersion: "17.04.0"
-          Labels:
-            foo: "bar"
-          Plugins:
-            - Type: "Volume"
-              Name: "local"
-            - Type: "Network"
-              Name: "bridge"
-            - Type: "Network"
-              Name: "null"
-            - Type: "Network"
-              Name: "overlay"
+        $ref: "#/definitions/NodeDescription"
       Status:
-        State: "ready"
-        Addr: "172.17.0.2"
+        $ref: "#/definitions/NodeStatus"
       ManagerStatus:
-        Leader: true
-        Reachability: "reachable"
-        Addr: "172.17.0.2:2377"
+        $ref: "#/definitions/ManagerStatus"
+
+  NodeDescription:
+    description: |
+      NodeDescription encapsulates the properties of the Node as reported by the
+      agent.
+    type: "object"
+    properties:
+      Hostname:
+        type: "string"
+        example: "bf3067039e47"
+      Platform:
+        $ref: "#/definitions/Platform"
+      Resources:
+        $ref: "#/definitions/ResourceObject"
+      Engine:
+        $ref: "#/definitions/EngineDescription"
       TLSInfo:
-        TrustRoot: |
-          -----BEGIN CERTIFICATE-----
-          MIIBajCCARCgAwIBAgIUbYqrLSOSQHoxD8CwG6Bi2PJi9c8wCgYIKoZIzj0EAwIw
-          EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwNDI0MjE0MzAwWhcNMzcwNDE5MjE0
-          MzAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH
-          A0IABJk/VyMPYdaqDXJb/VXh5n/1Yuv7iNrxV3Qb3l06XD46seovcDWs3IZNV1lf
-          3Skyr0ofcchipoiHkXBODojJydSjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
-          Af8EBTADAQH/MB0GA1UdDgQWBBRUXxuRcnFjDfR/RIAUQab8ZV/n4jAKBggqhkjO
-          PQQDAgNIADBFAiAy+JTe6Uc3KyLCMiqGl2GyWGQqQDEcO3/YG36x7om65AIhAJvz
-          pxv6zFeVEkAEEkqIYi0omA9+CjanB/6Bz4n1uw8H
-          -----END CERTIFICATE-----
-        CertIssuerSubject: "MBMxETAPBgNVBAMTCHN3YXJtLWNh"
-        CertIssuerPublicKey: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmT9XIw9h1qoNclv9VeHmf/Vi6/uI2vFXdBveXTpcPjqx6i9wNazchk1XWV/dKTKvSh9xyGKmiIeRcE4OiMnJ1A=="
+        $ref: "#/definitions/TLSInfo"
+
+  Platform:
+    description: |
+      Platform represents the platform (Arch/OS).
+    type: "object"
+    properties:
+      Architecture:
+        description: |
+          Architecture represents the hardware architecture (for example,
+          `x86_64`).
+        type: "string"
+        example: "x86_64"
+      OS:
+        description: |
+          OS represents the Operating System (for example, `linux` or `windows`).
+        type: "string"
+        example: "linux"
+
+  EngineDescription:
+    description: "EngineDescription provides information about an engine."
+    type: "object"
+    properties:
+      EngineVersion:
+        type: "string"
+        example: "17.06.0"
+      Labels:
+        type: "object"
+        additionalProperties:
+          type: "string"
+        example:
+          foo: "bar"
+      Plugins:
+        type: "array"
+        items:
+          type: "object"
+          properties:
+            Type:
+              type: "string"
+            Name:
+              type: "string"
+        example:
+          - Type: "Log"
+            Name: "awslogs"
+          - Type: "Log"
+            Name: "fluentd"
+          - Type: "Log"
+            Name: "gcplogs"
+          - Type: "Log"
+            Name: "gelf"
+          - Type: "Log"
+            Name: "journald"
+          - Type: "Log"
+            Name: "json-file"
+          - Type: "Log"
+            Name: "logentries"
+          - Type: "Log"
+            Name: "splunk"
+          - Type: "Log"
+            Name: "syslog"
+          - Type: "Network"
+            Name: "bridge"
+          - Type: "Network"
+            Name: "host"
+          - Type: "Network"
+            Name: "ipvlan"
+          - Type: "Network"
+            Name: "macvlan"
+          - Type: "Network"
+            Name: "null"
+          - Type: "Network"
+            Name: "overlay"
+          - Type: "Volume"
+            Name: "local"
+          - Type: "Volume"
+            Name: "localhost:5000/vieux/sshfs:latest"
+          - Type: "Volume"
+            Name: "vieux/sshfs:latest"
+
   TLSInfo:
     description: "Information about the issuer of leaf TLS certificates and the trusted root CA certificate"
     type: "object"
@@ -1858,6 +2171,64 @@
         -----END CERTIFICATE-----
       CertIssuerSubject: "MBMxETAPBgNVBAMTCHN3YXJtLWNh"
       CertIssuerPublicKey: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmT9XIw9h1qoNclv9VeHmf/Vi6/uI2vFXdBveXTpcPjqx6i9wNazchk1XWV/dKTKvSh9xyGKmiIeRcE4OiMnJ1A=="
+
+  NodeStatus:
+    description: |
+      NodeStatus represents the status of a node.
+
+      It provides the current status of the node, as seen by the manager.
+    type: "object"
+    properties:
+      State:
+        $ref: "#/definitions/NodeState"
+      Message:
+        type: "string"
+        example: ""
+      Addr:
+        description: "IP address of the node."
+        type: "string"
+        example: "172.17.0.2"
+
+  NodeState:
+    description: "NodeState represents the state of a node."
+    type: "string"
+    enum:
+      - "unknown"
+      - "down"
+      - "ready"
+      - "disconnected"
+    example: "ready"
+
+  ManagerStatus:
+    description: |
+      ManagerStatus represents the status of a manager.
+
+      It provides the current status of a node's manager component, if the node
+      is a manager.
+    x-nullable: true
+    type: "object"
+    properties:
+      Leader:
+        type: "boolean"
+        default: false
+        example: true
+      Reachability:
+        $ref: "#/definitions/Reachability"
+      Addr:
+        description: |
+          The IP address and port at which the manager is reachable.
+        type: "string"
+        example: "10.0.0.46:2377"
+
+  Reachability:
+    description: "Reachability represents the reachability of a node."
+    type: "string"
+    enum:
+      - "unknown"
+      - "unreachable"
+      - "reachable"
+    example: "reachable"
+
   SwarmSpec:
     description: "User modifiable swarm configuration."
     type: "object"
@@ -1865,19 +2236,25 @@
       Name:
         description: "Name of the swarm."
         type: "string"
+        example: "default"
       Labels:
         description: "User-defined key/value metadata."
         type: "object"
         additionalProperties:
           type: "string"
+        example:
+          com.example.corp.type: "production"
+          com.example.corp.department: "engineering"
       Orchestration:
         description: "Orchestration configuration."
         type: "object"
+        x-nullable: true
         properties:
           TaskHistoryRetentionLimit:
             description: "The number of historic tasks to keep per instance or node. If negative, never remove completed or failed tasks."
             type: "integer"
             format: "int64"
+            example: 10
       Raft:
         description: "Raft configuration."
         type: "object"
@@ -1885,43 +2262,51 @@
           SnapshotInterval:
             description: "The number of log entries between snapshots."
             type: "integer"
-            format: "int64"
+            format: "uint64"
+            example: 10000
           KeepOldSnapshots:
             description: "The number of snapshots to keep beyond the current snapshot."
             type: "integer"
-            format: "int64"
+            format: "uint64"
           LogEntriesForSlowFollowers:
             description: "The number of log entries to keep around to sync up slow followers after a snapshot is created."
             type: "integer"
-            format: "int64"
+            format: "uint64"
+            example: 500
           ElectionTick:
             description: |
               The number of ticks that a follower will wait for a message from the leader before becoming a candidate and starting an election. `ElectionTick` must be greater than `HeartbeatTick`.
 
               A tick currently defaults to one second, so these translate directly to seconds currently, but this is NOT guaranteed.
             type: "integer"
+            example: 3
           HeartbeatTick:
             description: |
               The number of ticks between heartbeats. Every HeartbeatTick ticks, the leader will send a heartbeat to the followers.
 
               A tick currently defaults to one second, so these translate directly to seconds currently, but this is NOT guaranteed.
             type: "integer"
+            example: 1
       Dispatcher:
         description: "Dispatcher configuration."
         type: "object"
+        x-nullable: true
         properties:
           HeartbeatPeriod:
             description: "The delay for an agent to send a heartbeat to the dispatcher."
             type: "integer"
             format: "int64"
+            example: 5000000000
       CAConfig:
         description: "CA configuration."
         type: "object"
+        x-nullable: true
         properties:
           NodeCertExpiry:
             description: "The duration node certificates are issued for."
             type: "integer"
             format: "int64"
+            example: 7776000000000000
           ExternalCAs:
             description: "Configuration for forwarding signing requests to an external certificate authority."
             type: "array"
@@ -1953,6 +2338,8 @@
             type: "string"
           ForceRotate:
             description: "An integer whose purpose is to force swarm to generate a new signing CA certificate and key, if none have been specified in `SigningCACert` and `SigningCAKey`"
+            format: "uint64"
+            type: "integer"
       EncryptionConfig:
         description: "Parameters related to encryption-at-rest."
         type: "object"
@@ -1960,57 +2347,65 @@
           AutoLockManagers:
             description: "If set, generate a key and use it to lock data stored on the managers."
             type: "boolean"
+            example: false
       TaskDefaults:
         description: "Defaults for creating tasks in this cluster."
         type: "object"
         properties:
           LogDriver:
             description: |
-              The log driver to use for tasks created in the orchestrator if unspecified by a service.
+              The log driver to use for tasks created in the orchestrator if
+              unspecified by a service.
 
-              Updating this value will only have an affect on new tasks. Old tasks will continue use their previously configured log driver until recreated.
+              Updating this value only affects new tasks. Existing tasks continue
+              to use their previously configured log driver until recreated.
             type: "object"
             properties:
               Name:
+                description: |
+                  The log driver to use as a default for new tasks.
                 type: "string"
+                example: "json-file"
               Options:
+                description: |
+                  Driver-specific options for the selectd log driver, specified
+                  as key/value pairs.
                 type: "object"
                 additionalProperties:
                   type: "string"
-    example:
-      Name: "default"
-      Orchestration:
-        TaskHistoryRetentionLimit: 10
-      Raft:
-        SnapshotInterval: 10000
-        LogEntriesForSlowFollowers: 500
-        HeartbeatTick: 1
-        ElectionTick: 3
-      Dispatcher:
-        HeartbeatPeriod: 5000000000
-      CAConfig:
-        NodeCertExpiry: 7776000000000000
-      JoinTokens:
-        Worker: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx"
-        Manager: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2"
-      EncryptionConfig:
-        AutoLockManagers: false
+                example:
+                  "max-file": "10"
+                  "max-size": "100m"
+
   # The Swarm information for `GET /info`. It is the same as `GET /swarm`, but
   # without `JoinTokens`.
   ClusterInfo:
+    description: |
+      ClusterInfo represents information about the swarm as is returned by the
+      "/info" endpoint. Join-tokens are not included.
+    x-nullable: true
     type: "object"
     properties:
       ID:
         description: "The ID of the swarm."
         type: "string"
+        example: "abajmipo7b4xz5ip2nrla6b11"
       Version:
         $ref: "#/definitions/ObjectVersion"
       CreatedAt:
+        description: |
+          Date and time at which the swarm was initialised in
+          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
         type: "string"
         format: "dateTime"
+        example: "2016-08-18T10:44:24.496525531Z"
       UpdatedAt:
+        description: |
+          Date and time at which the swarm was last updated in
+          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.
         type: "string"
         format: "dateTime"
+        example: "2017-08-09T07:09:37.632105588Z"
       Spec:
         $ref: "#/definitions/SwarmSpec"
       TLSInfo:
@@ -2018,13 +2413,40 @@
       RootRotationInProgress:
         description: "Whether there is currently a root CA rotation in progress for the swarm"
         type: "boolean"
+        example: false
+
+  JoinTokens:
+    description: |
+      JoinTokens contains the tokens workers and managers need to join the swarm.
+    type: "object"
+    properties:
+      Worker:
+        description: |
+          The token workers can use to join the swarm.
+        type: "string"
+        example: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx"
+      Manager:
+        description: |
+          The token managers can use to join the swarm.
+        type: "string"
+        example: "SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2"
+
+  Swarm:
+    type: "object"
+    allOf:
+      - $ref: "#/definitions/ClusterInfo"
+      - type: "object"
+        properties:
+          JoinTokens:
+            $ref: "#/definitions/JoinTokens"
+
   TaskSpec:
     description: "User modifiable task configuration."
     type: "object"
     properties:
       PluginSpec:
         type: "object"
-        description: "Invalid when specified with `ContainerSpec`."
+        description: "Invalid when specified with `ContainerSpec`. *(Experimental release only.)*"
         properties:
           Name:
             description: "The name or 'alias' to use for the plugin."
@@ -2167,10 +2589,12 @@
           Hosts:
             type: "array"
             description: |
-              A list of hostnames/IP mappings to add to the container's `/etc/hosts` file.
-              The format of extra hosts on swarmkit is specified in:
-              http://man7.org/linux/man-pages/man5/hosts.5.html
-                IP_address canonical_hostname [aliases...]
+              A list of hostname/IP mappings to add to the container's `hosts`
+              file. The format of extra hosts is specified in the
+              [hosts(5)](http://man7.org/linux/man-pages/man5/hosts.5.html)
+              man page:
+
+                  IP_address canonical_hostname [aliases...]
             items:
               type: "string"
           DNSConfig:
@@ -2298,6 +2722,10 @@
             type: "array"
             items:
               type: "string"
+            example:
+              - "node.hostname!=node3.corp.example.com"
+              - "node.role!=manager"
+              - "node.labels.type==production"
           Preferences:
             description: "Preferences provide a way to make the scheduler aware of factors such as topology. They are provided in order from highest to lowest precedence."
             type: "array"
@@ -2310,16 +2738,20 @@
                     SpreadDescriptor:
                       description: "label descriptor, such as engine.labels.az"
                       type: "string"
+            example:
+              - Spread:
+                  SpreadDescriptor: "node.labels.datacenter"
+              - Spread:
+                  SpreadDescriptor: "node.labels.rack"
           Platforms:
-            description: "An array of supported platforms."
+            description: |
+              Platforms stores all the platforms that the service's image can
+              run on. This field is used in the platform filter for scheduling.
+              If empty, then the platform filter is off, meaning there are no
+              scheduling restrictions.
             type: "array"
             items:
-              type: "object"
-              properties:
-                Architecture:
-                  type: "string"
-                OS:
-                  type: "string"
+              $ref: "#/definitions/Platform"
       ForceUpdate:
         description: "A counter that triggers an update even if no relevant parameters have been changed."
         type: "integer"
@@ -2347,6 +2779,7 @@
             type: "object"
             additionalProperties:
               type: "string"
+
   TaskState:
     type: "string"
     enum:
@@ -2363,6 +2796,7 @@
       - "shutdown"
       - "failed"
       - "rejected"
+
   Task:
     type: "object"
     properties:
@@ -2486,6 +2920,7 @@
         - NamedResourceSpec:
             Kind: "GPU"
             Value: "UUID2"
+
   ServiceSpec:
     description: "User modifiable configuration for a service."
     properties:
@@ -2590,6 +3025,7 @@
                 type: "string"
       EndpointSpec:
         $ref: "#/definitions/EndpointSpec"
+
   EndpointPortConfig:
     type: "object"
     properties:
@@ -2606,6 +3042,7 @@
       PublishedPort:
         description: "The port on the swarm hosts."
         type: "integer"
+
   EndpointSpec:
     description: "Properties that can be configured to access and load balance a service."
     type: "object"
@@ -2623,6 +3060,7 @@
         type: "array"
         items:
           $ref: "#/definitions/EndpointPortConfig"
+
   Service:
     type: "object"
     properties:
@@ -2735,6 +3173,7 @@
           -
             NetworkID: "4qvuz4ko70xaltuqbt8956gd1"
             Addr: "10.255.0.3/16"
+
   ImageDeleteResponseItem:
     type: "object"
     properties:
@@ -2744,6 +3183,7 @@
       Deleted:
         description: "The image ID of an image that was deleted"
         type: "string"
+
   ServiceUpdateResponse:
     type: "object"
     properties:
@@ -2754,6 +3194,7 @@
           type: "string"
     example:
       Warning: "unable to pin image doesnotexist:latest to digest: image library/doesnotexist:latest not found"
+
   ContainerSummary:
     type: "array"
     items:
@@ -2822,6 +3263,27 @@
           type: "array"
           items:
             $ref: "#/definitions/Mount"
+
+  Driver:
+    description: "Driver represents a driver (network, logging, secrets)."
+    type: "object"
+    required: [Name]
+    properties:
+      Name:
+        description: "Name of the driver."
+        type: "string"
+        x-nullable: false
+        example: "some-driver"
+      Options:
+        description: "Key/value map of driver-specific options."
+        type: "object"
+        x-nullable: false
+        additionalProperties:
+          type: "string"
+        example:
+          OptionA: "value for driver-specific option A"
+          OptionB: "value for driver-specific option B"
+
   SecretSpec:
     type: "object"
     properties:
@@ -2833,26 +3295,41 @@
         type: "object"
         additionalProperties:
           type: "string"
+        example:
+          com.example.some-label: "some-value"
+          com.example.some-other-label: "some-other-value"
       Data:
-        description: "Base64-url-safe-encoded secret data"
-        type: "array"
-        items:
-          type: "string"
+        description: |
+          Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-3.2))
+          data to store as secret.
+
+          This field is only used to _create_ a secret, and is not returned by
+          other endpoints.
+        type: "string"
+        example: ""
+      Driver:
+        description: "Name of the secrets driver used to fetch the secret's value from an external secret store"
+        $ref: "#/definitions/Driver"
+
   Secret:
     type: "object"
     properties:
       ID:
         type: "string"
+        example: "blt1owaxmitz71s9v5zh81zun"
       Version:
         $ref: "#/definitions/ObjectVersion"
       CreatedAt:
         type: "string"
         format: "dateTime"
+        example: "2017-07-20T13:55:28.678958722Z"
       UpdatedAt:
         type: "string"
         format: "dateTime"
+        example: "2017-07-20T13:55:28.678958722Z"
       Spec:
         $ref: "#/definitions/SecretSpec"
+
   ConfigSpec:
     type: "object"
     properties:
@@ -2865,10 +3342,11 @@
         additionalProperties:
           type: "string"
       Data:
-        description: "Base64-url-safe-encoded config data"
-        type: "array"
-        items:
-          type: "string"
+        description: |
+          Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-3.2))
+          config data.
+        type: "string"
+
   Config:
     type: "object"
     properties:
@@ -2885,6 +3363,774 @@
       Spec:
         $ref: "#/definitions/ConfigSpec"
 
+  SystemInfo:
+    type: "object"
+    properties:
+      ID:
+        description: |
+          Unique identifier of the daemon.
+
+          <p><br /></p>
+
+          > **Note**: The format of the ID itself is not part of the API, and
+          > should not be considered stable.
+        type: "string"
+        example: "7TRN:IPZB:QYBB:VPBQ:UMPP:KARE:6ZNR:XE6T:7EWV:PKF4:ZOJD:TPYS"
+      Containers:
+        description: "Total number of containers on the host."
+        type: "integer"
+        example: 14
+      ContainersRunning:
+        description: |
+          Number of containers with status `"running"`.
+        type: "integer"
+        example: 3
+      ContainersPaused:
+        description: |
+          Number of containers with status `"paused"`.
+        type: "integer"
+        example: 1
+      ContainersStopped:
+        description: |
+          Number of containers with status `"stopped"`.
+        type: "integer"
+        example: 10
+      Images:
+        description: |
+          Total number of images on the host.
+
+          Both _tagged_ and _untagged_ (dangling) images are counted.
+        type: "integer"
+        example: 508
+      Driver:
+        description: "Name of the storage driver in use."
+        type: "string"
+        example: "overlay2"
+      DriverStatus:
+        description: |
+          Information specific to the storage driver, provided as
+          "label" / "value" pairs.
+
+          This information is provided by the storage driver, and formatted
+          in a way consistent with the output of `docker info` on the command
+          line.
+
+          <p><br /></p>
+
+          > **Note**: The information returned in this field, including the
+          > formatting of values and labels, should not be considered stable,
+          > and may change without notice.
+        type: "array"
+        items:
+          type: "array"
+          items:
+            type: "string"
+        example:
+          - ["Backing Filesystem", "extfs"]
+          - ["Supports d_type", "true"]
+          - ["Native Overlay Diff", "true"]
+      DockerRootDir:
+        description: |
+          Root directory of persistent Docker state.
+
+          Defaults to `/var/lib/docker` on Linux, and `C:\ProgramData\docker`
+          on Windows.
+        type: "string"
+        example: "/var/lib/docker"
+      SystemStatus:
+        description: |
+          Status information about this node (standalone Swarm API).
+
+          <p><br /></p>
+
+          > **Note**: The information returned in this field is only propagated
+          > by the Swarm standalone API, and is empty (`null`) when using
+          > built-in swarm mode.
+        type: "array"
+        items:
+          type: "array"
+          items:
+            type: "string"
+        example:
+          - ["Role", "primary"]
+          - ["State", "Healthy"]
+          - ["Strategy", "spread"]
+          - ["Filters", "health, port, containerslots, dependency, affinity, constraint, whitelist"]
+          - ["Nodes", "2"]
+          - [" swarm-agent-00", "192.168.99.102:2376"]
+          - ["  └ ID", "5CT6:FBGO:RVGO:CZL4:PB2K:WCYN:2JSV:KSHH:GGFW:QOPG:6J5Q:IOZ2|192.168.99.102:2376"]
+          - ["  └ Status", "Healthy"]
+          - ["  └ Containers", "1 (1 Running, 0 Paused, 0 Stopped)"]
+          - ["  └ Reserved CPUs", "0 / 1"]
+          - ["  └ Reserved Memory", "0 B / 1.021 GiB"]
+          - ["  └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"]
+          - ["  └ UpdatedAt", "2017-08-09T10:03:46Z"]
+          - ["  └ ServerVersion", "17.06.0-ce"]
+          - [" swarm-manager", "192.168.99.101:2376"]
+          - ["  └ ID", "TAMD:7LL3:SEF7:LW2W:4Q2X:WVFH:RTXX:JSYS:XY2P:JEHL:ZMJK:JGIW|192.168.99.101:2376"]
+          - ["  └ Status", "Healthy"]
+          - ["  └ Containers", "2 (2 Running, 0 Paused, 0 Stopped)"]
+          - ["  └ Reserved CPUs", "0 / 1"]
+          - ["  └ Reserved Memory", "0 B / 1.021 GiB"]
+          - ["  └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"]
+          - ["  └ UpdatedAt", "2017-08-09T10:04:11Z"]
+          - ["  └ ServerVersion", "17.06.0-ce"]
+      Plugins:
+        $ref: "#/definitions/PluginsInfo"
+      MemoryLimit:
+        description: "Indicates if the host has memory limit support enabled."
+        type: "boolean"
+        example: true
+      SwapLimit:
+        description: "Indicates if the host has memory swap limit support enabled."
+        type: "boolean"
+        example: true
+      KernelMemory:
+        description: "Indicates if the host has kernel memory limit support enabled."
+        type: "boolean"
+        example: true
+      CpuCfsPeriod:
+        description: "Indicates if CPU CFS(Completely Fair Scheduler) period is supported by the host."
+        type: "boolean"
+        example: true
+      CpuCfsQuota:
+        description: "Indicates if CPU CFS(Completely Fair Scheduler) quota is supported by the host."
+        type: "boolean"
+        example: true
+      CPUShares:
+        description: "Indicates if CPU Shares limiting is supported by the host."
+        type: "boolean"
+        example: true
+      CPUSet:
+        description: |
+          Indicates if CPUsets (cpuset.cpus, cpuset.mems) are supported by the host.
+
+          See [cpuset(7)](https://www.kernel.org/doc/Documentation/cgroup-v1/cpusets.txt)
+        type: "boolean"
+        example: true
+      OomKillDisable:
+        description: "Indicates if OOM killer disable is supported on the host."
+        type: "boolean"
+      IPv4Forwarding:
+        description: "Indicates IPv4 forwarding is enabled."
+        type: "boolean"
+        example: true
+      BridgeNfIptables:
+        description: "Indicates if `bridge-nf-call-iptables` is available on the host."
+        type: "boolean"
+        example: true
+      BridgeNfIp6tables:
+        description: "Indicates if `bridge-nf-call-ip6tables` is available on the host."
+        type: "boolean"
+        example: true
+      Debug:
+        description: "Indicates if the daemon is running in debug-mode / with debug-level logging enabled."
+        type: "boolean"
+        example: true
+      NFd:
+        description: |
+          The total number of file Descriptors in use by the daemon process.
+
+          This information is only returned if debug-mode is enabled.
+        type: "integer"
+        example: 64
+      NGoroutines:
+        description: |
+          The  number of goroutines that currently exist.
+
+          This information is only returned if debug-mode is enabled.
+        type: "integer"
+        example: 174
+      SystemTime:
+        description: |
+          Current system-time in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt)
+          format with nano-seconds.
+        type: "string"
+        example: "2017-08-08T20:28:29.06202363Z"
+      LoggingDriver:
+        description: |
+          The logging driver to use as a default for new containers.
+        type: "string"
+      CgroupDriver:
+        description: |
+          The driver to use for managing cgroups.
+        type: "string"
+        enum: ["cgroupfs", "systemd"]
+        default: "cgroupfs"
+        example: "cgroupfs"
+      NEventsListener:
+        description: "Number of event listeners subscribed."
+        type: "integer"
+        example: 30
+      KernelVersion:
+        description: |
+          Kernel version of the host.
+
+          On Linux, this information obtained from `uname`. On Windows this
+          information is queried from the <kbd>HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\</kbd>
+          registry value, for example _"10.0 14393 (14393.1198.amd64fre.rs1_release_sec.170427-1353)"_.
+        type: "string"
+        example: "4.9.38-moby"
+      OperatingSystem:
+        description: |
+          Name of the host's operating system, for example: "Ubuntu 16.04.2 LTS"
+          or "Windows Server 2016 Datacenter"
+        type: "string"
+        example: "Alpine Linux v3.5"
+      OSType:
+        description: |
+          Generic type of the operating system of the host, as returned by the
+          Go runtime (`GOOS`).
+
+          Currently returned values are "linux" and "windows". A full list of
+          possible values can be found in the [Go documentation](https://golang.org/doc/install/source#environment).
+        type: "string"
+        example: "linux"
+      Architecture:
+        description: |
+          Hardware architecture of the host, as returned by the Go runtime
+          (`GOARCH`).
+
+          A full list of possible values can be found in the [Go documentation](https://golang.org/doc/install/source#environment).
+        type: "string"
+        example: "x86_64"
+      NCPU:
+        description: |
+          The number of logical CPUs usable by the daemon.
+
+          The number of available CPUs is checked by querying the operating
+          system when the daemon starts. Changes to operating system CPU
+          allocation after the daemon is started are not reflected.
+        type: "integer"
+        example: 4
+      MemTotal:
+        description: |
+          Total amount of physical memory available on the host, in kilobytes (kB).
+        type: "integer"
+        format: "int64"
+        example: 2095882240
+
+      IndexServerAddress:
+        description: |
+          Address / URL of the index server that is used for image search,
+          and as a default for user authentication for Docker Hub and Docker Cloud.
+        default: "https://index.docker.io/v1/"
+        type: "string"
+        example: "https://index.docker.io/v1/"
+      RegistryConfig:
+        $ref: "#/definitions/RegistryServiceConfig"
+      GenericResources:
+        $ref: "#/definitions/GenericResources"
+      HttpProxy:
+        description: |
+          HTTP-proxy configured for the daemon. This value is obtained from the
+          [`HTTP_PROXY`](https://www.gnu.org/software/wget/manual/html_node/Proxies.html) environment variable.
+
+          Containers do not automatically inherit this configuration.
+        type: "string"
+        example: "http://user:pass@proxy.corp.example.com:8080"
+      HttpsProxy:
+        description: |
+          HTTPS-proxy configured for the daemon. This value is obtained from the
+          [`HTTPS_PROXY`](https://www.gnu.org/software/wget/manual/html_node/Proxies.html) environment variable.
+
+          Containers do not automatically inherit this configuration.
+        type: "string"
+        example: "https://user:pass@proxy.corp.example.com:4443"
+      NoProxy:
+        description: |
+          Comma-separated list of domain extensions for which no proxy should be
+          used. This value is obtained from the [`NO_PROXY`](https://www.gnu.org/software/wget/manual/html_node/Proxies.html)
+          environment variable.
+
+          Containers do not automatically inherit this configuration.
+        type: "string"
+        example: "*.local, 169.254/16"
+      Name:
+        description: "Hostname of the host."
+        type: "string"
+        example: "node5.corp.example.com"
+      Labels:
+        description: |
+          User-defined labels (key/value metadata) as set on the daemon.
+
+          <p><br /></p>
+
+          > **Note**: When part of a Swarm, nodes can both have _daemon_ labels,
+          > set through the daemon configuration, and _node_ labels, set from a
+          > manager node in the Swarm. Node labels are not included in this
+          > field. Node labels can be retrieved using the `/nodes/(id)` endpoint
+          > on a manager node in the Swarm.
+        type: "array"
+        items:
+          type: "string"
+        example: ["storage=ssd", "production"]
+      ExperimentalBuild:
+        description: |
+          Indicates if experimental features are enabled on the daemon.
+        type: "boolean"
+        example: true
+      ServerVersion:
+        description: |
+          Version string of the daemon.
+
+          > **Note**: the [standalone Swarm API](https://docs.docker.com/swarm/swarm-api/)
+          > returns the Swarm version instead of the daemon  version, for example
+          > `swarm/1.2.8`.
+        type: "string"
+        example: "17.06.0-ce"
+      ClusterStore:
+        description: |
+          URL of the distributed storage backend.
+
+
+          The storage backend is used for multihost networking (to store
+          network and endpoint information) and by the node discovery mechanism.
+
+          <p><br /></p>
+
+          > **Note**: This field is only propagated when using standalone Swarm
+          > mode, and overlay networking using an external k/v store. Overlay
+          > networks with Swarm mode enabled use the built-in raft store, and
+          > this field will be empty.
+        type: "string"
+        example: "consul://consul.corp.example.com:8600/some/path"
+      ClusterAdvertise:
+        description: |
+          The network endpoint that the Engine advertises for the purpose of
+          node discovery. ClusterAdvertise is a `host:port` combination on which
+          the daemon is reachable by other hosts.
+
+          <p><br /></p>
+
+          > **Note**: This field is only propagated when using standalone Swarm
+          > mode, and overlay networking using an external k/v store. Overlay
+          > networks with Swarm mode enabled use the built-in raft store, and
+          > this field will be empty.
+        type: "string"
+        example: "node5.corp.example.com:8000"
+      Runtimes:
+        description: |
+          List of [OCI compliant](https://github.com/opencontainers/runtime-spec)
+          runtimes configured on the daemon. Keys hold the "name" used to
+          reference the runtime.
+
+          The Docker daemon relies on an OCI compliant runtime (invoked via the
+          `containerd` daemon) as its interface to the Linux kernel namespaces,
+          cgroups, and SELinux.
+
+          The default runtime is `runc`, and automatically configured. Additional
+          runtimes can be configured by the user and will be listed here.
+        type: "object"
+        additionalProperties:
+          $ref: "#/definitions/Runtime"
+        default:
+          runc:
+            path: "docker-runc"
+        example:
+          runc:
+            path: "docker-runc"
+          runc-master:
+            path: "/go/bin/runc"
+          custom:
+            path: "/usr/local/bin/my-oci-runtime"
+            runtimeArgs: ["--debug", "--systemd-cgroup=false"]
+      DefaultRuntime:
+        description: |
+          Name of the default OCI runtime that is used when starting containers.
+
+          The default can be overridden per-container at create time.
+        type: "string"
+        default: "runc"
+        example: "runc"
+      Swarm:
+        $ref: "#/definitions/SwarmInfo"
+      LiveRestoreEnabled:
+        description: |
+          Indicates if live restore is enabled.
+
+          If enabled, containers are kept running when the daemon is shutdown
+          or upon daemon start if running containers are detected.
+        type: "boolean"
+        default: false
+        example: false
+      Isolation:
+        description: |
+          Represents the isolation technology to use as a default for containers.
+          The supported values are platform-specific.
+
+          If no isolation value is specified on daemon start, on Windows client,
+          the default is `hyperv`, and on Windows server, the default is `process`.
+
+          This option is currently not used on other platforms.
+        default: "default"
+        type: "string"
+        enum:
+          - "default"
+          - "hyperv"
+          - "process"
+      InitBinary:
+        description: |
+          Name and, optional, path of the the `docker-init` binary.
+
+          If the path is omitted, the daemon searches the host's `$PATH` for the
+          binary and uses the first result.
+        type: "string"
+        example: "docker-init"
+      ContainerdCommit:
+        $ref: "#/definitions/Commit"
+      RuncCommit:
+        $ref: "#/definitions/Commit"
+      InitCommit:
+        $ref: "#/definitions/Commit"
+      SecurityOptions:
+        description: |
+          List of security features that are enabled on the daemon, such as
+          apparmor, seccomp, SELinux, and user-namespaces (userns).
+
+          Additional configuration options for each security feature may
+          be present, and are included as a comma-separated list of key/value
+          pairs.
+        type: "array"
+        items:
+          type: "string"
+        example:
+          - "name=apparmor"
+          - "name=seccomp,profile=default"
+          - "name=selinux"
+          - "name=userns"
+
+
+  # PluginsInfo is a temp struct holding Plugins name
+  # registered with docker daemon. It is used by Info struct
+  PluginsInfo:
+    description: |
+      Available plugins per type.
+
+      <p><br /></p>
+
+      > **Note**: Only unmanaged (V1) plugins are included in this list.
+      > V1 plugins are "lazily" loaded, and are not returned in this list
+      > if there is no resource using the plugin.
+    type: "object"
+    properties:
+      Volume:
+        description: "Names of available volume-drivers, and network-driver plugins."
+        type: "array"
+        items:
+          type: "string"
+        example: ["local"]
+      Network:
+        description: "Names of available network-drivers, and network-driver plugins."
+        type: "array"
+        items:
+          type: "string"
+        example: ["bridge", "host", "ipvlan", "macvlan", "null", "overlay"]
+      Authorization:
+        description: "Names of available authorization plugins."
+        type: "array"
+        items:
+          type: "string"
+        example: ["img-authz-plugin", "hbm"]
+      Log:
+        description: "Names of available logging-drivers, and logging-driver plugins."
+        type: "array"
+        items:
+          type: "string"
+        example: ["awslogs", "fluentd", "gcplogs", "gelf", "journald", "json-file", "logentries", "splunk", "syslog"]
+
+
+  RegistryServiceConfig:
+    description: |
+      RegistryServiceConfig stores daemon registry services configuration.
+    type: "object"
+    x-nullable: true
+    properties:
+      AllowNondistributableArtifactsCIDRs:
+        description: |
+          List of IP ranges to which nondistributable artifacts can be pushed,
+          using the CIDR syntax [RFC 4632](https://tools.ietf.org/html/4632).
+
+          Some images (for example, Windows base images) contain artifacts
+          whose distribution is restricted by license. When these images are
+          pushed to a registry, restricted artifacts are not included.
+
+          This configuration override this behavior, and enables the daemon to
+          push nondistributable artifacts to all registries whose resolved IP
+          address is within the subnet described by the CIDR syntax.
+
+          This option is useful when pushing images containing
+          nondistributable artifacts to a registry on an air-gapped network so
+          hosts on that network can pull the images without connecting to
+          another server.
+
+          > **Warning**: Nondistributable artifacts typically have restrictions
+          > on how and where they can be distributed and shared. Only use this
+          > feature to push artifacts to private registries and ensure that you
+          > are in compliance with any terms that cover redistributing
+          > nondistributable artifacts.
+
+        type: "array"
+        items:
+          type: "string"
+        example: ["::1/128", "127.0.0.0/8"]
+      AllowNondistributableArtifactsHostnames:
+        description: |
+          List of registry hostnames to which nondistributable artifacts can be
+          pushed, using the format `<hostname>[:<port>]` or `<IP address>[:<port>]`.
+
+          Some images (for example, Windows base images) contain artifacts
+          whose distribution is restricted by license. When these images are
+          pushed to a registry, restricted artifacts are not included.
+
+          This configuration override this behavior for the specified
+          registries.
+
+          This option is useful when pushing images containing
+          nondistributable artifacts to a registry on an air-gapped network so
+          hosts on that network can pull the images without connecting to
+          another server.
+
+          > **Warning**: Nondistributable artifacts typically have restrictions
+          > on how and where they can be distributed and shared. Only use this
+          > feature to push artifacts to private registries and ensure that you
+          > are in compliance with any terms that cover redistributing
+          > nondistributable artifacts.
+        type: "array"
+        items:
+          type: "string"
+        example: ["registry.internal.corp.example.com:3000", "[2001:db8:a0b:12f0::1]:443"]
+      InsecureRegistryCIDRs:
+        description: |
+          List of IP ranges of insecure registries, using the CIDR syntax
+          ([RFC 4632](https://tools.ietf.org/html/4632)). Insecure registries
+          accept un-encrypted (HTTP) and/or untrusted (HTTPS with certificates
+          from unknown CAs) communication.
+
+          By default, local registries (`127.0.0.0/8`) are configured as
+          insecure. All other registries are secure. Communicating with an
+          insecure registry is not possible if the daemon assumes that registry
+          is secure.
+
+          This configuration override this behavior, insecure communication with
+          registries whose resolved IP address is within the subnet described by
+          the CIDR syntax.
+
+          Registries can also be marked insecure by hostname. Those registries
+          are listed under `IndexConfigs` and have their `Secure` field set to
+          `false`.
+
+          > **Warning**: Using this option can be useful when running a local
+          > registry, but introduces security vulnerabilities. This option
+          > should therefore ONLY be used for testing purposes. For increased
+          > security, users should add their CA to their system's list of trusted
+          > CAs instead of enabling this option.
+        type: "array"
+        items:
+          type: "string"
+        example: ["::1/128", "127.0.0.0/8"]
+      IndexConfigs:
+        type: "object"
+        additionalProperties:
+          $ref: "#/definitions/IndexInfo"
+        example:
+          "127.0.0.1:5000":
+            "Name": "127.0.0.1:5000"
+            "Mirrors": []
+            "Secure": false
+            "Official": false
+          "[2001:db8:a0b:12f0::1]:80":
+            "Name": "[2001:db8:a0b:12f0::1]:80"
+            "Mirrors": []
+            "Secure": false
+            "Official": false
+          "docker.io":
+            Name: "docker.io"
+            Mirrors: ["https://hub-mirror.corp.example.com:5000/"]
+            Secure: true
+            Official: true
+          "registry.internal.corp.example.com:3000":
+            Name: "registry.internal.corp.example.com:3000"
+            Mirrors: []
+            Secure: false
+            Official: false
+      Mirrors:
+        description: |
+          List of registry URLs that act as a mirror for the official
+          (`docker.io`) registry.
+
+        type: "array"
+        items:
+          type: "string"
+        example:
+          - "https://hub-mirror.corp.example.com:5000/"
+          - "https://[2001:db8:a0b:12f0::1]/"
+
+  IndexInfo:
+    description:
+      IndexInfo contains information about a registry.
+    type: "object"
+    x-nullable: true
+    properties:
+      Name:
+        description: |
+          Name of the registry, such as "docker.io".
+        type: "string"
+        example: "docker.io"
+      Mirrors:
+        description: |
+          List of mirrors, expressed as URIs.
+        type: "array"
+        items:
+          type: "string"
+        example:
+          - "https://hub-mirror.corp.example.com:5000/"
+          - "https://registry-2.docker.io/"
+          - "https://registry-3.docker.io/"
+      Secure:
+        description: |
+          Indicates if the the registry is part of the list of insecure
+          registries.
+
+          If `false`, the registry is insecure. Insecure registries accept
+          un-encrypted (HTTP) and/or untrusted (HTTPS with certificates from
+          unknown CAs) communication.
+
+          > **Warning**: Insecure registries can be useful when running a local
+          > registry. However, because its use creates security vulnerabilities
+          > it should ONLY be enabled for testing purposes. For increased
+          > security, users should add their CA to their system's list of
+          > trusted CAs instead of enabling this option.
+        type: "boolean"
+        example: true
+      Official:
+        description: |
+          Indicates whether this is an official registry (i.e., Docker Hub / docker.io)
+        type: "boolean"
+        example: true
+
+  Runtime:
+    description: |
+      Runtime describes an [OCI compliant](https://github.com/opencontainers/runtime-spec)
+      runtime.
+
+      The runtime is invoked by the daemon via the `containerd` daemon. OCI
+      runtimes act as an interface to the Linux kernel namespaces, cgroups,
+      and SELinux.
+    type: "object"
+    properties:
+      path:
+        description: |
+          Name and, optional, path, of the OCI executable binary.
+
+          If the path is omitted, the daemon searches the host's `$PATH` for the
+          binary and uses the first result.
+        type: "string"
+        example: "/usr/local/bin/my-oci-runtime"
+      runtimeArgs:
+        description: |
+          List of command-line arguments to pass to the runtime when invoked.
+        type: "array"
+        x-nullable: true
+        items:
+          type: "string"
+        example: ["--debug", "--systemd-cgroup=false"]
+
+  Commit:
+    description: |
+      Commit holds the Git-commit (SHA1) that a binary was built from, as
+      reported in the version-string of external tools, such as `containerd`,
+      or `runC`.
+    type: "object"
+    properties:
+      ID:
+        description: "Actual commit ID of external tool."
+        type: "string"
+        example: "cfb82a876ecc11b5ca0977d1733adbe58599088a"
+      Expected:
+        description: |
+          Commit ID of external tool expected by dockerd as set at build time.
+        type: "string"
+        example: "2d41c047c83e09a6d61d464906feb2a2f3c52aa4"
+
+  SwarmInfo:
+    description: |
+      Represents generic information about swarm.
+    type: "object"
+    properties:
+      NodeID:
+        description: "Unique identifier of for this node in the swarm."
+        type: "string"
+        default: ""
+        example: "k67qz4598weg5unwwffg6z1m1"
+      NodeAddr:
+        description: |
+          IP address at which this node can be reached by other nodes in the
+          swarm.
+        type: "string"
+        default: ""
+        example: "10.0.0.46"
+      LocalNodeState:
+        $ref: "#/definitions/LocalNodeState"
+      ControlAvailable:
+        type: "boolean"
+        default: false
+        example: true
+      Error:
+        type: "string"
+        default: ""
+      RemoteManagers:
+        description: |
+          List of ID's and addresses of other managers in the swarm.
+        type: "array"
+        default: null
+        x-nullable: true
+        items:
+          $ref: "#/definitions/PeerNode"
+        example:
+          - NodeID: "71izy0goik036k48jg985xnds"
+            Addr: "10.0.0.158:2377"
+          - NodeID: "79y6h1o4gv8n120drcprv5nmc"
+            Addr: "10.0.0.159:2377"
+          - NodeID: "k67qz4598weg5unwwffg6z1m1"
+            Addr: "10.0.0.46:2377"
+      Nodes:
+        description: "Total number of nodes in the swarm."
+        type: "integer"
+        x-nullable: true
+        example: 4
+      Managers:
+        description: "Total number of managers in the swarm."
+        type: "integer"
+        x-nullable: true
+        example: 3
+      Cluster:
+        $ref: "#/definitions/ClusterInfo"
+
+  LocalNodeState:
+    description: "Current local status of this node."
+    type: "string"
+    default: ""
+    enum:
+      - ""
+      - "inactive"
+      - "pending"
+      - "active"
+      - "error"
+      - "locked"
+    example: "active"
+
+  PeerNode:
+    description: "Represents a peer-node in the swarm"
+    properties:
+      NodeID:
+        description: "Unique identifier of for this node in the swarm."
+        type: "string"
+      Addr:
+        description: |
+          IP address and ports at which this node can be reached.
+        type: "string"
+
 paths:
   /containers/json:
     get:
@@ -3260,10 +4506,6 @@
           examples:
             application/json:
               message: "No such container: c2ada9df5af8"
-        406:
-          description: "impossible to attach"
-          schema:
-            $ref: "#/definitions/ErrorResponse"
         409:
           description: "conflict"
           schema:
@@ -3394,7 +4636,7 @@
               Config:
                 $ref: "#/definitions/ContainerConfig"
               NetworkSettings:
-                $ref: "#/definitions/NetworkConfig"
+                $ref: "#/definitions/NetworkSettings"
           examples:
             application/json:
               AppArmorProfile: ""
@@ -3493,8 +4735,6 @@
                 LinkLocalIPv6Address: ""
                 LinkLocalIPv6PrefixLen: 0
                 SandboxKey: ""
-                SecondaryIPAddresses: null
-                SecondaryIPv6Addresses: null
                 EndpointID: ""
                 Gateway: ""
                 GlobalIPv6Address: ""
@@ -5471,209 +6711,7 @@
         200:
           description: "No error"
           schema:
-            type: "object"
-            properties:
-              Architecture:
-                type: "string"
-              Containers:
-                type: "integer"
-              ContainersRunning:
-                type: "integer"
-              ContainersStopped:
-                type: "integer"
-              ContainersPaused:
-                type: "integer"
-              CpuCfsPeriod:
-                type: "boolean"
-              CpuCfsQuota:
-                type: "boolean"
-              Debug:
-                type: "boolean"
-              DiscoveryBackend:
-                type: "string"
-              DockerRootDir:
-                type: "string"
-              Driver:
-                type: "string"
-              DriverStatus:
-                type: "array"
-                items:
-                  type: "array"
-                  items:
-                    type: "string"
-              SystemStatus:
-                type: "array"
-                items:
-                  type: "array"
-                  items:
-                    type: "string"
-              Plugins:
-                type: "object"
-                properties:
-                  Volume:
-                    type: "array"
-                    items:
-                      type: "string"
-                  Network:
-                    type: "array"
-                    items:
-                      type: "string"
-                  Log:
-                    type: "array"
-                    items:
-                      type: "string"
-              ExperimentalBuild:
-                type: "boolean"
-              HttpProxy:
-                type: "string"
-              HttpsProxy:
-                type: "string"
-              ID:
-                type: "string"
-              IPv4Forwarding:
-                type: "boolean"
-              Images:
-                type: "integer"
-              IndexServerAddress:
-                type: "string"
-              InitPath:
-                type: "string"
-              InitSha1:
-                type: "string"
-              KernelVersion:
-                type: "string"
-              Labels:
-                type: "array"
-                items:
-                  type: "string"
-              MemTotal:
-                type: "integer"
-              GenericResources:
-                $ref: "#/definitions/GenericResources"
-              MemoryLimit:
-                type: "boolean"
-              NCPU:
-                type: "integer"
-              NEventsListener:
-                type: "integer"
-              NFd:
-                type: "integer"
-              NGoroutines:
-                type: "integer"
-              Name:
-                type: "string"
-              NoProxy:
-                type: "string"
-              OomKillDisable:
-                type: "boolean"
-              OSType:
-                type: "string"
-              OomScoreAdj:
-                type: "integer"
-              OperatingSystem:
-                type: "string"
-              RegistryConfig:
-                type: "object"
-                properties:
-                  IndexConfigs:
-                    type: "object"
-                    additionalProperties:
-                      type: "object"
-                      properties:
-                        Mirrors:
-                          type: "array"
-                          items:
-                            type: "string"
-                        Name:
-                          type: "string"
-                        Official:
-                          type: "boolean"
-                        Secure:
-                          type: "boolean"
-                  InsecureRegistryCIDRs:
-                    type: "array"
-                    items:
-                      type: "string"
-              SwapLimit:
-                type: "boolean"
-              SystemTime:
-                type: "string"
-              ServerVersion:
-                type: "string"
-          examples:
-            application/json:
-              Architecture: "x86_64"
-              ClusterStore: "etcd://localhost:2379"
-              CgroupDriver: "cgroupfs"
-              Containers: 11
-              ContainersRunning: 7
-              ContainersStopped: 3
-              ContainersPaused: 1
-              CpuCfsPeriod: true
-              CpuCfsQuota: true
-              Debug: false
-              DockerRootDir: "/var/lib/docker"
-              Driver: "btrfs"
-              DriverStatus:
-                -
-                  - ""
-              ExperimentalBuild: false
-              HttpProxy: "http://test:test@localhost:8080"
-              HttpsProxy: "https://test:test@localhost:8080"
-              ID: "7TRN:IPZB:QYBB:VPBQ:UMPP:KARE:6ZNR:XE6T:7EWV:PKF4:ZOJD:TPYS"
-              IPv4Forwarding: true
-              Images: 16
-              IndexServerAddress: "https://index.docker.io/v1/"
-              InitPath: "/usr/bin/docker"
-              InitSha1: ""
-              KernelMemory: true
-              KernelVersion: "3.12.0-1-amd64"
-              Labels:
-                - "storage=ssd"
-              MemTotal: 2099236864
-              MemoryLimit: true
-              NCPU: 1
-              NEventsListener: 0
-              NFd: 11
-              NGoroutines: 21
-              Name: "prod-server-42"
-              NoProxy: "9.81.1.160"
-              OomKillDisable: true
-              OSType: "linux"
-              OperatingSystem: "Boot2Docker"
-              Plugins:
-                Volume:
-                  - "local"
-                Network:
-                  - "null"
-                  - "host"
-                  - "bridge"
-              RegistryConfig:
-                IndexConfigs:
-                  docker.io:
-                    Name: "docker.io"
-                    Official: true
-                    Secure: true
-                InsecureRegistryCIDRs:
-                  - "127.0.0.0/8"
-              SecurityOptions:
-                - Key: "Name"
-                  Value: "seccomp"
-                - Key: "Profile"
-                  Value: "default"
-                - Key: "Name"
-                  Value: "apparmor"
-                - Key: "Name"
-                  Value: "selinux"
-                - Key: "Name"
-                  Value: "userns"
-              ServerVersion: "1.9.0"
-              SwapLimit: false
-              SystemStatus:
-                -
-                  - "State"
-                  - "Healthy"
-              SystemTime: "2015-03-10T11:11:23.730591467-07:00"
+            $ref: "#/definitions/SystemInfo"
         500:
           description: "Server error"
           schema:
@@ -5904,16 +6942,20 @@
           description: |
             A JSON encoded value of filters (a `map[string][]string`) to process on the event list. Available filters:
 
+            - `config=<string>` config name or ID
             - `container=<string>` container name or ID
             - `daemon=<string>` daemon name or ID
             - `event=<string>` event type
             - `image=<string>` image name or ID
             - `label=<string>` image or container label
             - `network=<string>` network name or ID
+            - `node=<string>` node ID
             - `plugin`=<string> plugin name or ID
             - `scope`=<string> local or swarm
-            - `type=<string>` object to filter by, one of `container`, `image`, `volume`, `network`, `daemon`, `plugin`, `node`, `service` or `secret`
-            - `volume=<string>` volume name or ID
+            - `secret=<string>` secret name or ID
+            - `service=<string>` service name or ID
+            - `type=<string>` object to filter by, one of `container`, `image`, `volume`, `network`, `daemon`, `plugin`, `node`, `service`, `secret` or `config`
+            - `volume=<string>` volume name
           type: "string"
       tags: ["System"]
   /system/df:
@@ -6931,46 +7973,6 @@
             type: "array"
             items:
               $ref: "#/definitions/Plugin"
-            example:
-              - Id: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078"
-                Name: "tiborvass/sample-volume-plugin"
-                Tag: "latest"
-                Active: true
-                Settings:
-                  Env:
-                    - "DEBUG=0"
-                  Args: null
-                  Devices: null
-                Config:
-                  Description: "A sample volume plugin for Docker"
-                  Documentation: "https://docs.docker.com/engine/extend/plugins/"
-                  Interface:
-                    Types:
-                      - "docker.volumedriver/1.0"
-                    Socket: "plugins.sock"
-                  Entrypoint:
-                    - "/usr/bin/sample-volume-plugin"
-                    - "/data"
-                  WorkDir: ""
-                  User: {}
-                  Network:
-                    Type: ""
-                  Linux:
-                    Capabilities: null
-                    AllowAllDevices: false
-                    Devices: null
-                  Mounts: null
-                  PropagatedMount: "/data"
-                  Env:
-                    - Name: "DEBUG"
-                      Description: "If set, prints debug messages"
-                      Settable: null
-                      Value: "0"
-                  Args:
-                    Name: "args"
-                    Description: "command line arguments"
-                    Settable: null
-                    Value: []
         500:
           description: "Server error"
           schema:
@@ -7484,60 +8486,7 @@
         200:
           description: "no error"
           schema:
-            allOf:
-              - $ref: "#/definitions/ClusterInfo"
-              - type: "object"
-                properties:
-                  JoinTokens:
-                    description: "The tokens workers and managers need to join the swarm."
-                    type: "object"
-                    properties:
-                      Worker:
-                        description: "The token workers can use to join the swarm."
-                        type: "string"
-                      Manager:
-                        description: "The token managers can use to join the swarm."
-                        type: "string"
-            example:
-              CreatedAt: "2016-08-15T16:00:20.349727406Z"
-              Spec:
-                Dispatcher:
-                  HeartbeatPeriod: 5000000000
-                Orchestration:
-                  TaskHistoryRetentionLimit: 10
-                CAConfig:
-                  NodeCertExpiry: 7776000000000000
-                Raft:
-                  LogEntriesForSlowFollowers: 500
-                  HeartbeatTick: 1
-                  SnapshotInterval: 10000
-                  ElectionTick: 3
-                TaskDefaults: {}
-                EncryptionConfig:
-                  AutoLockManagers: false
-                Name: "default"
-              JoinTokens:
-                Worker: "SWMTKN-1-1h8aps2yszaiqmz2l3oc5392pgk8e49qhx2aj3nyv0ui0hez2a-6qmn92w6bu3jdvnglku58u11a"
-                Manager: "SWMTKN-1-1h8aps2yszaiqmz2l3oc5392pgk8e49qhx2aj3nyv0ui0hez2a-8llk83c4wm9lwioey2s316r9l"
-              ID: "70ilmkj2f6sp2137c753w2nmt"
-              UpdatedAt: "2016-08-15T16:32:09.623207604Z"
-              Version:
-                Index: 51
-              RootRotationInProgress: false
-              TLSInfo:
-                TrustRoot: |
-                  -----BEGIN CERTIFICATE-----
-                  MIIBajCCARCgAwIBAgIUbYqrLSOSQHoxD8CwG6Bi2PJi9c8wCgYIKoZIzj0EAwIw
-                  EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwNDI0MjE0MzAwWhcNMzcwNDE5MjE0
-                  MzAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH
-                  A0IABJk/VyMPYdaqDXJb/VXh5n/1Yuv7iNrxV3Qb3l06XD46seovcDWs3IZNV1lf
-                  3Skyr0ofcchipoiHkXBODojJydSjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
-                  Af8EBTADAQH/MB0GA1UdDgQWBBRUXxuRcnFjDfR/RIAUQab8ZV/n4jAKBggqhkjO
-                  PQQDAgNIADBFAiAy+JTe6Uc3KyLCMiqGl2GyWGQqQDEcO3/YG36x7om65AIhAJvz
-                  pxv6zFeVEkAEEkqIYi0omA9+CjanB/6Bz4n1uw8H
-                  -----END CERTIFICATE-----
-                CertIssuerSubject: "MBMxETAPBgNVBAMTCHN3YXJtLWNh"
-                CertIssuerPublicKey: "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmT9XIw9h1qoNclv9VeHmf/Vi6/uI2vFXdBveXTpcPjqx6i9wNazchk1XWV/dKTKvSh9xyGKmiIeRcE4OiMnJ1A=="
+            $ref: "#/definitions/Swarm"
         404:
           description: "no such swarm"
           schema:
@@ -8460,6 +9409,20 @@
             items:
               $ref: "#/definitions/Secret"
             example:
+              - ID: "blt1owaxmitz71s9v5zh81zun"
+                Version:
+                  Index: 85
+                CreatedAt: "2017-07-20T13:55:28.678958722Z"
+                UpdatedAt: "2017-07-20T13:55:28.678958722Z"
+                Spec:
+                  Name: "mysql-passwd"
+                  Labels:
+                    some.label: "some.value"
+                  Driver:
+                    Name: "secret-bucket"
+                    Options:
+                      OptionA: "value for driver option A"
+                      OptionB: "value for driver option B"
               - ID: "ktnbjxoalbkvbvedmg1urrz8h"
                 Version:
                   Index: 11
@@ -8467,6 +9430,8 @@
                 UpdatedAt: "2016-11-05T01:20:17.327670065Z"
                 Spec:
                   Name: "app-dev.crt"
+                  Labels:
+                    foo: "bar"
         500:
           description: "server error"
           schema:
@@ -8530,6 +9495,11 @@
                   Labels:
                     foo: "bar"
                   Data: "VEhJUyBJUyBOT1QgQSBSRUFMIENFUlRJRklDQVRFCg=="
+                  Driver:
+                    Name: "secret-bucket"
+                    Options:
+                      OptionA: "value for driver option A"
+                      OptionB: "value for driver option B"
       tags: ["Secret"]
   /secrets/{id}:
     get:
@@ -8551,6 +9521,14 @@
               UpdatedAt: "2016-11-05T01:20:17.327670065Z"
               Spec:
                 Name: "app-dev.crt"
+                Labels:
+                  foo: "bar"
+                Driver:
+                  Name: "secret-bucket"
+                  Options:
+                    OptionA: "value for driver option A"
+                    OptionB: "value for driver option B"
+
         404:
           description: "secret not found"
           schema:
diff --git a/api/types/client.go b/api/types/client.go
index 18a1263..4ca9cca 100644
--- a/api/types/client.go
+++ b/api/types/client.go
@@ -181,7 +181,7 @@
 	SessionID   string
 
 	// TODO @jhowardmsft LCOW Support: This will require extending to include
-	// `Platform string`, but is ommited for now as it's hard-coded temporarily
+	// `Platform string`, but is omitted for now as it's hard-coded temporarily
 	// to avoid API changes.
 }
 
diff --git a/api/types/container/host_config.go b/api/types/container/host_config.go
index 9fea9eb..bb421b3 100644
--- a/api/types/container/host_config.go
+++ b/api/types/container/host_config.go
@@ -23,41 +23,46 @@
 // IpcMode represents the container ipc stack.
 type IpcMode string
 
-// IsPrivate indicates whether the container uses its private ipc stack.
+// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared.
 func (n IpcMode) IsPrivate() bool {
-	return !(n.IsHost() || n.IsContainer())
+	return n == "private"
 }
 
-// IsHost indicates whether the container uses the host's ipc stack.
+// IsHost indicates whether the container shares the host's ipc namespace.
 func (n IpcMode) IsHost() bool {
 	return n == "host"
 }
 
-// IsContainer indicates whether the container uses a container's ipc stack.
+// IsShareable indicates whether the container's ipc namespace can be shared with another container.
+func (n IpcMode) IsShareable() bool {
+	return n == "shareable"
+}
+
+// IsContainer indicates whether the container uses another container's ipc namespace.
 func (n IpcMode) IsContainer() bool {
 	parts := strings.SplitN(string(n), ":", 2)
 	return len(parts) > 1 && parts[0] == "container"
 }
 
-// Valid indicates whether the ipc stack is valid.
+// IsNone indicates whether container IpcMode is set to "none".
+func (n IpcMode) IsNone() bool {
+	return n == "none"
+}
+
+// IsEmpty indicates whether container IpcMode is empty
+func (n IpcMode) IsEmpty() bool {
+	return n == ""
+}
+
+// Valid indicates whether the ipc mode is valid.
 func (n IpcMode) Valid() bool {
-	parts := strings.Split(string(n), ":")
-	switch mode := parts[0]; mode {
-	case "", "host":
-	case "container":
-		if len(parts) != 2 || parts[1] == "" {
-			return false
-		}
-	default:
-		return false
-	}
-	return true
+	return n.IsEmpty() || n.IsNone() || n.IsPrivate() || n.IsHost() || n.IsShareable() || n.IsContainer()
 }
 
 // Container returns the name of the container ipc stack is going to be used.
 func (n IpcMode) Container() string {
 	parts := strings.SplitN(string(n), ":", 2)
-	if len(parts) > 1 {
+	if len(parts) > 1 && parts[0] == "container" {
 		return parts[1]
 	}
 	return ""
diff --git a/api/types/filters/example_test.go b/api/types/filters/example_test.go
new file mode 100644
index 0000000..6529be3
--- /dev/null
+++ b/api/types/filters/example_test.go
@@ -0,0 +1,24 @@
+package filters
+
+func ExampleArgs_MatchKVList() {
+	args := NewArgs(
+		Arg("label", "image=foo"),
+		Arg("label", "state=running"))
+
+	// returns true because there are no values for bogus
+	args.MatchKVList("bogus", nil)
+
+	// returns false because there are no sources
+	args.MatchKVList("label", nil)
+
+	// returns true because all sources are matched
+	args.MatchKVList("label", map[string]string{
+		"image": "foo",
+		"state": "running",
+	})
+
+	// returns false because the values do not match
+	args.MatchKVList("label", map[string]string{
+		"image": "other",
+	})
+}
diff --git a/api/types/filters/parse.go b/api/types/filters/parse.go
index beec3d4..d45d052 100644
--- a/api/types/filters/parse.go
+++ b/api/types/filters/parse.go
@@ -1,38 +1,45 @@
-// Package filters provides helper function to parse and handle command line
-// filter, used for example in docker ps or docker images commands.
+/*Package filters provides tools for encoding a mapping of keys to a set of
+multiple values.
+*/
 package filters
 
 import (
 	"encoding/json"
 	"errors"
-	"fmt"
 	"regexp"
 	"strings"
 
 	"github.com/docker/docker/api/types/versions"
 )
 
-// Args stores filter arguments as map key:{map key: bool}.
-// It contains an aggregation of the map of arguments (which are in the form
-// of -f 'key=value') based on the key, and stores values for the same key
-// in a map with string keys and boolean values.
-// e.g given -f 'label=label1=1' -f 'label=label2=2' -f 'image.name=ubuntu'
-// the args will be {"image.name":{"ubuntu":true},"label":{"label1=1":true,"label2=2":true}}
+// Args stores a mapping of keys to a set of multiple values.
 type Args struct {
 	fields map[string]map[string]bool
 }
 
-// NewArgs initializes a new Args struct.
-func NewArgs() Args {
-	return Args{fields: map[string]map[string]bool{}}
+// KeyValuePair are used to initialize a new Args
+type KeyValuePair struct {
+	Key   string
+	Value string
 }
 
-// ParseFlag parses the argument to the filter flag. Like
+// Arg creates a new KeyValuePair for initializing Args
+func Arg(key, value string) KeyValuePair {
+	return KeyValuePair{Key: key, Value: value}
+}
+
+// NewArgs returns a new Args populated with the initial args
+func NewArgs(initialArgs ...KeyValuePair) Args {
+	args := Args{fields: map[string]map[string]bool{}}
+	for _, arg := range initialArgs {
+		args.Add(arg.Key, arg.Value)
+	}
+	return args
+}
+
+// ParseFlag parses a key=value string and adds it to an Args.
 //
-//   `docker ps -f 'created=today' -f 'image.name=ubuntu*'`
-//
-// If prev map is provided, then it is appended to, and returned. By default a new
-// map is created.
+// Deprecated: Use Args.Add()
 func ParseFlag(arg string, prev Args) (Args, error) {
 	filters := prev
 	if len(arg) == 0 {
@@ -53,74 +60,95 @@
 	return filters, nil
 }
 
-// ErrBadFormat is an error returned in case of bad format for a filter.
+// ErrBadFormat is an error returned when a filter is not in the form key=value
+//
+// Deprecated: this error will be removed in a future version
 var ErrBadFormat = errors.New("bad format of filter (expected name=value)")
 
-// ToParam packs the Args into a string for easy transport from client to server.
+// ToParam encodes the Args as args JSON encoded string
+//
+// Deprecated: use ToJSON
 func ToParam(a Args) (string, error) {
-	// this way we don't URL encode {}, just empty space
+	return ToJSON(a)
+}
+
+// MarshalJSON returns a JSON byte representation of the Args
+func (args Args) MarshalJSON() ([]byte, error) {
+	if len(args.fields) == 0 {
+		return []byte{}, nil
+	}
+	return json.Marshal(args.fields)
+}
+
+// ToJSON returns the Args as a JSON encoded string
+func ToJSON(a Args) (string, error) {
 	if a.Len() == 0 {
 		return "", nil
 	}
-
-	buf, err := json.Marshal(a.fields)
-	if err != nil {
-		return "", err
-	}
-	return string(buf), nil
+	buf, err := json.Marshal(a)
+	return string(buf), err
 }
 
-// ToParamWithVersion packs the Args into a string for easy transport from client to server.
-// The generated string will depend on the specified version (corresponding to the API version).
+// ToParamWithVersion encodes Args as a JSON string. If version is less than 1.22
+// then the encoded format will use an older legacy format where the values are a
+// list of strings, instead of a set.
+//
+// Deprecated: Use ToJSON
 func ToParamWithVersion(version string, a Args) (string, error) {
-	// this way we don't URL encode {}, just empty space
 	if a.Len() == 0 {
 		return "", nil
 	}
 
-	// for daemons older than v1.10, filter must be of the form map[string][]string
-	var buf []byte
-	var err error
 	if version != "" && versions.LessThan(version, "1.22") {
-		buf, err = json.Marshal(convertArgsToSlice(a.fields))
-	} else {
-		buf, err = json.Marshal(a.fields)
+		buf, err := json.Marshal(convertArgsToSlice(a.fields))
+		return string(buf), err
 	}
-	if err != nil {
-		return "", err
-	}
-	return string(buf), nil
+
+	return ToJSON(a)
 }
 
-// FromParam unpacks the filter Args.
+// FromParam decodes a JSON encoded string into Args
+//
+// Deprecated: use FromJSON
 func FromParam(p string) (Args, error) {
-	if len(p) == 0 {
-		return NewArgs(), nil
-	}
-
-	r := strings.NewReader(p)
-	d := json.NewDecoder(r)
-
-	m := map[string]map[string]bool{}
-	if err := d.Decode(&m); err != nil {
-		r.Seek(0, 0)
-
-		// Allow parsing old arguments in slice format.
-		// Because other libraries might be sending them in this format.
-		deprecated := map[string][]string{}
-		if deprecatedErr := d.Decode(&deprecated); deprecatedErr == nil {
-			m = deprecatedArgs(deprecated)
-		} else {
-			return NewArgs(), err
-		}
-	}
-	return Args{m}, nil
+	return FromJSON(p)
 }
 
-// Get returns the list of values associates with a field.
-// It returns a slice of strings to keep backwards compatibility with old code.
-func (filters Args) Get(field string) []string {
-	values := filters.fields[field]
+// FromJSON decodes a JSON encoded string into Args
+func FromJSON(p string) (Args, error) {
+	args := NewArgs()
+
+	if p == "" {
+		return args, nil
+	}
+
+	raw := []byte(p)
+	err := json.Unmarshal(raw, &args)
+	if err == nil {
+		return args, nil
+	}
+
+	// Fallback to parsing arguments in the legacy slice format
+	deprecated := map[string][]string{}
+	if legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil {
+		return args, err
+	}
+
+	args.fields = deprecatedArgs(deprecated)
+	return args, nil
+}
+
+// UnmarshalJSON populates the Args from JSON encode bytes
+func (args Args) UnmarshalJSON(raw []byte) error {
+	if len(raw) == 0 {
+		return nil
+	}
+	return json.Unmarshal(raw, &args.fields)
+}
+
+// Get returns the list of values associated with the key
+func (args Args) Get(key string) []string {
+	values := args.fields[key]
 	if values == nil {
 		return make([]string, 0)
 	}
@@ -131,37 +159,34 @@
 	return slice
 }
 
-// Add adds a new value to a filter field.
-func (filters Args) Add(name, value string) {
-	if _, ok := filters.fields[name]; ok {
-		filters.fields[name][value] = true
+// Add a new value to the set of values
+func (args Args) Add(key, value string) {
+	if _, ok := args.fields[key]; ok {
+		args.fields[key][value] = true
 	} else {
-		filters.fields[name] = map[string]bool{value: true}
+		args.fields[key] = map[string]bool{value: true}
 	}
 }
 
-// Del removes a value from a filter field.
-func (filters Args) Del(name, value string) {
-	if _, ok := filters.fields[name]; ok {
-		delete(filters.fields[name], value)
-		if len(filters.fields[name]) == 0 {
-			delete(filters.fields, name)
+// Del removes a value from the set
+func (args Args) Del(key, value string) {
+	if _, ok := args.fields[key]; ok {
+		delete(args.fields[key], value)
+		if len(args.fields[key]) == 0 {
+			delete(args.fields, key)
 		}
 	}
 }
 
-// Len returns the number of fields in the arguments.
-func (filters Args) Len() int {
-	return len(filters.fields)
+// Len returns the number of keys in the mapping
+func (args Args) Len() int {
+	return len(args.fields)
 }
 
-// MatchKVList returns true if the values for the specified field matches the ones
-// from the sources.
-// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
-//      field is 'label' and sources are {'label1': '1', 'label2': '2'}
-//      it returns true.
-func (filters Args) MatchKVList(field string, sources map[string]string) bool {
-	fieldValues := filters.fields[field]
+// MatchKVList returns true if all the pairs in sources exist as key=value
+// pairs in the mapping at key, or if there are no values at key.
+func (args Args) MatchKVList(key string, sources map[string]string) bool {
+	fieldValues := args.fields[key]
 
 	//do not filter if there is no filter set or cannot determine filter
 	if len(fieldValues) == 0 {
@@ -172,8 +197,8 @@
 		return false
 	}
 
-	for name2match := range fieldValues {
-		testKV := strings.SplitN(name2match, "=", 2)
+	for value := range fieldValues {
+		testKV := strings.SplitN(value, "=", 2)
 
 		v, ok := sources[testKV[0]]
 		if !ok {
@@ -187,16 +212,13 @@
 	return true
 }
 
-// Match returns true if the values for the specified field matches the source string
-// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
-//      field is 'image.name' and source is 'ubuntu'
-//      it returns true.
-func (filters Args) Match(field, source string) bool {
-	if filters.ExactMatch(field, source) {
+// Match returns true if any of the values at key match the source string
+func (args Args) Match(field, source string) bool {
+	if args.ExactMatch(field, source) {
 		return true
 	}
 
-	fieldValues := filters.fields[field]
+	fieldValues := args.fields[field]
 	for name2match := range fieldValues {
 		match, err := regexp.MatchString(name2match, source)
 		if err != nil {
@@ -209,9 +231,9 @@
 	return false
 }
 
-// ExactMatch returns true if the source matches exactly one of the filters.
-func (filters Args) ExactMatch(field, source string) bool {
-	fieldValues, ok := filters.fields[field]
+// ExactMatch returns true if the source matches exactly one of the values.
+func (args Args) ExactMatch(key, source string) bool {
+	fieldValues, ok := args.fields[key]
 	//do not filter if there is no filter set or cannot determine filter
 	if !ok || len(fieldValues) == 0 {
 		return true
@@ -221,14 +243,15 @@
 	return fieldValues[source]
 }
 
-// UniqueExactMatch returns true if there is only one filter and the source matches exactly this one.
-func (filters Args) UniqueExactMatch(field, source string) bool {
-	fieldValues := filters.fields[field]
+// UniqueExactMatch returns true if there is only one value and the source
+// matches exactly the value.
+func (args Args) UniqueExactMatch(key, source string) bool {
+	fieldValues := args.fields[key]
 	//do not filter if there is no filter set or cannot determine filter
 	if len(fieldValues) == 0 {
 		return true
 	}
-	if len(filters.fields[field]) != 1 {
+	if len(args.fields[key]) != 1 {
 		return false
 	}
 
@@ -236,14 +259,14 @@
 	return fieldValues[source]
 }
 
-// FuzzyMatch returns true if the source matches exactly one of the filters,
-// or the source has one of the filters as a prefix.
-func (filters Args) FuzzyMatch(field, source string) bool {
-	if filters.ExactMatch(field, source) {
+// FuzzyMatch returns true if the source matches exactly one value,  or the
+// source has one of the values as a prefix.
+func (args Args) FuzzyMatch(key, source string) bool {
+	if args.ExactMatch(key, source) {
 		return true
 	}
 
-	fieldValues := filters.fields[field]
+	fieldValues := args.fields[key]
 	for prefix := range fieldValues {
 		if strings.HasPrefix(source, prefix) {
 			return true
@@ -252,30 +275,47 @@
 	return false
 }
 
-// Include returns true if the name of the field to filter is in the filters.
-func (filters Args) Include(field string) bool {
-	_, ok := filters.fields[field]
+// Include returns true if the key exists in the mapping
+//
+// Deprecated: use Contains
+func (args Args) Include(field string) bool {
+	_, ok := args.fields[field]
 	return ok
 }
 
-// Validate ensures that all the fields in the filter are valid.
-// It returns an error as soon as it finds an invalid field.
-func (filters Args) Validate(accepted map[string]bool) error {
-	for name := range filters.fields {
+// Contains returns true if the key exists in the mapping
+func (args Args) Contains(field string) bool {
+	_, ok := args.fields[field]
+	return ok
+}
+
+type invalidFilter string
+
+func (e invalidFilter) Error() string {
+	return "Invalid filter '" + string(e) + "'"
+}
+
+func (invalidFilter) InvalidParameter() {}
+
+// Validate compared the set of accepted keys against the keys in the mapping.
+// An error is returned if any mapping keys are not in the accepted set.
+func (args Args) Validate(accepted map[string]bool) error {
+	for name := range args.fields {
 		if !accepted[name] {
-			return fmt.Errorf("Invalid filter '%s'", name)
+			return invalidFilter(name)
 		}
 	}
 	return nil
 }
 
-// WalkValues iterates over the list of filtered values for a field.
-// It stops the iteration if it finds an error and it returns that error.
-func (filters Args) WalkValues(field string, op func(value string) error) error {
-	if _, ok := filters.fields[field]; !ok {
+// WalkValues iterates over the list of values for a key in the mapping and calls
+// op() for each value. If op returns an error the iteration stops and the
+// error is returned.
+func (args Args) WalkValues(field string, op func(value string) error) error {
+	if _, ok := args.fields[field]; !ok {
 		return nil
 	}
-	for v := range filters.fields[field] {
+	for v := range args.fields[field] {
 		if err := op(v); err != nil {
 			return err
 		}
diff --git a/api/types/filters/parse_test.go b/api/types/filters/parse_test.go
index ccd1684..67b2ec9 100644
--- a/api/types/filters/parse_test.go
+++ b/api/types/filters/parse_test.go
@@ -3,6 +3,9 @@
 import (
 	"errors"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestParseArgs(t *testing.T) {
@@ -16,23 +19,18 @@
 		args = NewArgs()
 		err  error
 	)
+
 	for i := range flagArgs {
 		args, err = ParseFlag(flagArgs[i], args)
-		if err != nil {
-			t.Errorf("failed to parse %s: %s", flagArgs[i], err)
-		}
+		require.NoError(t, err)
 	}
-	if len(args.Get("created")) != 1 {
-		t.Error("failed to set this arg")
-	}
-	if len(args.Get("image.name")) != 2 {
-		t.Error("the args should have collapsed")
-	}
+	assert.Len(t, args.Get("created"), 1)
+	assert.Len(t, args.Get("image.name"), 2)
 }
 
 func TestParseArgsEdgeCase(t *testing.T) {
-	var filters Args
-	args, err := ParseFlag("", filters)
+	var args Args
+	args, err := ParseFlag("", args)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -44,14 +42,14 @@
 	}
 }
 
-func TestToParam(t *testing.T) {
+func TestToJSON(t *testing.T) {
 	fields := map[string]map[string]bool{
 		"created":    {"today": true},
 		"image.name": {"ubuntu*": true, "*untu": true},
 	}
 	a := Args{fields: fields}
 
-	_, err := ToParam(a)
+	_, err := ToJSON(a)
 	if err != nil {
 		t.Errorf("failed to marshal the filters: %s", err)
 	}
@@ -82,7 +80,7 @@
 	}
 }
 
-func TestFromParam(t *testing.T) {
+func TestFromJSON(t *testing.T) {
 	invalids := []string{
 		"anything",
 		"['a','list']",
@@ -105,14 +103,14 @@
 	}
 
 	for _, invalid := range invalids {
-		if _, err := FromParam(invalid); err == nil {
+		if _, err := FromJSON(invalid); err == nil {
 			t.Fatalf("Expected an error with %v, got nothing", invalid)
 		}
 	}
 
 	for expectedArgs, matchers := range valid {
 		for _, json := range matchers {
-			args, err := FromParam(json)
+			args, err := FromJSON(json)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -138,11 +136,11 @@
 
 func TestEmpty(t *testing.T) {
 	a := Args{}
-	v, err := ToParam(a)
+	v, err := ToJSON(a)
 	if err != nil {
 		t.Errorf("failed to marshal the filters: %s", err)
 	}
-	v1, err := FromParam(v)
+	v1, err := FromJSON(v)
 	if err != nil {
 		t.Errorf("%s", err)
 	}
@@ -184,7 +182,7 @@
 	}
 
 	for args, field := range matches {
-		if args.MatchKVList(field, sources) != true {
+		if !args.MatchKVList(field, sources) {
 			t.Fatalf("Expected true for %v on %v, got false", sources, args)
 		}
 	}
@@ -204,7 +202,7 @@
 	}
 
 	for args, field := range differs {
-		if args.MatchKVList(field, sources) != false {
+		if args.MatchKVList(field, sources) {
 			t.Fatalf("Expected false for %v on %v, got true", sources, args)
 		}
 	}
@@ -233,9 +231,8 @@
 	}
 
 	for args, field := range matches {
-		if args.Match(field, source) != true {
-			t.Fatalf("Expected true for %v on %v, got false", source, args)
-		}
+		assert.True(t, args.Match(field, source),
+			"Expected field %s to match %s", field, source)
 	}
 
 	differs := map[*Args]string{
@@ -258,9 +255,8 @@
 	}
 
 	for args, field := range differs {
-		if args.Match(field, source) != false {
-			t.Fatalf("Expected false for %v on %v, got true", source, args)
-		}
+		assert.False(t, args.Match(field, source),
+			"Expected field %s to not match %s", field, source)
 	}
 }
 
@@ -341,6 +337,17 @@
 	}
 }
 
+func TestContains(t *testing.T) {
+	f := NewArgs()
+	if f.Contains("status") {
+		t.Fatal("Expected to not contain a status key, got true")
+	}
+	f.Add("status", "running")
+	if !f.Contains("status") {
+		t.Fatal("Expected to contain a status key, got false")
+	}
+}
+
 func TestInclude(t *testing.T) {
 	f := NewArgs()
 	if f.Include("status") {
diff --git a/api/types/mount/mount.go b/api/types/mount/mount.go
index 2744f85..b7d133c 100644
--- a/api/types/mount/mount.go
+++ b/api/types/mount/mount.go
@@ -15,6 +15,8 @@
 	TypeVolume Type = "volume"
 	// TypeTmpfs is the type for mounting tmpfs
 	TypeTmpfs Type = "tmpfs"
+	// TypeNamedPipe is the type for mounting Windows named pipes
+	TypeNamedPipe Type = "npipe"
 )
 
 // Mount represents a mount (volume).
@@ -65,7 +67,7 @@
 type Consistency string
 
 const (
-	// ConsistencyFull guarantees bind-mount-like consistency
+	// ConsistencyFull guarantees bind mount-like consistency
 	ConsistencyFull Consistency = "consistent"
 	// ConsistencyCached mounts can cache read data and FS structure
 	ConsistencyCached Consistency = "cached"
diff --git a/api/types/plugin.go b/api/types/plugin.go
index ed3c2c2..cab333e 100644
--- a/api/types/plugin.go
+++ b/api/types/plugin.go
@@ -11,7 +11,7 @@
 	// Required: true
 	Config PluginConfig `json:"Config"`
 
-	// True when the plugin is running. False when the plugin is not running, only installed.
+	// True if the plugin is running. False if the plugin is not running, only installed.
 	// Required: true
 	Enabled bool `json:"Enabled"`
 
diff --git a/api/types/swarm/common.go b/api/types/swarm/common.go
index 54af82b..2834cf2 100644
--- a/api/types/swarm/common.go
+++ b/api/types/swarm/common.go
@@ -20,7 +20,7 @@
 	Labels map[string]string `json:"Labels"`
 }
 
-// Driver represents a driver (network, logging).
+// Driver represents a driver (network, logging, secrets backend).
 type Driver struct {
 	Name    string            `json:",omitempty"`
 	Options map[string]string `json:",omitempty"`
diff --git a/api/types/time/timestamp.go b/api/types/time/timestamp.go
index 9aa9702..ed9c116 100644
--- a/api/types/time/timestamp.go
+++ b/api/types/time/timestamp.go
@@ -29,10 +29,8 @@
 	}
 
 	var format string
-	var parseInLocation bool
-
 	// if the string has a Z or a + or three dashes use parse otherwise use parseinlocation
-	parseInLocation = !(strings.ContainsAny(value, "zZ+") || strings.Count(value, "-") == 3)
+	parseInLocation := !(strings.ContainsAny(value, "zZ+") || strings.Count(value, "-") == 3)
 
 	if strings.Contains(value, ".") {
 		if parseInLocation {
diff --git a/builder/builder.go b/builder/builder.go
index e480601..f376f53 100644
--- a/builder/builder.go
+++ b/builder/builder.go
@@ -12,6 +12,7 @@
 	"github.com/docker/docker/api/types/container"
 	containerpkg "github.com/docker/docker/container"
 	"github.com/docker/docker/layer"
+	"github.com/docker/docker/pkg/containerfs"
 	"golang.org/x/net/context"
 )
 
@@ -24,7 +25,7 @@
 // instructions in the builder.
 type Source interface {
 	// Root returns root path for accessing source
-	Root() string
+	Root() containerfs.ContainerFS
 	// Close allows to signal that the filesystem tree won't be used anymore.
 	// For Context implementations using a temporary directory, it is recommended to
 	// delete the temporary directory in Close().
@@ -99,7 +100,7 @@
 // ReleaseableLayer is an image layer that can be mounted and released
 type ReleaseableLayer interface {
 	Release() error
-	Mount() (string, error)
+	Mount() (containerfs.ContainerFS, error)
 	Commit(platform string) (ReleaseableLayer, error)
 	DiffID() layer.DiffID
 }
diff --git a/builder/dockerfile/buildargs.go b/builder/dockerfile/buildargs.go
index e0daf9a..c8f34a7 100644
--- a/builder/dockerfile/buildargs.go
+++ b/builder/dockerfile/buildargs.go
@@ -42,6 +42,26 @@
 	}
 }
 
+func (b *buildArgs) Clone() *buildArgs {
+	result := newBuildArgs(b.argsFromOptions)
+	for k, v := range b.allowedBuildArgs {
+		result.allowedBuildArgs[k] = v
+	}
+	for k, v := range b.allowedMetaArgs {
+		result.allowedMetaArgs[k] = v
+	}
+	for k := range b.referencedArgs {
+		result.referencedArgs[k] = struct{}{}
+	}
+	return result
+}
+
+func (b *buildArgs) MergeReferencedArgs(other *buildArgs) {
+	for k := range other.referencedArgs {
+		b.referencedArgs[k] = struct{}{}
+	}
+}
+
 // WarnOnUnusedBuildArgs checks if there are any leftover build-args that were
 // passed but not consumed during build. Print a warning, if there are any.
 func (b *buildArgs) WarnOnUnusedBuildArgs(out io.Writer) {
diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go
index fb17862..27fd4d6 100644
--- a/builder/dockerfile/builder.go
+++ b/builder/dockerfile/builder.go
@@ -9,23 +9,21 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/builder"
-	"github.com/docker/docker/builder/dockerfile/command"
+	"github.com/docker/docker/builder/dockerfile/instructions"
 	"github.com/docker/docker/builder/dockerfile/parser"
 	"github.com/docker/docker/builder/fscache"
 	"github.com/docker/docker/builder/remotecontext"
-	"github.com/docker/docker/client/session"
-	"github.com/docker/docker/pkg/archive"
-	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/system"
+	"github.com/moby/buildkit/session"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/sync/syncmap"
 )
@@ -43,6 +41,10 @@
 	"workdir":     true,
 }
 
+const (
+	stepFormat = "Step %d/%d : %v"
+)
+
 // SessionGetter is object used to get access to a session by uuid
 type SessionGetter interface {
 	Get(ctx context.Context, uuid string) (session.Caller, error)
@@ -50,21 +52,21 @@
 
 // BuildManager is shared across all Builder objects
 type BuildManager struct {
-	archiver  *archive.Archiver
-	backend   builder.Backend
-	pathCache pathCache // TODO: make this persistent
-	sg        SessionGetter
-	fsCache   *fscache.FSCache
+	idMappings *idtools.IDMappings
+	backend    builder.Backend
+	pathCache  pathCache // TODO: make this persistent
+	sg         SessionGetter
+	fsCache    *fscache.FSCache
 }
 
 // NewBuildManager creates a BuildManager
 func NewBuildManager(b builder.Backend, sg SessionGetter, fsCache *fscache.FSCache, idMappings *idtools.IDMappings) (*BuildManager, error) {
 	bm := &BuildManager{
-		backend:   b,
-		pathCache: &syncmap.Map{},
-		sg:        sg,
-		archiver:  chrootarchive.NewArchiver(idMappings),
-		fsCache:   fsCache,
+		backend:    b,
+		pathCache:  &syncmap.Map{},
+		sg:         sg,
+		idMappings: idMappings,
+		fsCache:    fsCache,
 	}
 	if err := fsCache.RegisterTransport(remotecontext.ClientSessionRemote, NewClientSessionTransport()); err != nil {
 		return nil, err
@@ -114,7 +116,7 @@
 		ProgressWriter: config.ProgressWriter,
 		Backend:        bm.backend,
 		PathCache:      bm.pathCache,
-		Archiver:       bm.archiver,
+		IDMappings:     bm.idMappings,
 		Platform:       dockerfile.Platform,
 	}
 
@@ -160,7 +162,7 @@
 	Backend        builder.Backend
 	ProgressWriter backend.ProgressWriter
 	PathCache      pathCache
-	Archiver       *archive.Archiver
+	IDMappings     *idtools.IDMappings
 	Platform       string
 }
 
@@ -177,10 +179,8 @@
 	docker    builder.Backend
 	clientCtx context.Context
 
-	archiver         *archive.Archiver
-	buildStages      *buildStages
+	idMappings       *idtools.IDMappings
 	disableCommit    bool
-	buildArgs        *buildArgs
 	imageSources     *imageSources
 	pathCache        pathCache
 	containerManager *containerManager
@@ -219,9 +219,7 @@
 		Aux:              options.ProgressWriter.AuxFormatter,
 		Output:           options.ProgressWriter.Output,
 		docker:           options.Backend,
-		archiver:         options.Archiver,
-		buildArgs:        newBuildArgs(config.BuildArgs),
-		buildStages:      newBuildStages(),
+		idMappings:       options.IDMappings,
 		imageSources:     newImageSources(clientCtx, options),
 		pathCache:        options.PathCache,
 		imageProber:      newImageProber(options.Backend, config.CacheFrom, options.Platform, config.NoCache),
@@ -239,24 +237,27 @@
 
 	addNodesForLabelOption(dockerfile.AST, b.options.Labels)
 
-	if err := checkDispatchDockerfile(dockerfile.AST); err != nil {
-		buildsFailed.WithValues(metricsDockerfileSyntaxError).Inc()
-		return nil, err
-	}
-
-	dispatchState, err := b.dispatchDockerfileWithCancellation(dockerfile, source)
+	stages, metaArgs, err := instructions.Parse(dockerfile.AST)
 	if err != nil {
-		return nil, err
+		if instructions.IsUnknownInstruction(err) {
+			buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
+		}
+		return nil, validationError{err}
 	}
-
-	if b.options.Target != "" && !dispatchState.isCurrentStage(b.options.Target) {
-		buildsFailed.WithValues(metricsBuildTargetNotReachableError).Inc()
-		return nil, errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)
+	if b.options.Target != "" {
+		targetIx, found := instructions.HasStage(stages, b.options.Target)
+		if !found {
+			buildsFailed.WithValues(metricsBuildTargetNotReachableError).Inc()
+			return nil, errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)
+		}
+		stages = stages[:targetIx+1]
 	}
 
 	dockerfile.PrintWarnings(b.Stderr)
-	b.buildArgs.WarnOnUnusedBuildArgs(b.Stderr)
-
+	dispatchState, err := b.dispatchDockerfileWithCancellation(stages, metaArgs, dockerfile.EscapeToken, source)
+	if err != nil {
+		return nil, err
+	}
 	if dispatchState.imageID == "" {
 		buildsFailed.WithValues(metricsDockerfileEmptyError).Inc()
 		return nil, errors.New("No image was generated. Is your Dockerfile empty?")
@@ -271,61 +272,91 @@
 	return aux.Emit(types.BuildResult{ID: state.imageID})
 }
 
-func (b *Builder) dispatchDockerfileWithCancellation(dockerfile *parser.Result, source builder.Source) (*dispatchState, error) {
-	shlex := NewShellLex(dockerfile.EscapeToken)
-	state := newDispatchState()
-	total := len(dockerfile.AST.Children)
-	var err error
-	for i, n := range dockerfile.AST.Children {
-		select {
-		case <-b.clientCtx.Done():
-			logrus.Debug("Builder: build cancelled!")
-			fmt.Fprint(b.Stdout, "Build cancelled")
-			buildsFailed.WithValues(metricsBuildCanceled).Inc()
-			return nil, errors.New("Build cancelled")
-		default:
-			// Not cancelled yet, keep going...
-		}
+func processMetaArg(meta instructions.ArgCommand, shlex *ShellLex, args *buildArgs) error {
+	// ShellLex currently only support the concatenated string format
+	envs := convertMapToEnvList(args.GetAllAllowed())
+	if err := meta.Expand(func(word string) (string, error) {
+		return shlex.ProcessWord(word, envs)
+	}); err != nil {
+		return err
+	}
+	args.AddArg(meta.Key, meta.Value)
+	args.AddMetaArg(meta.Key, meta.Value)
+	return nil
+}
 
-		// If this is a FROM and we have a previous image then
-		// emit an aux message for that image since it is the
-		// end of the previous stage
-		if n.Value == command.From {
-			if err := emitImageID(b.Aux, state); err != nil {
-				return nil, err
-			}
-		}
+func printCommand(out io.Writer, currentCommandIndex int, totalCommands int, cmd interface{}) int {
+	fmt.Fprintf(out, stepFormat, currentCommandIndex, totalCommands, cmd)
+	fmt.Fprintln(out)
+	return currentCommandIndex + 1
+}
 
-		if n.Value == command.From && state.isCurrentStage(b.options.Target) {
-			break
-		}
+func (b *Builder) dispatchDockerfileWithCancellation(parseResult []instructions.Stage, metaArgs []instructions.ArgCommand, escapeToken rune, source builder.Source) (*dispatchState, error) {
+	dispatchRequest := dispatchRequest{}
+	buildArgs := newBuildArgs(b.options.BuildArgs)
+	totalCommands := len(metaArgs) + len(parseResult)
+	currentCommandIndex := 1
+	for _, stage := range parseResult {
+		totalCommands += len(stage.Commands)
+	}
+	shlex := NewShellLex(escapeToken)
+	for _, meta := range metaArgs {
+		currentCommandIndex = printCommand(b.Stdout, currentCommandIndex, totalCommands, &meta)
 
-		opts := dispatchOptions{
-			state:   state,
-			stepMsg: formatStep(i, total),
-			node:    n,
-			shlex:   shlex,
-			source:  source,
-		}
-		if state, err = b.dispatch(opts); err != nil {
-			if b.options.ForceRemove {
-				b.containerManager.RemoveAll(b.Stdout)
-			}
+		err := processMetaArg(meta, shlex, buildArgs)
+		if err != nil {
 			return nil, err
 		}
+	}
 
-		fmt.Fprintf(b.Stdout, " ---> %s\n", stringid.TruncateID(state.imageID))
-		if b.options.Remove {
-			b.containerManager.RemoveAll(b.Stdout)
+	stagesResults := newStagesBuildResults()
+
+	for _, stage := range parseResult {
+		if err := stagesResults.checkStageNameAvailable(stage.Name); err != nil {
+			return nil, err
+		}
+		dispatchRequest = newDispatchRequest(b, escapeToken, source, buildArgs, stagesResults)
+
+		currentCommandIndex = printCommand(b.Stdout, currentCommandIndex, totalCommands, stage.SourceCode)
+		if err := initializeStage(dispatchRequest, &stage); err != nil {
+			return nil, err
+		}
+		dispatchRequest.state.updateRunConfig()
+		fmt.Fprintf(b.Stdout, " ---> %s\n", stringid.TruncateID(dispatchRequest.state.imageID))
+		for _, cmd := range stage.Commands {
+			select {
+			case <-b.clientCtx.Done():
+				logrus.Debug("Builder: build cancelled!")
+				fmt.Fprint(b.Stdout, "Build cancelled\n")
+				buildsFailed.WithValues(metricsBuildCanceled).Inc()
+				return nil, errors.New("Build cancelled")
+			default:
+				// Not cancelled yet, keep going...
+			}
+
+			currentCommandIndex = printCommand(b.Stdout, currentCommandIndex, totalCommands, cmd)
+
+			if err := dispatch(dispatchRequest, cmd); err != nil {
+				return nil, err
+			}
+
+			dispatchRequest.state.updateRunConfig()
+			fmt.Fprintf(b.Stdout, " ---> %s\n", stringid.TruncateID(dispatchRequest.state.imageID))
+
+		}
+		if err := emitImageID(b.Aux, dispatchRequest.state); err != nil {
+			return nil, err
+		}
+		buildArgs.MergeReferencedArgs(dispatchRequest.state.buildArgs)
+		if err := commitStage(dispatchRequest.state, stagesResults); err != nil {
+			return nil, err
 		}
 	}
-
-	// Emit a final aux message for the final image
-	if err := emitImageID(b.Aux, state); err != nil {
-		return nil, err
+	if b.options.Remove {
+		b.containerManager.RemoveAll(b.Stdout)
 	}
-
-	return state, nil
+	buildArgs.WarnOnUnusedBuildArgs(b.Stdout)
+	return dispatchRequest.state, nil
 }
 
 func addNodesForLabelOption(dockerfile *parser.Node, labels map[string]string) {
@@ -357,7 +388,7 @@
 
 	dockerfile, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
 	if err != nil {
-		return nil, err
+		return nil, validationError{err}
 	}
 
 	// TODO @jhowardmsft LCOW support. For now, if LCOW enabled, switch to linux.
@@ -374,7 +405,7 @@
 	// ensure that the commands are valid
 	for _, n := range dockerfile.AST.Children {
 		if !validCommitCommands[n.Value] {
-			return nil, fmt.Errorf("%s is not a valid change command", n.Value)
+			return nil, validationError{errors.Errorf("%s is not a valid change command", n.Value)}
 		}
 	}
 
@@ -382,39 +413,33 @@
 	b.Stderr = ioutil.Discard
 	b.disableCommit = true
 
-	if err := checkDispatchDockerfile(dockerfile.AST); err != nil {
-		return nil, err
+	commands := []instructions.Command{}
+	for _, n := range dockerfile.AST.Children {
+		cmd, err := instructions.ParseCommand(n)
+		if err != nil {
+			return nil, validationError{err}
+		}
+		commands = append(commands, cmd)
 	}
-	dispatchState := newDispatchState()
-	dispatchState.runConfig = config
-	return dispatchFromDockerfile(b, dockerfile, dispatchState, nil)
+
+	dispatchRequest := newDispatchRequest(b, dockerfile.EscapeToken, nil, newBuildArgs(b.options.BuildArgs), newStagesBuildResults())
+	dispatchRequest.state.runConfig = config
+	dispatchRequest.state.imageID = config.Image
+	for _, cmd := range commands {
+		err := dispatch(dispatchRequest, cmd)
+		if err != nil {
+			return nil, validationError{err}
+		}
+		dispatchRequest.state.updateRunConfig()
+	}
+
+	return dispatchRequest.state.runConfig, nil
 }
 
-func checkDispatchDockerfile(dockerfile *parser.Node) error {
-	for _, n := range dockerfile.Children {
-		if err := checkDispatch(n); err != nil {
-			return errors.Wrapf(err, "Dockerfile parse error line %d", n.StartLine)
-		}
+func convertMapToEnvList(m map[string]string) []string {
+	result := []string{}
+	for k, v := range m {
+		result = append(result, k+"="+v)
 	}
-	return nil
-}
-
-func dispatchFromDockerfile(b *Builder, result *parser.Result, dispatchState *dispatchState, source builder.Source) (*container.Config, error) {
-	shlex := NewShellLex(result.EscapeToken)
-	ast := result.AST
-	total := len(ast.Children)
-
-	for i, n := range ast.Children {
-		opts := dispatchOptions{
-			state:   dispatchState,
-			stepMsg: formatStep(i, total),
-			node:    n,
-			shlex:   shlex,
-			source:  source,
-		}
-		if _, err := b.dispatch(opts); err != nil {
-			return nil, err
-		}
-	}
-	return dispatchState.runConfig, nil
+	return result
 }
diff --git a/builder/dockerfile/clientsession.go b/builder/dockerfile/clientsession.go
index a7709ce..2ef5bf5 100644
--- a/builder/dockerfile/clientsession.go
+++ b/builder/dockerfile/clientsession.go
@@ -5,8 +5,8 @@
 
 	"github.com/docker/docker/builder/fscache"
 	"github.com/docker/docker/builder/remotecontext"
-	"github.com/docker/docker/client/session"
-	"github.com/docker/docker/client/session/filesync"
+	"github.com/moby/buildkit/session"
+	"github.com/moby/buildkit/session/filesync"
 	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 )
@@ -41,7 +41,6 @@
 type ClientSessionSourceIdentifier struct {
 	includePatterns []string
 	caller          session.Caller
-	sharedKey       string
 	uuid            string
 }
 
diff --git a/builder/dockerfile/containerbackend.go b/builder/dockerfile/containerbackend.go
index 7b241f3..d11c952 100644
--- a/builder/dockerfile/containerbackend.go
+++ b/builder/dockerfile/containerbackend.go
@@ -4,13 +4,13 @@
 	"fmt"
 	"io"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/builder"
 	containerpkg "github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/builder/dockerfile/copy.go b/builder/dockerfile/copy.go
index c7db943..f4b703d 100644
--- a/builder/dockerfile/copy.go
+++ b/builder/dockerfile/copy.go
@@ -1,12 +1,15 @@
 package dockerfile
 
 import (
+	"archive/tar"
 	"fmt"
 	"io"
+	"mime"
 	"net/http"
 	"net/url"
 	"os"
 	"path/filepath"
+	"runtime"
 	"sort"
 	"strings"
 	"time"
@@ -14,16 +17,18 @@
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/builder/remotecontext"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/streamformatter"
-	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/pkg/urlutil"
 	"github.com/pkg/errors"
 )
 
+const unnamedFilename = "__unnamed__"
+
 type pathCache interface {
 	Load(key interface{}) (value interface{}, ok bool)
 	Store(key, value interface{})
@@ -32,14 +37,14 @@
 // copyInfo is a data object which stores the metadata about each source file in
 // a copyInstruction
 type copyInfo struct {
-	root         string
+	root         containerfs.ContainerFS
 	path         string
 	hash         string
 	noDecompress bool
 }
 
 func (c copyInfo) fullPath() (string, error) {
-	return symlink.FollowSymlinkInScope(filepath.Join(c.root, c.path), c.root)
+	return c.root.ResolveScopedPath(c.path, true)
 }
 
 func newCopyInfoFromSource(source builder.Source, path string, hash string) copyInfo {
@@ -56,6 +61,7 @@
 	cmdName                 string
 	infos                   []copyInfo
 	dest                    string
+	chownStr                string
 	allowLocalDecompression bool
 }
 
@@ -67,6 +73,7 @@
 	pathCache   pathCache
 	download    sourceDownloader
 	tmpPaths    []string
+	platform    string
 }
 
 func copierFromDispatchRequest(req dispatchRequest, download sourceDownloader, imageSource *imageMount) copier {
@@ -75,6 +82,7 @@
 		pathCache:   req.builder.pathCache,
 		download:    download,
 		imageSource: imageSource,
+		platform:    req.builder.platform,
 	}
 }
 
@@ -82,14 +90,14 @@
 	inst := copyInstruction{cmdName: cmdName}
 	last := len(args) - 1
 
-	// Work in daemon-specific filepath semantics
-	inst.dest = filepath.FromSlash(args[last])
-
-	infos, err := o.getCopyInfosForSourcePaths(args[0:last])
+	// Work in platform-specific filepath semantics
+	inst.dest = fromSlash(args[last], o.platform)
+	separator := string(separator(o.platform))
+	infos, err := o.getCopyInfosForSourcePaths(args[0:last], inst.dest)
 	if err != nil {
 		return inst, errors.Wrapf(err, "%s failed", cmdName)
 	}
-	if len(infos) > 1 && !strings.HasSuffix(inst.dest, string(os.PathSeparator)) {
+	if len(infos) > 1 && !strings.HasSuffix(inst.dest, separator) {
 		return inst, errors.Errorf("When using %s with more than one source file, the destination must be a directory and end with a /", cmdName)
 	}
 	inst.infos = infos
@@ -98,10 +106,11 @@
 
 // getCopyInfosForSourcePaths iterates over the source files and calculate the info
 // needed to copy (e.g. hash value if cached)
-func (o *copier) getCopyInfosForSourcePaths(sources []string) ([]copyInfo, error) {
+// The dest is used in case source is URL (and ends with "/")
+func (o *copier) getCopyInfosForSourcePaths(sources []string, dest string) ([]copyInfo, error) {
 	var infos []copyInfo
 	for _, orig := range sources {
-		subinfos, err := o.getCopyInfoForSourcePath(orig)
+		subinfos, err := o.getCopyInfoForSourcePath(orig, dest)
 		if err != nil {
 			return nil, err
 		}
@@ -114,15 +123,24 @@
 	return infos, nil
 }
 
-func (o *copier) getCopyInfoForSourcePath(orig string) ([]copyInfo, error) {
+func (o *copier) getCopyInfoForSourcePath(orig, dest string) ([]copyInfo, error) {
 	if !urlutil.IsURL(orig) {
 		return o.calcCopyInfo(orig, true)
 	}
+
 	remote, path, err := o.download(orig)
 	if err != nil {
 		return nil, err
 	}
-	o.tmpPaths = append(o.tmpPaths, remote.Root())
+	// If path == "" then we are unable to determine filename from src
+	// We have to make sure dest is available
+	if path == "" {
+		if strings.HasSuffix(dest, "/") {
+			return nil, errors.Errorf("cannot determine filename for source %s", orig)
+		}
+		path = unnamedFilename
+	}
+	o.tmpPaths = append(o.tmpPaths, remote.Root().Path())
 
 	hash, err := remote.Hash(path)
 	ci := newCopyInfoFromSource(remote, path, hash)
@@ -142,14 +160,6 @@
 // TODO: allowWildcards can probably be removed by refactoring this function further.
 func (o *copier) calcCopyInfo(origPath string, allowWildcards bool) ([]copyInfo, error) {
 	imageSource := o.imageSource
-	if err := validateCopySourcePath(imageSource, origPath); err != nil {
-		return nil, err
-	}
-
-	// Work in daemon-specific OS filepath semantics
-	origPath = filepath.FromSlash(origPath)
-	origPath = strings.TrimPrefix(origPath, string(os.PathSeparator))
-	origPath = strings.TrimPrefix(origPath, "."+string(os.PathSeparator))
 
 	// TODO: do this when creating copier. Requires validateCopySourcePath
 	// (and other below) to be aware of the difference sources. Why is it only
@@ -166,8 +176,20 @@
 		return nil, errors.Errorf("missing build context")
 	}
 
+	root := o.source.Root()
+
+	if err := validateCopySourcePath(imageSource, origPath, root.OS()); err != nil {
+		return nil, err
+	}
+
+	// Work in source OS specific filepath semantics
+	// For LCOW, this is NOT the daemon OS.
+	origPath = root.FromSlash(origPath)
+	origPath = strings.TrimPrefix(origPath, string(root.Separator()))
+	origPath = strings.TrimPrefix(origPath, "."+string(root.Separator()))
+
 	// Deal with wildcards
-	if allowWildcards && containsWildcards(origPath) {
+	if allowWildcards && containsWildcards(origPath, root.OS()) {
 		return o.copyWithWildcards(origPath)
 	}
 
@@ -199,6 +221,19 @@
 	return newCopyInfos(newCopyInfoFromSource(o.source, origPath, hash)), nil
 }
 
+func containsWildcards(name, platform string) bool {
+	isWindows := platform == "windows"
+	for i := 0; i < len(name); i++ {
+		ch := name[i]
+		if ch == '\\' && !isWindows {
+			i++
+		} else if ch == '*' || ch == '?' || ch == '[' {
+			return true
+		}
+	}
+	return false
+}
+
 func (o *copier) storeInPathCache(im *imageMount, path string, hash string) {
 	if im != nil {
 		o.pathCache.Store(im.ImageID()+path, hash)
@@ -206,12 +241,13 @@
 }
 
 func (o *copier) copyWithWildcards(origPath string) ([]copyInfo, error) {
+	root := o.source.Root()
 	var copyInfos []copyInfo
-	if err := filepath.Walk(o.source.Root(), func(path string, info os.FileInfo, err error) error {
+	if err := root.Walk(root.Path(), func(path string, info os.FileInfo, err error) error {
 		if err != nil {
 			return err
 		}
-		rel, err := remotecontext.Rel(o.source.Root(), path)
+		rel, err := remotecontext.Rel(root, path)
 		if err != nil {
 			return err
 		}
@@ -219,7 +255,7 @@
 		if rel == "." {
 			return nil
 		}
-		if match, _ := filepath.Match(origPath, rel); !match {
+		if match, _ := root.Match(origPath, rel); !match {
 			return nil
 		}
 
@@ -261,7 +297,7 @@
 	}
 	// Must be a dir
 	var subfiles []string
-	err = filepath.Walk(fp, func(path string, info os.FileInfo, err error) error {
+	err = source.Root().Walk(fp, func(path string, info os.FileInfo, err error) error {
 		if err != nil {
 			return err
 		}
@@ -300,22 +336,40 @@
 	return nil, "", errors.New("source can't be a URL for COPY")
 }
 
+func getFilenameForDownload(path string, resp *http.Response) string {
+	// Guess filename based on source
+	if path != "" && !strings.HasSuffix(path, "/") {
+		if filename := filepath.Base(filepath.FromSlash(path)); filename != "" {
+			return filename
+		}
+	}
+
+	// Guess filename based on Content-Disposition
+	if contentDisposition := resp.Header.Get("Content-Disposition"); contentDisposition != "" {
+		if _, params, err := mime.ParseMediaType(contentDisposition); err == nil {
+			if params["filename"] != "" && !strings.HasSuffix(params["filename"], "/") {
+				if filename := filepath.Base(filepath.FromSlash(params["filename"])); filename != "" {
+					return filename
+				}
+			}
+		}
+	}
+	return ""
+}
+
 func downloadSource(output io.Writer, stdout io.Writer, srcURL string) (remote builder.Source, p string, err error) {
 	u, err := url.Parse(srcURL)
 	if err != nil {
 		return
 	}
-	filename := filepath.Base(filepath.FromSlash(u.Path)) // Ensure in platform semantics
-	if filename == "" {
-		err = errors.Errorf("cannot determine filename from url: %s", u)
-		return
-	}
 
 	resp, err := remotecontext.GetWithStatusError(srcURL)
 	if err != nil {
 		return
 	}
 
+	filename := getFilenameForDownload(u.Path, resp)
+
 	// Prepare file in a tmp dir
 	tmpDir, err := ioutils.TempDir("", "docker-remote")
 	if err != nil {
@@ -326,7 +380,13 @@
 			os.RemoveAll(tmpDir)
 		}
 	}()
-	tmpFileName := filepath.Join(tmpDir, filename)
+	// If filename is empty, the returned filename will be "" but
+	// the tmp filename will be created as "__unnamed__"
+	tmpFileName := filename
+	if filename == "" {
+		tmpFileName = unnamedFilename
+	}
+	tmpFileName = filepath.Join(tmpDir, tmpFileName)
 	tmpFile, err := os.OpenFile(tmpFileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
 	if err != nil {
 		return
@@ -362,13 +422,19 @@
 		return
 	}
 
-	lc, err := remotecontext.NewLazySource(tmpDir)
+	lc, err := remotecontext.NewLazySource(containerfs.NewLocalContainerFS(tmpDir))
 	return lc, filename, err
 }
 
 type copyFileOptions struct {
 	decompress bool
-	archiver   *archive.Archiver
+	chownPair  idtools.IDPair
+	archiver   Archiver
+}
+
+type copyEndpoint struct {
+	driver containerfs.Driver
+	path   string
 }
 
 func performCopyForInfo(dest copyInfo, source copyInfo, options copyFileOptions) error {
@@ -376,6 +442,7 @@
 	if err != nil {
 		return err
 	}
+
 	destPath, err := dest.fullPath()
 	if err != nil {
 		return err
@@ -383,57 +450,90 @@
 
 	archiver := options.archiver
 
-	src, err := os.Stat(srcPath)
+	srcEndpoint := &copyEndpoint{driver: source.root, path: srcPath}
+	destEndpoint := &copyEndpoint{driver: dest.root, path: destPath}
+
+	src, err := source.root.Stat(srcPath)
 	if err != nil {
 		return errors.Wrapf(err, "source path not found")
 	}
 	if src.IsDir() {
-		return copyDirectory(archiver, srcPath, destPath)
+		return copyDirectory(archiver, srcEndpoint, destEndpoint, options.chownPair)
 	}
-	if options.decompress && archive.IsArchivePath(srcPath) && !source.noDecompress {
+	if options.decompress && isArchivePath(source.root, srcPath) && !source.noDecompress {
 		return archiver.UntarPath(srcPath, destPath)
 	}
 
-	destExistsAsDir, err := isExistingDirectory(destPath)
+	destExistsAsDir, err := isExistingDirectory(destEndpoint)
 	if err != nil {
 		return err
 	}
 	// dest.path must be used because destPath has already been cleaned of any
 	// trailing slash
-	if endsInSlash(dest.path) || destExistsAsDir {
+	if endsInSlash(dest.root, dest.path) || destExistsAsDir {
 		// source.path must be used to get the correct filename when the source
 		// is a symlink
-		destPath = filepath.Join(destPath, filepath.Base(source.path))
+		destPath = dest.root.Join(destPath, source.root.Base(source.path))
+		destEndpoint = &copyEndpoint{driver: dest.root, path: destPath}
 	}
-	return copyFile(archiver, srcPath, destPath)
+	return copyFile(archiver, srcEndpoint, destEndpoint, options.chownPair)
 }
 
-func copyDirectory(archiver *archive.Archiver, source, dest string) error {
-	if err := archiver.CopyWithTar(source, dest); err != nil {
+func isArchivePath(driver containerfs.ContainerFS, path string) bool {
+	file, err := driver.Open(path)
+	if err != nil {
+		return false
+	}
+	defer file.Close()
+	rdr, err := archive.DecompressStream(file)
+	if err != nil {
+		return false
+	}
+	r := tar.NewReader(rdr)
+	_, err = r.Next()
+	return err == nil
+}
+
+func copyDirectory(archiver Archiver, source, dest *copyEndpoint, chownPair idtools.IDPair) error {
+	destExists, err := isExistingDirectory(dest)
+	if err != nil {
+		return errors.Wrapf(err, "failed to query destination path")
+	}
+
+	if err := archiver.CopyWithTar(source.path, dest.path); err != nil {
 		return errors.Wrapf(err, "failed to copy directory")
 	}
-	return fixPermissions(source, dest, archiver.IDMappings.RootPair())
+	// TODO: @gupta-ak. Investigate how LCOW permission mappings will work.
+	return fixPermissions(source.path, dest.path, chownPair, !destExists)
 }
 
-func copyFile(archiver *archive.Archiver, source, dest string) error {
-	rootIDs := archiver.IDMappings.RootPair()
-
-	if err := idtools.MkdirAllAndChownNew(filepath.Dir(dest), 0755, rootIDs); err != nil {
-		return errors.Wrapf(err, "failed to create new directory")
+func copyFile(archiver Archiver, source, dest *copyEndpoint, chownPair idtools.IDPair) error {
+	if runtime.GOOS == "windows" && dest.driver.OS() == "linux" {
+		// LCOW
+		if err := dest.driver.MkdirAll(dest.driver.Dir(dest.path), 0755); err != nil {
+			return errors.Wrapf(err, "failed to create new directory")
+		}
+	} else {
+		if err := idtools.MkdirAllAndChownNew(filepath.Dir(dest.path), 0755, chownPair); err != nil {
+			// Normal containers
+			return errors.Wrapf(err, "failed to create new directory")
+		}
 	}
-	if err := archiver.CopyFileWithTar(source, dest); err != nil {
+
+	if err := archiver.CopyFileWithTar(source.path, dest.path); err != nil {
 		return errors.Wrapf(err, "failed to copy file")
 	}
-	return fixPermissions(source, dest, rootIDs)
+	// TODO: @gupta-ak. Investigate how LCOW permission mappings will work.
+	return fixPermissions(source.path, dest.path, chownPair, false)
 }
 
-func endsInSlash(path string) bool {
-	return strings.HasSuffix(path, string(os.PathSeparator))
+func endsInSlash(driver containerfs.Driver, path string) bool {
+	return strings.HasSuffix(path, string(driver.Separator()))
 }
 
 // isExistingDirectory returns true if the path exists and is a directory
-func isExistingDirectory(path string) (bool, error) {
-	destStat, err := os.Stat(path)
+func isExistingDirectory(point *copyEndpoint) (bool, error) {
+	destStat, err := point.driver.Stat(point.path)
 	switch {
 	case os.IsNotExist(err):
 		return false, nil
diff --git a/builder/dockerfile/copy_test.go b/builder/dockerfile/copy_test.go
index aee225b..87c5675 100644
--- a/builder/dockerfile/copy_test.go
+++ b/builder/dockerfile/copy_test.go
@@ -1,16 +1,18 @@
 package dockerfile
 
 import (
+	"net/http"
 	"testing"
 
-	"github.com/docker/docker/pkg/testutil/tempfile"
+	"github.com/docker/docker/pkg/containerfs"
+	"github.com/gotestyourself/gotestyourself/fs"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestIsExistingDirectory(t *testing.T) {
-	tmpfile := tempfile.NewTempFile(t, "file-exists-test", "something")
+	tmpfile := fs.NewFile(t, "file-exists-test", fs.WithContent("something"))
 	defer tmpfile.Remove()
-	tmpdir := tempfile.NewTempDir(t, "dir-exists-test")
+	tmpdir := fs.NewDir(t, "dir-exists-test")
 	defer tmpdir.Remove()
 
 	var testcases = []struct {
@@ -20,7 +22,7 @@
 	}{
 		{
 			doc:      "directory exists",
-			path:     tmpdir.Path,
+			path:     tmpdir.Path(),
 			expected: true,
 		},
 		{
@@ -30,16 +32,116 @@
 		},
 		{
 			doc:      "file exists",
-			path:     tmpfile.Name(),
+			path:     tmpfile.Path(),
 			expected: false,
 		},
 	}
 
 	for _, testcase := range testcases {
-		result, err := isExistingDirectory(testcase.path)
+		result, err := isExistingDirectory(&copyEndpoint{driver: containerfs.NewLocalDriver(), path: testcase.path})
 		if !assert.NoError(t, err) {
 			continue
 		}
 		assert.Equal(t, testcase.expected, result, testcase.doc)
 	}
 }
+
+func TestGetFilenameForDownload(t *testing.T) {
+	var testcases = []struct {
+		path        string
+		disposition string
+		expected    string
+	}{
+		{
+			path:     "http://www.example.com/",
+			expected: "",
+		},
+		{
+			path:     "http://www.example.com/xyz",
+			expected: "xyz",
+		},
+		{
+			path:     "http://www.example.com/xyz.html",
+			expected: "xyz.html",
+		},
+		{
+			path:     "http://www.example.com/xyz/",
+			expected: "",
+		},
+		{
+			path:     "http://www.example.com/xyz/uvw",
+			expected: "uvw",
+		},
+		{
+			path:     "http://www.example.com/xyz/uvw.html",
+			expected: "uvw.html",
+		},
+		{
+			path:     "http://www.example.com/xyz/uvw/",
+			expected: "",
+		},
+		{
+			path:     "/",
+			expected: "",
+		},
+		{
+			path:     "/xyz",
+			expected: "xyz",
+		},
+		{
+			path:     "/xyz.html",
+			expected: "xyz.html",
+		},
+		{
+			path:     "/xyz/",
+			expected: "",
+		},
+		{
+			path:        "/xyz/",
+			disposition: "attachment; filename=xyz.html",
+			expected:    "xyz.html",
+		},
+		{
+			disposition: "",
+			expected:    "",
+		},
+		{
+			disposition: "attachment; filename=xyz",
+			expected:    "xyz",
+		},
+		{
+			disposition: "attachment; filename=xyz.html",
+			expected:    "xyz.html",
+		},
+		{
+			disposition: "attachment; filename=\"xyz\"",
+			expected:    "xyz",
+		},
+		{
+			disposition: "attachment; filename=\"xyz.html\"",
+			expected:    "xyz.html",
+		},
+		{
+			disposition: "attachment; filename=\"/xyz.html\"",
+			expected:    "xyz.html",
+		},
+		{
+			disposition: "attachment; filename=\"/xyz/uvw\"",
+			expected:    "uvw",
+		},
+		{
+			disposition: "attachment; filename=\"Naïve file.txt\"",
+			expected:    "Naïve file.txt",
+		},
+	}
+	for _, testcase := range testcases {
+		resp := http.Response{
+			Header: make(map[string][]string),
+		}
+		if testcase.disposition != "" {
+			resp.Header.Add("Content-Disposition", testcase.disposition)
+		}
+		filename := getFilenameForDownload(testcase.path, &resp)
+		assert.Equal(t, testcase.expected, filename)
+	}
+}
diff --git a/builder/dockerfile/copy_unix.go b/builder/dockerfile/copy_unix.go
index 326d95b..8833700 100644
--- a/builder/dockerfile/copy_unix.go
+++ b/builder/dockerfile/copy_unix.go
@@ -6,13 +6,21 @@
 	"os"
 	"path/filepath"
 
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 )
 
-func fixPermissions(source, destination string, rootIDs idtools.IDPair) error {
-	skipChownRoot, err := isExistingDirectory(destination)
-	if err != nil {
-		return err
+func fixPermissions(source, destination string, rootIDs idtools.IDPair, overrideSkip bool) error {
+	var (
+		skipChownRoot bool
+		err           error
+	)
+	if !overrideSkip {
+		destEndpoint := &copyEndpoint{driver: containerfs.NewLocalDriver(), path: destination}
+		skipChownRoot, err = isExistingDirectory(destEndpoint)
+		if err != nil {
+			return err
+		}
 	}
 
 	// We Walk on the source rather than on the destination because we don't
@@ -34,3 +42,7 @@
 		return os.Lchown(fullpath, rootIDs.UID, rootIDs.GID)
 	})
 }
+
+func validateCopySourcePath(imageSource *imageMount, origPath, platform string) error {
+	return nil
+}
diff --git a/builder/dockerfile/copy_windows.go b/builder/dockerfile/copy_windows.go
index 78f5b09..f7fc6e0 100644
--- a/builder/dockerfile/copy_windows.go
+++ b/builder/dockerfile/copy_windows.go
@@ -1,8 +1,43 @@
 package dockerfile
 
-import "github.com/docker/docker/pkg/idtools"
+import (
+	"errors"
+	"path/filepath"
+	"strings"
 
-func fixPermissions(source, destination string, rootIDs idtools.IDPair) error {
+	"github.com/docker/docker/pkg/idtools"
+)
+
+var pathBlacklist = map[string]bool{
+	"c:\\":        true,
+	"c:\\windows": true,
+}
+
+func fixPermissions(source, destination string, rootIDs idtools.IDPair, overrideSkip bool) error {
 	// chown is not supported on Windows
 	return nil
 }
+
+func validateCopySourcePath(imageSource *imageMount, origPath, platform string) error {
+	// validate windows paths from other images + LCOW
+	if imageSource == nil || platform != "windows" {
+		return nil
+	}
+
+	origPath = filepath.FromSlash(origPath)
+	p := strings.ToLower(filepath.Clean(origPath))
+	if !filepath.IsAbs(p) {
+		if filepath.VolumeName(p) != "" {
+			if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths
+				p = p[:len(p)-1]
+			}
+			p += "\\"
+		} else {
+			p = filepath.Join("c:\\", p)
+		}
+	}
+	if _, blacklisted := pathBlacklist[p]; blacklisted {
+		return errors.New("copy from c:\\ or c:\\windows is not allowed on windows")
+	}
+	return nil
+}
diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go
index 1f74241..76bcb0b 100644
--- a/builder/dockerfile/dispatchers.go
+++ b/builder/dockerfile/dispatchers.go
@@ -10,18 +10,15 @@
 import (
 	"bytes"
 	"fmt"
-	"regexp"
 	"runtime"
 	"sort"
-	"strconv"
 	"strings"
-	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/strslice"
 	"github.com/docker/docker/builder"
+	"github.com/docker/docker/builder/dockerfile/instructions"
 	"github.com/docker/docker/builder/dockerfile/parser"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/jsonmessage"
@@ -29,6 +26,7 @@
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/go-connections/nat"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ENV foo bar
@@ -36,32 +34,14 @@
 // Sets the environment variable foo to bar, also makes interpolation
 // in the dockerfile available from the next statement on via ${foo}.
 //
-func env(req dispatchRequest) error {
-	if len(req.args) == 0 {
-		return errAtLeastOneArgument("ENV")
-	}
-
-	if len(req.args)%2 != 0 {
-		// should never get here, but just in case
-		return errTooManyArguments("ENV")
-	}
-
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	runConfig := req.state.runConfig
+func dispatchEnv(d dispatchRequest, c *instructions.EnvCommand) error {
+	runConfig := d.state.runConfig
 	commitMessage := bytes.NewBufferString("ENV")
+	for _, e := range c.Env {
+		name := e.Key
+		newVar := e.String()
 
-	for j := 0; j < len(req.args); j += 2 {
-		if len(req.args[j]) == 0 {
-			return errBlankCommandNames("ENV")
-		}
-		name := req.args[j]
-		value := req.args[j+1]
-		newVar := name + "=" + value
 		commitMessage.WriteString(" " + newVar)
-
 		gotOne := false
 		for i, envVar := range runConfig.Env {
 			envParts := strings.SplitN(envVar, "=", 2)
@@ -76,64 +56,32 @@
 			runConfig.Env = append(runConfig.Env, newVar)
 		}
 	}
-
-	return req.builder.commit(req.state, commitMessage.String())
+	return d.builder.commit(d.state, commitMessage.String())
 }
 
 // MAINTAINER some text <maybe@an.email.address>
 //
 // Sets the maintainer metadata.
-func maintainer(req dispatchRequest) error {
-	if len(req.args) != 1 {
-		return errExactlyOneArgument("MAINTAINER")
-	}
+func dispatchMaintainer(d dispatchRequest, c *instructions.MaintainerCommand) error {
 
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	maintainer := req.args[0]
-	req.state.maintainer = maintainer
-	return req.builder.commit(req.state, "MAINTAINER "+maintainer)
+	d.state.maintainer = c.Maintainer
+	return d.builder.commit(d.state, "MAINTAINER "+c.Maintainer)
 }
 
 // LABEL some json data describing the image
 //
 // Sets the Label variable foo to bar,
 //
-func label(req dispatchRequest) error {
-	if len(req.args) == 0 {
-		return errAtLeastOneArgument("LABEL")
+func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error {
+	if d.state.runConfig.Labels == nil {
+		d.state.runConfig.Labels = make(map[string]string)
 	}
-	if len(req.args)%2 != 0 {
-		// should never get here, but just in case
-		return errTooManyArguments("LABEL")
-	}
-
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
 	commitStr := "LABEL"
-	runConfig := req.state.runConfig
-
-	if runConfig.Labels == nil {
-		runConfig.Labels = map[string]string{}
+	for _, v := range c.Labels {
+		d.state.runConfig.Labels[v.Key] = v.Value
+		commitStr += " " + v.String()
 	}
-
-	for j := 0; j < len(req.args); j++ {
-		name := req.args[j]
-		if name == "" {
-			return errBlankCommandNames("LABEL")
-		}
-
-		value := req.args[j+1]
-		commitStr += " " + name + "=" + value
-
-		runConfig.Labels[name] = value
-		j++
-	}
-	return req.builder.commit(req.state, commitStr)
+	return d.builder.commit(d.state, commitStr)
 }
 
 // ADD foo /path
@@ -141,253 +89,172 @@
 // Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling
 // exist here. If you do not wish to have this automatic handling, use COPY.
 //
-func add(req dispatchRequest) error {
-	if len(req.args) < 2 {
-		return errAtLeastTwoArguments("ADD")
-	}
-
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	downloader := newRemoteSourceDownloader(req.builder.Output, req.builder.Stdout)
-	copier := copierFromDispatchRequest(req, downloader, nil)
+func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
+	downloader := newRemoteSourceDownloader(d.builder.Output, d.builder.Stdout)
+	copier := copierFromDispatchRequest(d, downloader, nil)
 	defer copier.Cleanup()
-	copyInstruction, err := copier.createCopyInstruction(req.args, "ADD")
+
+	copyInstruction, err := copier.createCopyInstruction(c.SourcesAndDest, "ADD")
 	if err != nil {
 		return err
 	}
+	copyInstruction.chownStr = c.Chown
 	copyInstruction.allowLocalDecompression = true
 
-	return req.builder.performCopy(req.state, copyInstruction)
+	return d.builder.performCopy(d.state, copyInstruction)
 }
 
 // COPY foo /path
 //
 // Same as 'ADD' but without the tar and remote url handling.
 //
-func dispatchCopy(req dispatchRequest) error {
-	if len(req.args) < 2 {
-		return errAtLeastTwoArguments("COPY")
+func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error {
+	var im *imageMount
+	var err error
+	if c.From != "" {
+		im, err = d.getImageMount(c.From)
+		if err != nil {
+			return errors.Wrapf(err, "invalid from flag value %s", c.From)
+		}
 	}
-
-	flFrom := req.flags.AddString("from", "")
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	im, err := req.builder.getImageMount(flFrom)
-	if err != nil {
-		return errors.Wrapf(err, "invalid from flag value %s", flFrom.Value)
-	}
-
-	copier := copierFromDispatchRequest(req, errOnSourceDownload, im)
+	copier := copierFromDispatchRequest(d, errOnSourceDownload, im)
 	defer copier.Cleanup()
-	copyInstruction, err := copier.createCopyInstruction(req.args, "COPY")
+	copyInstruction, err := copier.createCopyInstruction(c.SourcesAndDest, "COPY")
 	if err != nil {
 		return err
 	}
+	copyInstruction.chownStr = c.Chown
 
-	return req.builder.performCopy(req.state, copyInstruction)
+	return d.builder.performCopy(d.state, copyInstruction)
 }
 
-func (b *Builder) getImageMount(fromFlag *Flag) (*imageMount, error) {
-	if !fromFlag.IsUsed() {
+func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error) {
+	if imageRefOrID == "" {
 		// TODO: this could return the source in the default case as well?
 		return nil, nil
 	}
 
 	var localOnly bool
-	imageRefOrID := fromFlag.Value
-	stage, err := b.buildStages.get(fromFlag.Value)
+	stage, err := d.stages.get(imageRefOrID)
 	if err != nil {
 		return nil, err
 	}
 	if stage != nil {
-		imageRefOrID = stage.ImageID()
+		imageRefOrID = stage.Image
 		localOnly = true
 	}
-	return b.imageSources.Get(imageRefOrID, localOnly)
+	return d.builder.imageSources.Get(imageRefOrID, localOnly)
 }
 
 // FROM imagename[:tag | @digest] [AS build-stage-name]
 //
-func from(req dispatchRequest) error {
-	stageName, err := parseBuildStageName(req.args)
+func initializeStage(d dispatchRequest, cmd *instructions.Stage) error {
+	d.builder.imageProber.Reset()
+	image, err := d.getFromImage(d.shlex, cmd.BaseName)
 	if err != nil {
 		return err
 	}
-
-	if err := req.flags.Parse(); err != nil {
-		return err
+	state := d.state
+	state.beginStage(cmd.Name, image)
+	if len(state.runConfig.OnBuild) > 0 {
+		triggers := state.runConfig.OnBuild
+		state.runConfig.OnBuild = nil
+		return dispatchTriggeredOnBuild(d, triggers)
 	}
-
-	req.builder.imageProber.Reset()
-	image, err := req.builder.getFromImage(req.shlex, req.args[0])
-	if err != nil {
-		return err
-	}
-	if err := req.builder.buildStages.add(stageName, image); err != nil {
-		return err
-	}
-	req.state.beginStage(stageName, image)
-	req.builder.buildArgs.ResetAllowed()
-	if image.ImageID() == "" {
-		// Typically this means they used "FROM scratch"
-		return nil
-	}
-
-	return processOnBuild(req)
+	return nil
 }
 
-func parseBuildStageName(args []string) (string, error) {
-	stageName := ""
-	switch {
-	case len(args) == 3 && strings.EqualFold(args[1], "as"):
-		stageName = strings.ToLower(args[2])
-		if ok, _ := regexp.MatchString("^[a-z][a-z0-9-_\\.]*$", stageName); !ok {
-			return "", errors.Errorf("invalid name for build stage: %q, name can't start with a number or contain symbols", stageName)
-		}
-	case len(args) != 1:
-		return "", errors.New("FROM requires either one or three arguments")
+func dispatchTriggeredOnBuild(d dispatchRequest, triggers []string) error {
+	fmt.Fprintf(d.builder.Stdout, "# Executing %d build trigger", len(triggers))
+	if len(triggers) > 1 {
+		fmt.Fprint(d.builder.Stdout, "s")
 	}
-
-	return stageName, nil
-}
-
-// scratchImage is used as a token for the empty base image.
-var scratchImage builder.Image = &image.Image{}
-
-func (b *Builder) getFromImage(shlex *ShellLex, name string) (builder.Image, error) {
-	substitutionArgs := []string{}
-	for key, value := range b.buildArgs.GetAllMeta() {
-		substitutionArgs = append(substitutionArgs, key+"="+value)
-	}
-
-	name, err := shlex.ProcessWord(name, substitutionArgs)
-	if err != nil {
-		return nil, err
-	}
-
-	var localOnly bool
-	if stage, ok := b.buildStages.getByName(name); ok {
-		name = stage.ImageID()
-		localOnly = true
-	}
-
-	// Windows cannot support a container with no base image unless it is LCOW.
-	if name == api.NoBaseImageSpecifier {
-		if runtime.GOOS == "windows" {
-			if b.platform == "windows" || (b.platform != "windows" && !system.LCOWSupported()) {
-				return nil, errors.New("Windows does not support FROM scratch")
-			}
-		}
-		return scratchImage, nil
-	}
-	imageMount, err := b.imageSources.Get(name, localOnly)
-	if err != nil {
-		return nil, err
-	}
-	return imageMount.Image(), nil
-}
-
-func processOnBuild(req dispatchRequest) error {
-	dispatchState := req.state
-	// Process ONBUILD triggers if they exist
-	if nTriggers := len(dispatchState.runConfig.OnBuild); nTriggers != 0 {
-		word := "trigger"
-		if nTriggers > 1 {
-			word = "triggers"
-		}
-		fmt.Fprintf(req.builder.Stderr, "# Executing %d build %s...\n", nTriggers, word)
-	}
-
-	// Copy the ONBUILD triggers, and remove them from the config, since the config will be committed.
-	onBuildTriggers := dispatchState.runConfig.OnBuild
-	dispatchState.runConfig.OnBuild = []string{}
-
-	// Reset stdin settings as all build actions run without stdin
-	dispatchState.runConfig.OpenStdin = false
-	dispatchState.runConfig.StdinOnce = false
-
-	// parse the ONBUILD triggers by invoking the parser
-	for _, step := range onBuildTriggers {
-		dockerfile, err := parser.Parse(strings.NewReader(step))
+	fmt.Fprintln(d.builder.Stdout)
+	for _, trigger := range triggers {
+		d.state.updateRunConfig()
+		ast, err := parser.Parse(strings.NewReader(trigger))
 		if err != nil {
 			return err
 		}
-
-		for _, n := range dockerfile.AST.Children {
-			if err := checkDispatch(n); err != nil {
-				return err
-			}
-
-			upperCasedCmd := strings.ToUpper(n.Value)
-			switch upperCasedCmd {
-			case "ONBUILD":
-				return errors.New("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
-			case "MAINTAINER", "FROM":
-				return errors.Errorf("%s isn't allowed as an ONBUILD trigger", upperCasedCmd)
-			}
+		if len(ast.AST.Children) != 1 {
+			return errors.New("onbuild trigger should be a single expression")
 		}
-
-		if _, err := dispatchFromDockerfile(req.builder, dockerfile, dispatchState, req.source); err != nil {
+		cmd, err := instructions.ParseCommand(ast.AST.Children[0])
+		if err != nil {
+			if instructions.IsUnknownInstruction(err) {
+				buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
+			}
+			return err
+		}
+		err = dispatch(d, cmd)
+		if err != nil {
 			return err
 		}
 	}
 	return nil
 }
 
-// ONBUILD RUN echo yo
-//
-// ONBUILD triggers run when the image is used in a FROM statement.
-//
-// ONBUILD handling has a lot of special-case functionality, the heading in
-// evaluator.go and comments around dispatch() in the same file explain the
-// special cases. search for 'OnBuild' in internals.go for additional special
-// cases.
-//
-func onbuild(req dispatchRequest) error {
-	if len(req.args) == 0 {
-		return errAtLeastOneArgument("ONBUILD")
+// scratchImage is used as a token for the empty base image. It uses buildStage
+// as a convenient implementation of builder.Image, but is not actually a
+// buildStage.
+var scratchImage builder.Image = &image.Image{}
+
+func (d *dispatchRequest) getExpandedImageName(shlex *ShellLex, name string) (string, error) {
+	substitutionArgs := []string{}
+	for key, value := range d.state.buildArgs.GetAllMeta() {
+		substitutionArgs = append(substitutionArgs, key+"="+value)
 	}
 
-	if err := req.flags.Parse(); err != nil {
-		return err
+	name, err := shlex.ProcessWord(name, substitutionArgs)
+	if err != nil {
+		return "", err
+	}
+	return name, nil
+}
+func (d *dispatchRequest) getImageOrStage(name string) (builder.Image, error) {
+	var localOnly bool
+	if im, ok := d.stages.getByName(name); ok {
+		name = im.Image
+		localOnly = true
 	}
 
-	triggerInstruction := strings.ToUpper(strings.TrimSpace(req.args[0]))
-	switch triggerInstruction {
-	case "ONBUILD":
-		return errors.New("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
-	case "MAINTAINER", "FROM":
-		return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", triggerInstruction)
+	// Windows cannot support a container with no base image unless it is LCOW.
+	if name == api.NoBaseImageSpecifier {
+		if runtime.GOOS == "windows" {
+			if d.builder.platform == "windows" || (d.builder.platform != "windows" && !system.LCOWSupported()) {
+				return nil, errors.New("Windows does not support FROM scratch")
+			}
+		}
+		return scratchImage, nil
 	}
+	imageMount, err := d.builder.imageSources.Get(name, localOnly)
+	if err != nil {
+		return nil, err
+	}
+	return imageMount.Image(), nil
+}
+func (d *dispatchRequest) getFromImage(shlex *ShellLex, name string) (builder.Image, error) {
+	name, err := d.getExpandedImageName(shlex, name)
+	if err != nil {
+		return nil, err
+	}
+	return d.getImageOrStage(name)
+}
 
-	runConfig := req.state.runConfig
-	original := regexp.MustCompile(`(?i)^\s*ONBUILD\s*`).ReplaceAllString(req.original, "")
-	runConfig.OnBuild = append(runConfig.OnBuild, original)
-	return req.builder.commit(req.state, "ONBUILD "+original)
+func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error {
+
+	d.state.runConfig.OnBuild = append(d.state.runConfig.OnBuild, c.Expression)
+	return d.builder.commit(d.state, "ONBUILD "+c.Expression)
 }
 
 // WORKDIR /tmp
 //
 // Set the working directory for future RUN/CMD/etc statements.
 //
-func workdir(req dispatchRequest) error {
-	if len(req.args) != 1 {
-		return errExactlyOneArgument("WORKDIR")
-	}
-
-	err := req.flags.Parse()
-	if err != nil {
-		return err
-	}
-
-	runConfig := req.state.runConfig
-	// This is from the Dockerfile and will not necessarily be in platform
-	// specific semantics, hence ensure it is converted.
-	runConfig.WorkingDir, err = normaliseWorkdir(runConfig.WorkingDir, req.args[0])
+func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
+	runConfig := d.state.runConfig
+	var err error
+	runConfig.WorkingDir, err = normalizeWorkdir(d.builder.platform, runConfig.WorkingDir, c.Path)
 	if err != nil {
 		return err
 	}
@@ -396,23 +263,31 @@
 	// This avoids having an unnecessary expensive mount/unmount calls
 	// (on Windows in particular) during each container create.
 	// Prior to 1.13, the mkdir was deferred and not executed at this step.
-	if req.builder.disableCommit {
+	if d.builder.disableCommit {
 		// Don't call back into the daemon if we're going through docker commit --change "WORKDIR /foo".
 		// We've already updated the runConfig and that's enough.
 		return nil
 	}
 
 	comment := "WORKDIR " + runConfig.WorkingDir
-	runConfigWithCommentCmd := copyRunConfig(runConfig, withCmdCommentString(comment, req.builder.platform))
-	containerID, err := req.builder.probeAndCreate(req.state, runConfigWithCommentCmd)
+	runConfigWithCommentCmd := copyRunConfig(runConfig, withCmdCommentString(comment, d.builder.platform))
+	containerID, err := d.builder.probeAndCreate(d.state, runConfigWithCommentCmd)
 	if err != nil || containerID == "" {
 		return err
 	}
-	if err := req.builder.docker.ContainerCreateWorkdir(containerID); err != nil {
+	if err := d.builder.docker.ContainerCreateWorkdir(containerID); err != nil {
 		return err
 	}
 
-	return req.builder.commitContainer(req.state, containerID, runConfigWithCommentCmd)
+	return d.builder.commitContainer(d.state, containerID, runConfigWithCommentCmd)
+}
+
+func resolveCmdLine(cmd instructions.ShellDependantCmdLine, runConfig *container.Config, platform string) []string {
+	result := cmd.CmdLine
+	if cmd.PrependShell && result != nil {
+		result = append(getShell(runConfig, platform), result...)
+	}
+	return result
 }
 
 // RUN some command yo
@@ -425,32 +300,21 @@
 // RUN echo hi          # cmd /S /C echo hi   (Windows)
 // RUN [ "echo", "hi" ] # echo hi
 //
-func run(req dispatchRequest) error {
-	if !req.state.hasFromImage() {
-		return errors.New("Please provide a source image with `from` prior to run")
-	}
+func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
 
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	stateRunConfig := req.state.runConfig
-	args := handleJSONArgs(req.args, req.attributes)
-	if !req.attributes["json"] {
-		args = append(getShell(stateRunConfig, req.builder.platform), args...)
-	}
-	cmdFromArgs := strslice.StrSlice(args)
-	buildArgs := req.builder.buildArgs.FilterAllowed(stateRunConfig.Env)
+	stateRunConfig := d.state.runConfig
+	cmdFromArgs := resolveCmdLine(c.ShellDependantCmdLine, stateRunConfig, d.builder.platform)
+	buildArgs := d.state.buildArgs.FilterAllowed(stateRunConfig.Env)
 
 	saveCmd := cmdFromArgs
 	if len(buildArgs) > 0 {
-		saveCmd = prependEnvOnCmd(req.builder.buildArgs, buildArgs, cmdFromArgs)
+		saveCmd = prependEnvOnCmd(d.state.buildArgs, buildArgs, cmdFromArgs)
 	}
 
 	runConfigForCacheProbe := copyRunConfig(stateRunConfig,
 		withCmd(saveCmd),
 		withEntrypointOverride(saveCmd, nil))
-	hit, err := req.builder.probeCache(req.state, runConfigForCacheProbe)
+	hit, err := d.builder.probeCache(d.state, runConfigForCacheProbe)
 	if err != nil || hit {
 		return err
 	}
@@ -464,11 +328,11 @@
 	runConfig.ArgsEscaped = true
 
 	logrus.Debugf("[BUILDER] Command to be executed: %v", runConfig.Cmd)
-	cID, err := req.builder.create(runConfig)
+	cID, err := d.builder.create(runConfig)
 	if err != nil {
 		return err
 	}
-	if err := req.builder.containerManager.Run(req.builder.clientCtx, cID, req.builder.Stdout, req.builder.Stderr); err != nil {
+	if err := d.builder.containerManager.Run(d.builder.clientCtx, cID, d.builder.Stdout, d.builder.Stderr); err != nil {
 		if err, ok := err.(*statusCodeError); ok {
 			// TODO: change error type, because jsonmessage.JSONError assumes HTTP
 			return &jsonmessage.JSONError{
@@ -481,7 +345,7 @@
 		return err
 	}
 
-	return req.builder.commitContainer(req.state, cID, runConfigForCacheProbe)
+	return d.builder.commitContainer(d.state, cID, runConfigForCacheProbe)
 }
 
 // Derive the command to use for probeCache() and to commit in this container.
@@ -514,139 +378,39 @@
 // Set the default command to run in the container (which may be empty).
 // Argument handling is the same as RUN.
 //
-func cmd(req dispatchRequest) error {
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	runConfig := req.state.runConfig
-	cmdSlice := handleJSONArgs(req.args, req.attributes)
-	if !req.attributes["json"] {
-		cmdSlice = append(getShell(runConfig, req.builder.platform), cmdSlice...)
-	}
-
-	runConfig.Cmd = strslice.StrSlice(cmdSlice)
+func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error {
+	runConfig := d.state.runConfig
+	cmd := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.builder.platform)
+	runConfig.Cmd = cmd
 	// set config as already being escaped, this prevents double escaping on windows
 	runConfig.ArgsEscaped = true
 
-	if err := req.builder.commit(req.state, fmt.Sprintf("CMD %q", cmdSlice)); err != nil {
+	if err := d.builder.commit(d.state, fmt.Sprintf("CMD %q", cmd)); err != nil {
 		return err
 	}
 
-	if len(req.args) != 0 {
-		req.state.cmdSet = true
+	if len(c.ShellDependantCmdLine.CmdLine) != 0 {
+		d.state.cmdSet = true
 	}
 
 	return nil
 }
 
-// parseOptInterval(flag) is the duration of flag.Value, or 0 if
-// empty. An error is reported if the value is given and less than minimum duration.
-func parseOptInterval(f *Flag) (time.Duration, error) {
-	s := f.Value
-	if s == "" {
-		return 0, nil
-	}
-	d, err := time.ParseDuration(s)
-	if err != nil {
-		return 0, err
-	}
-	if d < time.Duration(container.MinimumDuration) {
-		return 0, fmt.Errorf("Interval %#v cannot be less than %s", f.name, container.MinimumDuration)
-	}
-	return d, nil
-}
-
 // HEALTHCHECK foo
 //
 // Set the default healthcheck command to run in the container (which may be empty).
 // Argument handling is the same as RUN.
 //
-func healthcheck(req dispatchRequest) error {
-	if len(req.args) == 0 {
-		return errAtLeastOneArgument("HEALTHCHECK")
+func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand) error {
+	runConfig := d.state.runConfig
+	if runConfig.Healthcheck != nil {
+		oldCmd := runConfig.Healthcheck.Test
+		if len(oldCmd) > 0 && oldCmd[0] != "NONE" {
+			fmt.Fprintf(d.builder.Stdout, "Note: overriding previous HEALTHCHECK: %v\n", oldCmd)
+		}
 	}
-	runConfig := req.state.runConfig
-	typ := strings.ToUpper(req.args[0])
-	args := req.args[1:]
-	if typ == "NONE" {
-		if len(args) != 0 {
-			return errors.New("HEALTHCHECK NONE takes no arguments")
-		}
-		test := strslice.StrSlice{typ}
-		runConfig.Healthcheck = &container.HealthConfig{
-			Test: test,
-		}
-	} else {
-		if runConfig.Healthcheck != nil {
-			oldCmd := runConfig.Healthcheck.Test
-			if len(oldCmd) > 0 && oldCmd[0] != "NONE" {
-				fmt.Fprintf(req.builder.Stdout, "Note: overriding previous HEALTHCHECK: %v\n", oldCmd)
-			}
-		}
-
-		healthcheck := container.HealthConfig{}
-
-		flInterval := req.flags.AddString("interval", "")
-		flTimeout := req.flags.AddString("timeout", "")
-		flStartPeriod := req.flags.AddString("start-period", "")
-		flRetries := req.flags.AddString("retries", "")
-
-		if err := req.flags.Parse(); err != nil {
-			return err
-		}
-
-		switch typ {
-		case "CMD":
-			cmdSlice := handleJSONArgs(args, req.attributes)
-			if len(cmdSlice) == 0 {
-				return errors.New("Missing command after HEALTHCHECK CMD")
-			}
-
-			if !req.attributes["json"] {
-				typ = "CMD-SHELL"
-			}
-
-			healthcheck.Test = strslice.StrSlice(append([]string{typ}, cmdSlice...))
-		default:
-			return fmt.Errorf("Unknown type %#v in HEALTHCHECK (try CMD)", typ)
-		}
-
-		interval, err := parseOptInterval(flInterval)
-		if err != nil {
-			return err
-		}
-		healthcheck.Interval = interval
-
-		timeout, err := parseOptInterval(flTimeout)
-		if err != nil {
-			return err
-		}
-		healthcheck.Timeout = timeout
-
-		startPeriod, err := parseOptInterval(flStartPeriod)
-		if err != nil {
-			return err
-		}
-		healthcheck.StartPeriod = startPeriod
-
-		if flRetries.Value != "" {
-			retries, err := strconv.ParseInt(flRetries.Value, 10, 32)
-			if err != nil {
-				return err
-			}
-			if retries < 1 {
-				return fmt.Errorf("--retries must be at least 1 (not %d)", retries)
-			}
-			healthcheck.Retries = int(retries)
-		} else {
-			healthcheck.Retries = 0
-		}
-
-		runConfig.Healthcheck = &healthcheck
-	}
-
-	return req.builder.commit(req.state, fmt.Sprintf("HEALTHCHECK %q", runConfig.Healthcheck))
+	runConfig.Healthcheck = c.Health
+	return d.builder.commit(d.state, fmt.Sprintf("HEALTHCHECK %q", runConfig.Healthcheck))
 }
 
 // ENTRYPOINT /usr/sbin/nginx
@@ -657,33 +421,15 @@
 // Handles command processing similar to CMD and RUN, only req.runConfig.Entrypoint
 // is initialized at newBuilder time instead of through argument parsing.
 //
-func entrypoint(req dispatchRequest) error {
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	runConfig := req.state.runConfig
-	parsed := handleJSONArgs(req.args, req.attributes)
-
-	switch {
-	case req.attributes["json"]:
-		// ENTRYPOINT ["echo", "hi"]
-		runConfig.Entrypoint = strslice.StrSlice(parsed)
-	case len(parsed) == 0:
-		// ENTRYPOINT []
-		runConfig.Entrypoint = nil
-	default:
-		// ENTRYPOINT echo hi
-		runConfig.Entrypoint = strslice.StrSlice(append(getShell(runConfig, req.builder.platform), parsed[0]))
-	}
-
-	// when setting the entrypoint if a CMD was not explicitly set then
-	// set the command to nil
-	if !req.state.cmdSet {
+func dispatchEntrypoint(d dispatchRequest, c *instructions.EntrypointCommand) error {
+	runConfig := d.state.runConfig
+	cmd := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.builder.platform)
+	runConfig.Entrypoint = cmd
+	if !d.state.cmdSet {
 		runConfig.Cmd = nil
 	}
 
-	return req.builder.commit(req.state, fmt.Sprintf("ENTRYPOINT %q", runConfig.Entrypoint))
+	return d.builder.commit(d.state, fmt.Sprintf("ENTRYPOINT %q", runConfig.Entrypoint))
 }
 
 // EXPOSE 6667/tcp 7000/tcp
@@ -691,41 +437,33 @@
 // Expose ports for links and port mappings. This all ends up in
 // req.runConfig.ExposedPorts for runconfig.
 //
-func expose(req dispatchRequest) error {
-	portsTab := req.args
-
-	if len(req.args) == 0 {
-		return errAtLeastOneArgument("EXPOSE")
+func dispatchExpose(d dispatchRequest, c *instructions.ExposeCommand, envs []string) error {
+	// custom multi word expansion
+	// expose $FOO with FOO="80 443" is expanded as EXPOSE [80,443]. This is the only command supporting word to words expansion
+	// so the word processing has been de-generalized
+	ports := []string{}
+	for _, p := range c.Ports {
+		ps, err := d.shlex.ProcessWords(p, envs)
+		if err != nil {
+			return err
+		}
+		ports = append(ports, ps...)
 	}
+	c.Ports = ports
 
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	runConfig := req.state.runConfig
-	if runConfig.ExposedPorts == nil {
-		runConfig.ExposedPorts = make(nat.PortSet)
-	}
-
-	ports, _, err := nat.ParsePortSpecs(portsTab)
+	ps, _, err := nat.ParsePortSpecs(ports)
 	if err != nil {
 		return err
 	}
 
-	// instead of using ports directly, we build a list of ports and sort it so
-	// the order is consistent. This prevents cache burst where map ordering
-	// changes between builds
-	portList := make([]string, len(ports))
-	var i int
-	for port := range ports {
-		if _, exists := runConfig.ExposedPorts[port]; !exists {
-			runConfig.ExposedPorts[port] = struct{}{}
-		}
-		portList[i] = string(port)
-		i++
+	if d.state.runConfig.ExposedPorts == nil {
+		d.state.runConfig.ExposedPorts = make(nat.PortSet)
 	}
-	sort.Strings(portList)
-	return req.builder.commit(req.state, "EXPOSE "+strings.Join(portList, " "))
+	for p := range ps {
+		d.state.runConfig.ExposedPorts[p] = struct{}{}
+	}
+
+	return d.builder.commit(d.state, "EXPOSE "+strings.Join(c.Ports, " "))
 }
 
 // USER foo
@@ -733,62 +471,39 @@
 // Set the user to 'foo' for future commands and when running the
 // ENTRYPOINT/CMD at container run time.
 //
-func user(req dispatchRequest) error {
-	if len(req.args) != 1 {
-		return errExactlyOneArgument("USER")
-	}
-
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	req.state.runConfig.User = req.args[0]
-	return req.builder.commit(req.state, fmt.Sprintf("USER %v", req.args))
+func dispatchUser(d dispatchRequest, c *instructions.UserCommand) error {
+	d.state.runConfig.User = c.User
+	return d.builder.commit(d.state, fmt.Sprintf("USER %v", c.User))
 }
 
 // VOLUME /foo
 //
 // Expose the volume /foo for use. Will also accept the JSON array form.
 //
-func volume(req dispatchRequest) error {
-	if len(req.args) == 0 {
-		return errAtLeastOneArgument("VOLUME")
+func dispatchVolume(d dispatchRequest, c *instructions.VolumeCommand) error {
+	if d.state.runConfig.Volumes == nil {
+		d.state.runConfig.Volumes = map[string]struct{}{}
 	}
-
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-
-	runConfig := req.state.runConfig
-	if runConfig.Volumes == nil {
-		runConfig.Volumes = map[string]struct{}{}
-	}
-	for _, v := range req.args {
-		v = strings.TrimSpace(v)
+	for _, v := range c.Volumes {
 		if v == "" {
 			return errors.New("VOLUME specified can not be an empty string")
 		}
-		runConfig.Volumes[v] = struct{}{}
+		d.state.runConfig.Volumes[v] = struct{}{}
 	}
-	return req.builder.commit(req.state, fmt.Sprintf("VOLUME %v", req.args))
+	return d.builder.commit(d.state, fmt.Sprintf("VOLUME %v", c.Volumes))
 }
 
 // STOPSIGNAL signal
 //
 // Set the signal that will be used to kill the container.
-func stopSignal(req dispatchRequest) error {
-	if len(req.args) != 1 {
-		return errExactlyOneArgument("STOPSIGNAL")
-	}
+func dispatchStopSignal(d dispatchRequest, c *instructions.StopSignalCommand) error {
 
-	sig := req.args[0]
-	_, err := signal.ParseSignal(sig)
+	_, err := signal.ParseSignal(c.Signal)
 	if err != nil {
-		return err
+		return validationError{err}
 	}
-
-	req.state.runConfig.StopSignal = sig
-	return req.builder.commit(req.state, fmt.Sprintf("STOPSIGNAL %v", req.args))
+	d.state.runConfig.StopSignal = c.Signal
+	return d.builder.commit(d.state, fmt.Sprintf("STOPSIGNAL %v", c.Signal))
 }
 
 // ARG name[=value]
@@ -796,89 +511,21 @@
 // Adds the variable foo to the trusted list of variables that can be passed
 // to builder using the --build-arg flag for expansion/substitution or passing to 'run'.
 // Dockerfile author may optionally set a default value of this variable.
-func arg(req dispatchRequest) error {
-	if len(req.args) != 1 {
-		return errExactlyOneArgument("ARG")
+func dispatchArg(d dispatchRequest, c *instructions.ArgCommand) error {
+
+	commitStr := "ARG " + c.Key
+	if c.Value != nil {
+		commitStr += "=" + *c.Value
 	}
 
-	var (
-		name       string
-		newValue   string
-		hasDefault bool
-	)
-
-	arg := req.args[0]
-	// 'arg' can just be a name or name-value pair. Note that this is different
-	// from 'env' that handles the split of name and value at the parser level.
-	// The reason for doing it differently for 'arg' is that we support just
-	// defining an arg and not assign it a value (while 'env' always expects a
-	// name-value pair). If possible, it will be good to harmonize the two.
-	if strings.Contains(arg, "=") {
-		parts := strings.SplitN(arg, "=", 2)
-		if len(parts[0]) == 0 {
-			return errBlankCommandNames("ARG")
-		}
-
-		name = parts[0]
-		newValue = parts[1]
-		hasDefault = true
-	} else {
-		name = arg
-		hasDefault = false
-	}
-
-	var value *string
-	if hasDefault {
-		value = &newValue
-	}
-	req.builder.buildArgs.AddArg(name, value)
-
-	// Arg before FROM doesn't add a layer
-	if !req.state.hasFromImage() {
-		req.builder.buildArgs.AddMetaArg(name, value)
-		return nil
-	}
-	return req.builder.commit(req.state, "ARG "+arg)
+	d.state.buildArgs.AddArg(c.Key, c.Value)
+	return d.builder.commit(d.state, commitStr)
 }
 
 // SHELL powershell -command
 //
 // Set the non-default shell to use.
-func shell(req dispatchRequest) error {
-	if err := req.flags.Parse(); err != nil {
-		return err
-	}
-	shellSlice := handleJSONArgs(req.args, req.attributes)
-	switch {
-	case len(shellSlice) == 0:
-		// SHELL []
-		return errAtLeastOneArgument("SHELL")
-	case req.attributes["json"]:
-		// SHELL ["powershell", "-command"]
-		req.state.runConfig.Shell = strslice.StrSlice(shellSlice)
-	default:
-		// SHELL powershell -command - not JSON
-		return errNotJSON("SHELL", req.original)
-	}
-	return req.builder.commit(req.state, fmt.Sprintf("SHELL %v", shellSlice))
-}
-
-func errAtLeastOneArgument(command string) error {
-	return fmt.Errorf("%s requires at least one argument", command)
-}
-
-func errExactlyOneArgument(command string) error {
-	return fmt.Errorf("%s requires exactly one argument", command)
-}
-
-func errAtLeastTwoArguments(command string) error {
-	return fmt.Errorf("%s requires at least two arguments", command)
-}
-
-func errBlankCommandNames(command string) error {
-	return fmt.Errorf("%s names can not be blank", command)
-}
-
-func errTooManyArguments(command string) error {
-	return fmt.Errorf("Bad input to %s, too many arguments", command)
+func dispatchShell(d dispatchRequest, c *instructions.ShellCommand) error {
+	d.state.runConfig.Shell = c.Shell
+	return d.builder.commit(d.state, fmt.Sprintf("SHELL %v", d.state.runConfig.Shell))
 }
diff --git a/builder/dockerfile/dispatchers_test.go b/builder/dockerfile/dispatchers_test.go
index b3672fc..f7f1b1e 100644
--- a/builder/dockerfile/dispatchers_test.go
+++ b/builder/dockerfile/dispatchers_test.go
@@ -1,60 +1,29 @@
 package dockerfile
 
 import (
-	"fmt"
-	"runtime"
-	"testing"
-
 	"bytes"
 	"context"
+	"runtime"
+	"testing"
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/strslice"
 	"github.com/docker/docker/builder"
-	"github.com/docker/docker/builder/dockerfile/parser"
+	"github.com/docker/docker/builder/dockerfile/instructions"
 	"github.com/docker/docker/pkg/system"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/go-connections/nat"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
-type commandWithFunction struct {
-	name     string
-	function func(args []string) error
-}
-
-func withArgs(f dispatcher) func([]string) error {
-	return func(args []string) error {
-		return f(dispatchRequest{args: args})
-	}
-}
-
-func withBuilderAndArgs(builder *Builder, f dispatcher) func([]string) error {
-	return func(args []string) error {
-		return f(defaultDispatchReq(builder, args...))
-	}
-}
-
-func defaultDispatchReq(builder *Builder, args ...string) dispatchRequest {
-	return dispatchRequest{
-		builder: builder,
-		args:    args,
-		flags:   NewBFlags(),
-		shlex:   NewShellLex(parser.DefaultEscapeToken),
-		state:   &dispatchState{runConfig: &container.Config{}},
-	}
-}
-
 func newBuilderWithMockBackend() *Builder {
 	mockBackend := &MockBackend{}
 	ctx := context.Background()
 	b := &Builder{
 		options:       &types.ImageBuildOptions{},
 		docker:        mockBackend,
-		buildArgs:     newBuildArgs(make(map[string]*string)),
 		Stdout:        new(bytes.Buffer),
 		clientCtx:     ctx,
 		disableCommit: true,
@@ -62,137 +31,84 @@
 			Options: &types.ImageBuildOptions{},
 			Backend: mockBackend,
 		}),
-		buildStages:      newBuildStages(),
 		imageProber:      newImageProber(mockBackend, nil, runtime.GOOS, false),
 		containerManager: newContainerManager(mockBackend),
 	}
 	return b
 }
 
-func TestCommandsExactlyOneArgument(t *testing.T) {
-	commands := []commandWithFunction{
-		{"MAINTAINER", withArgs(maintainer)},
-		{"WORKDIR", withArgs(workdir)},
-		{"USER", withArgs(user)},
-		{"STOPSIGNAL", withArgs(stopSignal)},
-	}
-
-	for _, command := range commands {
-		err := command.function([]string{})
-		assert.EqualError(t, err, errExactlyOneArgument(command.name).Error())
-	}
-}
-
-func TestCommandsAtLeastOneArgument(t *testing.T) {
-	commands := []commandWithFunction{
-		{"ENV", withArgs(env)},
-		{"LABEL", withArgs(label)},
-		{"ONBUILD", withArgs(onbuild)},
-		{"HEALTHCHECK", withArgs(healthcheck)},
-		{"EXPOSE", withArgs(expose)},
-		{"VOLUME", withArgs(volume)},
-	}
-
-	for _, command := range commands {
-		err := command.function([]string{})
-		assert.EqualError(t, err, errAtLeastOneArgument(command.name).Error())
-	}
-}
-
-func TestCommandsAtLeastTwoArguments(t *testing.T) {
-	commands := []commandWithFunction{
-		{"ADD", withArgs(add)},
-		{"COPY", withArgs(dispatchCopy)}}
-
-	for _, command := range commands {
-		err := command.function([]string{"arg1"})
-		assert.EqualError(t, err, errAtLeastTwoArguments(command.name).Error())
-	}
-}
-
-func TestCommandsTooManyArguments(t *testing.T) {
-	commands := []commandWithFunction{
-		{"ENV", withArgs(env)},
-		{"LABEL", withArgs(label)}}
-
-	for _, command := range commands {
-		err := command.function([]string{"arg1", "arg2", "arg3"})
-		assert.EqualError(t, err, errTooManyArguments(command.name).Error())
-	}
-}
-
-func TestCommandsBlankNames(t *testing.T) {
-	builder := newBuilderWithMockBackend()
-	commands := []commandWithFunction{
-		{"ENV", withBuilderAndArgs(builder, env)},
-		{"LABEL", withBuilderAndArgs(builder, label)},
-	}
-
-	for _, command := range commands {
-		err := command.function([]string{"", ""})
-		assert.EqualError(t, err, errBlankCommandNames(command.name).Error())
-	}
-}
-
 func TestEnv2Variables(t *testing.T) {
 	b := newBuilderWithMockBackend()
-
-	args := []string{"var1", "val1", "var2", "val2"}
-	req := defaultDispatchReq(b, args...)
-	err := env(req)
+	sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	envCommand := &instructions.EnvCommand{
+		Env: instructions.KeyValuePairs{
+			instructions.KeyValuePair{Key: "var1", Value: "val1"},
+			instructions.KeyValuePair{Key: "var2", Value: "val2"},
+		},
+	}
+	err := dispatch(sb, envCommand)
 	require.NoError(t, err)
 
 	expected := []string{
-		fmt.Sprintf("%s=%s", args[0], args[1]),
-		fmt.Sprintf("%s=%s", args[2], args[3]),
+		"var1=val1",
+		"var2=val2",
 	}
-	assert.Equal(t, expected, req.state.runConfig.Env)
+	assert.Equal(t, expected, sb.state.runConfig.Env)
 }
 
 func TestEnvValueWithExistingRunConfigEnv(t *testing.T) {
 	b := newBuilderWithMockBackend()
-
-	args := []string{"var1", "val1"}
-	req := defaultDispatchReq(b, args...)
-	req.state.runConfig.Env = []string{"var1=old", "var2=fromenv"}
-	err := env(req)
+	sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	sb.state.runConfig.Env = []string{"var1=old", "var2=fromenv"}
+	envCommand := &instructions.EnvCommand{
+		Env: instructions.KeyValuePairs{
+			instructions.KeyValuePair{Key: "var1", Value: "val1"},
+		},
+	}
+	err := dispatch(sb, envCommand)
 	require.NoError(t, err)
-
 	expected := []string{
-		fmt.Sprintf("%s=%s", args[0], args[1]),
+		"var1=val1",
 		"var2=fromenv",
 	}
-	assert.Equal(t, expected, req.state.runConfig.Env)
+	assert.Equal(t, expected, sb.state.runConfig.Env)
 }
 
 func TestMaintainer(t *testing.T) {
 	maintainerEntry := "Some Maintainer <maintainer@example.com>"
-
 	b := newBuilderWithMockBackend()
-	req := defaultDispatchReq(b, maintainerEntry)
-	err := maintainer(req)
+	sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	cmd := &instructions.MaintainerCommand{Maintainer: maintainerEntry}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
-	assert.Equal(t, maintainerEntry, req.state.maintainer)
+	assert.Equal(t, maintainerEntry, sb.state.maintainer)
 }
 
 func TestLabel(t *testing.T) {
 	labelName := "label"
 	labelValue := "value"
 
-	labelEntry := []string{labelName, labelValue}
 	b := newBuilderWithMockBackend()
-	req := defaultDispatchReq(b, labelEntry...)
-	err := label(req)
+	sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	cmd := &instructions.LabelCommand{
+		Labels: instructions.KeyValuePairs{
+			instructions.KeyValuePair{Key: labelName, Value: labelValue},
+		},
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
 
-	require.Contains(t, req.state.runConfig.Labels, labelName)
-	assert.Equal(t, req.state.runConfig.Labels[labelName], labelValue)
+	require.Contains(t, sb.state.runConfig.Labels, labelName)
+	assert.Equal(t, sb.state.runConfig.Labels[labelName], labelValue)
 }
 
 func TestFromScratch(t *testing.T) {
 	b := newBuilderWithMockBackend()
-	req := defaultDispatchReq(b, "scratch")
-	err := from(req)
+	sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	cmd := &instructions.Stage{
+		BaseName: "scratch",
+	}
+	err := initializeStage(sb, cmd)
 
 	if runtime.GOOS == "windows" && !system.LCOWSupported() {
 		assert.EqualError(t, err, "Windows does not support FROM scratch")
@@ -200,14 +116,14 @@
 	}
 
 	require.NoError(t, err)
-	assert.True(t, req.state.hasFromImage())
-	assert.Equal(t, "", req.state.imageID)
+	assert.True(t, sb.state.hasFromImage())
+	assert.Equal(t, "", sb.state.imageID)
 	// Windows does not set the default path. TODO @jhowardmsft LCOW support. This will need revisiting as we get further into the implementation
 	expected := "PATH=" + system.DefaultPathEnv(runtime.GOOS)
 	if runtime.GOOS == "windows" {
 		expected = ""
 	}
-	assert.Equal(t, []string{expected}, req.state.runConfig.Env)
+	assert.Equal(t, []string{expected}, sb.state.runConfig.Env)
 }
 
 func TestFromWithArg(t *testing.T) {
@@ -219,16 +135,27 @@
 	}
 	b := newBuilderWithMockBackend()
 	b.docker.(*MockBackend).getImageFunc = getImage
+	args := newBuildArgs(make(map[string]*string))
 
-	require.NoError(t, arg(defaultDispatchReq(b, "THETAG="+tag)))
-	req := defaultDispatchReq(b, "alpine${THETAG}")
-	err := from(req)
+	val := "sometag"
+	metaArg := instructions.ArgCommand{
+		Key:   "THETAG",
+		Value: &val,
+	}
+	cmd := &instructions.Stage{
+		BaseName: "alpine:${THETAG}",
+	}
+	err := processMetaArg(metaArg, NewShellLex('\\'), args)
 
+	sb := newDispatchRequest(b, '\\', nil, args, newStagesBuildResults())
 	require.NoError(t, err)
-	assert.Equal(t, expected, req.state.imageID)
-	assert.Equal(t, expected, req.state.baseImage.ImageID())
-	assert.Len(t, b.buildArgs.GetAllAllowed(), 0)
-	assert.Len(t, b.buildArgs.GetAllMeta(), 1)
+	err = initializeStage(sb, cmd)
+	require.NoError(t, err)
+
+	assert.Equal(t, expected, sb.state.imageID)
+	assert.Equal(t, expected, sb.state.baseImage.ImageID())
+	assert.Len(t, sb.state.buildArgs.GetAllAllowed(), 0)
+	assert.Len(t, sb.state.buildArgs.GetAllMeta(), 1)
 }
 
 func TestFromWithUndefinedArg(t *testing.T) {
@@ -240,74 +167,74 @@
 	}
 	b := newBuilderWithMockBackend()
 	b.docker.(*MockBackend).getImageFunc = getImage
+	sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+
 	b.options.BuildArgs = map[string]*string{"THETAG": &tag}
 
-	req := defaultDispatchReq(b, "alpine${THETAG}")
-	err := from(req)
+	cmd := &instructions.Stage{
+		BaseName: "alpine${THETAG}",
+	}
+	err := initializeStage(sb, cmd)
 	require.NoError(t, err)
-	assert.Equal(t, expected, req.state.imageID)
+	assert.Equal(t, expected, sb.state.imageID)
 }
 
-func TestFromMultiStageWithScratchNamedStage(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("Windows does not support scratch")
-	}
+func TestFromMultiStageWithNamedStage(t *testing.T) {
 	b := newBuilderWithMockBackend()
-	req := defaultDispatchReq(b, "scratch", "AS", "base")
-
-	require.NoError(t, from(req))
-	assert.True(t, req.state.hasFromImage())
-
-	req.args = []string{"base"}
-	require.NoError(t, from(req))
-	assert.True(t, req.state.hasFromImage())
-}
-
-func TestOnbuildIllegalTriggers(t *testing.T) {
-	triggers := []struct{ command, expectedError string }{
-		{"ONBUILD", "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed"},
-		{"MAINTAINER", "MAINTAINER isn't allowed as an ONBUILD trigger"},
-		{"FROM", "FROM isn't allowed as an ONBUILD trigger"}}
-
-	for _, trigger := range triggers {
-		b := newBuilderWithMockBackend()
-
-		err := onbuild(defaultDispatchReq(b, trigger.command))
-		testutil.ErrorContains(t, err, trigger.expectedError)
-	}
+	firstFrom := &instructions.Stage{BaseName: "someimg", Name: "base"}
+	secondFrom := &instructions.Stage{BaseName: "base"}
+	previousResults := newStagesBuildResults()
+	firstSB := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), previousResults)
+	secondSB := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), previousResults)
+	err := initializeStage(firstSB, firstFrom)
+	require.NoError(t, err)
+	assert.True(t, firstSB.state.hasFromImage())
+	previousResults.indexed["base"] = firstSB.state.runConfig
+	previousResults.flat = append(previousResults.flat, firstSB.state.runConfig)
+	err = initializeStage(secondSB, secondFrom)
+	require.NoError(t, err)
+	assert.True(t, secondSB.state.hasFromImage())
 }
 
 func TestOnbuild(t *testing.T) {
 	b := newBuilderWithMockBackend()
-
-	req := defaultDispatchReq(b, "ADD", ".", "/app/src")
-	req.original = "ONBUILD ADD . /app/src"
-	req.state.runConfig = &container.Config{}
-
-	err := onbuild(req)
+	sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	cmd := &instructions.OnbuildCommand{
+		Expression: "ADD . /app/src",
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
-	assert.Equal(t, "ADD . /app/src", req.state.runConfig.OnBuild[0])
+	assert.Equal(t, "ADD . /app/src", sb.state.runConfig.OnBuild[0])
 }
 
 func TestWorkdir(t *testing.T) {
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 	workingDir := "/app"
 	if runtime.GOOS == "windows" {
-		workingDir = "C:\app"
+		workingDir = "C:\\app"
+	}
+	cmd := &instructions.WorkdirCommand{
+		Path: workingDir,
 	}
 
-	req := defaultDispatchReq(b, workingDir)
-	err := workdir(req)
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
-	assert.Equal(t, workingDir, req.state.runConfig.WorkingDir)
+	assert.Equal(t, workingDir, sb.state.runConfig.WorkingDir)
 }
 
 func TestCmd(t *testing.T) {
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 	command := "./executable"
 
-	req := defaultDispatchReq(b, command)
-	err := cmd(req)
+	cmd := &instructions.CmdCommand{
+		ShellDependantCmdLine: instructions.ShellDependantCmdLine{
+			CmdLine:      strslice.StrSlice{command},
+			PrependShell: true,
+		},
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
 
 	var expectedCommand strslice.StrSlice
@@ -317,42 +244,56 @@
 		expectedCommand = strslice.StrSlice(append([]string{"/bin/sh"}, "-c", command))
 	}
 
-	assert.Equal(t, expectedCommand, req.state.runConfig.Cmd)
-	assert.True(t, req.state.cmdSet)
+	assert.Equal(t, expectedCommand, sb.state.runConfig.Cmd)
+	assert.True(t, sb.state.cmdSet)
 }
 
 func TestHealthcheckNone(t *testing.T) {
 	b := newBuilderWithMockBackend()
-
-	req := defaultDispatchReq(b, "NONE")
-	err := healthcheck(req)
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	cmd := &instructions.HealthCheckCommand{
+		Health: &container.HealthConfig{
+			Test: []string{"NONE"},
+		},
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
 
-	require.NotNil(t, req.state.runConfig.Healthcheck)
-	assert.Equal(t, []string{"NONE"}, req.state.runConfig.Healthcheck.Test)
+	require.NotNil(t, sb.state.runConfig.Healthcheck)
+	assert.Equal(t, []string{"NONE"}, sb.state.runConfig.Healthcheck.Test)
 }
 
 func TestHealthcheckCmd(t *testing.T) {
-	b := newBuilderWithMockBackend()
 
-	args := []string{"CMD", "curl", "-f", "http://localhost/", "||", "exit", "1"}
-	req := defaultDispatchReq(b, args...)
-	err := healthcheck(req)
+	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	expectedTest := []string{"CMD-SHELL", "curl -f http://localhost/ || exit 1"}
+	cmd := &instructions.HealthCheckCommand{
+		Health: &container.HealthConfig{
+			Test: expectedTest,
+		},
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
 
-	require.NotNil(t, req.state.runConfig.Healthcheck)
-	expectedTest := []string{"CMD-SHELL", "curl -f http://localhost/ || exit 1"}
-	assert.Equal(t, expectedTest, req.state.runConfig.Healthcheck.Test)
+	require.NotNil(t, sb.state.runConfig.Healthcheck)
+	assert.Equal(t, expectedTest, sb.state.runConfig.Healthcheck.Test)
 }
 
 func TestEntrypoint(t *testing.T) {
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 	entrypointCmd := "/usr/sbin/nginx"
 
-	req := defaultDispatchReq(b, entrypointCmd)
-	err := entrypoint(req)
+	cmd := &instructions.EntrypointCommand{
+		ShellDependantCmdLine: instructions.ShellDependantCmdLine{
+			CmdLine:      strslice.StrSlice{entrypointCmd},
+			PrependShell: true,
+		},
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
-	require.NotNil(t, req.state.runConfig.Entrypoint)
+	require.NotNil(t, sb.state.runConfig.Entrypoint)
 
 	var expectedEntrypoint strslice.StrSlice
 	if runtime.GOOS == "windows" {
@@ -360,99 +301,99 @@
 	} else {
 		expectedEntrypoint = strslice.StrSlice(append([]string{"/bin/sh"}, "-c", entrypointCmd))
 	}
-	assert.Equal(t, expectedEntrypoint, req.state.runConfig.Entrypoint)
+	assert.Equal(t, expectedEntrypoint, sb.state.runConfig.Entrypoint)
 }
 
 func TestExpose(t *testing.T) {
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 
 	exposedPort := "80"
-	req := defaultDispatchReq(b, exposedPort)
-	err := expose(req)
+	cmd := &instructions.ExposeCommand{
+		Ports: []string{exposedPort},
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
 
-	require.NotNil(t, req.state.runConfig.ExposedPorts)
-	require.Len(t, req.state.runConfig.ExposedPorts, 1)
+	require.NotNil(t, sb.state.runConfig.ExposedPorts)
+	require.Len(t, sb.state.runConfig.ExposedPorts, 1)
 
 	portsMapping, err := nat.ParsePortSpec(exposedPort)
 	require.NoError(t, err)
-	assert.Contains(t, req.state.runConfig.ExposedPorts, portsMapping[0].Port)
+	assert.Contains(t, sb.state.runConfig.ExposedPorts, portsMapping[0].Port)
 }
 
 func TestUser(t *testing.T) {
 	b := newBuilderWithMockBackend()
-	userCommand := "foo"
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 
-	req := defaultDispatchReq(b, userCommand)
-	err := user(req)
+	cmd := &instructions.UserCommand{
+		User: "test",
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
-	assert.Equal(t, userCommand, req.state.runConfig.User)
+	assert.Equal(t, "test", sb.state.runConfig.User)
 }
 
 func TestVolume(t *testing.T) {
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 
 	exposedVolume := "/foo"
 
-	req := defaultDispatchReq(b, exposedVolume)
-	err := volume(req)
+	cmd := &instructions.VolumeCommand{
+		Volumes: []string{exposedVolume},
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
-
-	require.NotNil(t, req.state.runConfig.Volumes)
-	assert.Len(t, req.state.runConfig.Volumes, 1)
-	assert.Contains(t, req.state.runConfig.Volumes, exposedVolume)
+	require.NotNil(t, sb.state.runConfig.Volumes)
+	assert.Len(t, sb.state.runConfig.Volumes, 1)
+	assert.Contains(t, sb.state.runConfig.Volumes, exposedVolume)
 }
 
 func TestStopSignal(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("Windows does not support stopsignal")
+		return
+	}
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 	signal := "SIGKILL"
 
-	req := defaultDispatchReq(b, signal)
-	err := stopSignal(req)
+	cmd := &instructions.StopSignalCommand{
+		Signal: signal,
+	}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
-	assert.Equal(t, signal, req.state.runConfig.StopSignal)
+	assert.Equal(t, signal, sb.state.runConfig.StopSignal)
 }
 
 func TestArg(t *testing.T) {
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 
 	argName := "foo"
 	argVal := "bar"
-	argDef := fmt.Sprintf("%s=%s", argName, argVal)
-
-	err := arg(defaultDispatchReq(b, argDef))
+	cmd := &instructions.ArgCommand{Key: argName, Value: &argVal}
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
 
 	expected := map[string]string{argName: argVal}
-	assert.Equal(t, expected, b.buildArgs.GetAllAllowed())
+	assert.Equal(t, expected, sb.state.buildArgs.GetAllAllowed())
 }
 
 func TestShell(t *testing.T) {
 	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
 
 	shellCmd := "powershell"
-	req := defaultDispatchReq(b, shellCmd)
-	req.attributes = map[string]bool{"json": true}
+	cmd := &instructions.ShellCommand{Shell: strslice.StrSlice{shellCmd}}
 
-	err := shell(req)
+	err := dispatch(sb, cmd)
 	require.NoError(t, err)
 
 	expectedShell := strslice.StrSlice([]string{shellCmd})
-	assert.Equal(t, expectedShell, req.state.runConfig.Shell)
-}
-
-func TestParseOptInterval(t *testing.T) {
-	flInterval := &Flag{
-		name:     "interval",
-		flagType: stringType,
-		Value:    "50ns",
-	}
-	_, err := parseOptInterval(flInterval)
-	testutil.ErrorContains(t, err, "cannot be less than 1ms")
-
-	flInterval.Value = "1ms"
-	_, err = parseOptInterval(flInterval)
-	require.NoError(t, err)
+	assert.Equal(t, expectedShell, sb.state.runConfig.Shell)
 }
 
 func TestPrependEnvOnCmd(t *testing.T) {
@@ -469,8 +410,10 @@
 
 func TestRunWithBuildArgs(t *testing.T) {
 	b := newBuilderWithMockBackend()
-	b.buildArgs.argsFromOptions["HTTP_PROXY"] = strPtr("FOO")
+	args := newBuildArgs(make(map[string]*string))
+	args.argsFromOptions["HTTP_PROXY"] = strPtr("FOO")
 	b.disableCommit = false
+	sb := newDispatchRequest(b, '`', nil, args, newStagesBuildResults())
 
 	runConfig := &container.Config{}
 	origCmd := strslice.StrSlice([]string{"cmd", "in", "from", "image"})
@@ -512,14 +455,18 @@
 		assert.Equal(t, strslice.StrSlice(nil), cfg.Config.Entrypoint)
 		return "", nil
 	}
-
-	req := defaultDispatchReq(b, "abcdef")
-	require.NoError(t, from(req))
-	b.buildArgs.AddArg("one", strPtr("two"))
-
-	req.args = []string{"echo foo"}
-	require.NoError(t, run(req))
+	from := &instructions.Stage{BaseName: "abcdef"}
+	err := initializeStage(sb, from)
+	require.NoError(t, err)
+	sb.state.buildArgs.AddArg("one", strPtr("two"))
+	run := &instructions.RunCommand{
+		ShellDependantCmdLine: instructions.ShellDependantCmdLine{
+			CmdLine:      strslice.StrSlice{"echo foo"},
+			PrependShell: true,
+		},
+	}
+	require.NoError(t, dispatch(sb, run))
 
 	// Check that runConfig.Cmd has not been modified by run
-	assert.Equal(t, origCmd, req.state.runConfig.Cmd)
+	assert.Equal(t, origCmd, sb.state.runConfig.Cmd)
 }
diff --git a/builder/dockerfile/dispatchers_unix.go b/builder/dockerfile/dispatchers_unix.go
index 62ee371..6f0d581 100644
--- a/builder/dockerfile/dispatchers_unix.go
+++ b/builder/dockerfile/dispatchers_unix.go
@@ -4,16 +4,15 @@
 
 import (
 	"errors"
-	"fmt"
 	"os"
 	"path/filepath"
 )
 
-// normaliseWorkdir normalises a user requested working directory in a
+// normalizeWorkdir normalizes a user requested working directory in a
 // platform semantically consistent way.
-func normaliseWorkdir(current string, requested string) (string, error) {
+func normalizeWorkdir(_ string, current string, requested string) (string, error) {
 	if requested == "" {
-		return "", errors.New("cannot normalise nothing")
+		return "", errors.New("cannot normalize nothing")
 	}
 	current = filepath.FromSlash(current)
 	requested = filepath.FromSlash(requested)
@@ -23,10 +22,6 @@
 	return requested, nil
 }
 
-func errNotJSON(command, _ string) error {
-	return fmt.Errorf("%s requires the arguments to be in JSON form", command)
-}
-
 // equalEnvKeys compare two strings and returns true if they are equal. On
 // Windows this comparison is case insensitive.
 func equalEnvKeys(from, to string) bool {
diff --git a/builder/dockerfile/dispatchers_unix_test.go b/builder/dockerfile/dispatchers_unix_test.go
index 4aae6b4..053a38f 100644
--- a/builder/dockerfile/dispatchers_unix_test.go
+++ b/builder/dockerfile/dispatchers_unix_test.go
@@ -3,12 +3,13 @@
 package dockerfile
 
 import (
+	"runtime"
 	"testing"
 )
 
-func TestNormaliseWorkdir(t *testing.T) {
+func TestNormalizeWorkdir(t *testing.T) {
 	testCases := []struct{ current, requested, expected, expectedError string }{
-		{``, ``, ``, `cannot normalise nothing`},
+		{``, ``, ``, `cannot normalize nothing`},
 		{``, `foo`, `/foo`, ``},
 		{``, `/foo`, `/foo`, ``},
 		{`/foo`, `bar`, `/foo/bar`, ``},
@@ -16,18 +17,18 @@
 	}
 
 	for _, test := range testCases {
-		normalised, err := normaliseWorkdir(test.current, test.requested)
+		normalized, err := normalizeWorkdir(runtime.GOOS, test.current, test.requested)
 
 		if test.expectedError != "" && err == nil {
-			t.Fatalf("NormaliseWorkdir should return an error %s, got nil", test.expectedError)
+			t.Fatalf("NormalizeWorkdir should return an error %s, got nil", test.expectedError)
 		}
 
 		if test.expectedError != "" && err.Error() != test.expectedError {
-			t.Fatalf("NormaliseWorkdir returned wrong error. Expected %s, got %s", test.expectedError, err.Error())
+			t.Fatalf("NormalizeWorkdir returned wrong error. Expected %s, got %s", test.expectedError, err.Error())
 		}
 
-		if normalised != test.expected {
-			t.Fatalf("NormaliseWorkdir error. Expected %s for current %s and requested %s, got %s", test.expected, test.current, test.requested, normalised)
+		if normalized != test.expected {
+			t.Fatalf("NormalizeWorkdir error. Expected %s for current %s and requested %s, got %s", test.expected, test.current, test.requested, normalized)
 		}
 	}
 }
diff --git a/builder/dockerfile/dispatchers_windows.go b/builder/dockerfile/dispatchers_windows.go
index 71f7c92..8f6eaac 100644
--- a/builder/dockerfile/dispatchers_windows.go
+++ b/builder/dockerfile/dispatchers_windows.go
@@ -4,6 +4,7 @@
 	"errors"
 	"fmt"
 	"os"
+	"path"
 	"path/filepath"
 	"regexp"
 	"strings"
@@ -13,11 +14,37 @@
 
 var pattern = regexp.MustCompile(`^[a-zA-Z]:\.$`)
 
-// normaliseWorkdir normalises a user requested working directory in a
+// normalizeWorkdir normalizes a user requested working directory in a
 // platform semantically consistent way.
-func normaliseWorkdir(current string, requested string) (string, error) {
+func normalizeWorkdir(platform string, current string, requested string) (string, error) {
+	if platform == "" {
+		platform = "windows"
+	}
+	if platform == "windows" {
+		return normalizeWorkdirWindows(current, requested)
+	}
+	return normalizeWorkdirUnix(current, requested)
+}
+
+// normalizeWorkdirUnix normalizes a user requested working directory in a
+// platform semantically consistent way.
+func normalizeWorkdirUnix(current string, requested string) (string, error) {
 	if requested == "" {
-		return "", errors.New("cannot normalise nothing")
+		return "", errors.New("cannot normalize nothing")
+	}
+	current = strings.Replace(current, string(os.PathSeparator), "/", -1)
+	requested = strings.Replace(requested, string(os.PathSeparator), "/", -1)
+	if !path.IsAbs(requested) {
+		return path.Join(`/`, current, requested), nil
+	}
+	return requested, nil
+}
+
+// normalizeWorkdirWindows normalizes a user requested working directory in a
+// platform semantically consistent way.
+func normalizeWorkdirWindows(current string, requested string) (string, error) {
+	if requested == "" {
+		return "", errors.New("cannot normalize nothing")
 	}
 
 	// `filepath.Clean` will replace "" with "." so skip in that case
@@ -67,25 +94,6 @@
 	return (strings.ToUpper(string(requested[0])) + requested[1:]), nil
 }
 
-func errNotJSON(command, original string) error {
-	// For Windows users, give a hint if it looks like it might contain
-	// a path which hasn't been escaped such as ["c:\windows\system32\prog.exe", "-param"],
-	// as JSON must be escaped. Unfortunate...
-	//
-	// Specifically looking for quote-driveletter-colon-backslash, there's no
-	// double backslash and a [] pair. No, this is not perfect, but it doesn't
-	// have to be. It's simply a hint to make life a little easier.
-	extra := ""
-	original = filepath.FromSlash(strings.ToLower(strings.Replace(strings.ToLower(original), strings.ToLower(command)+" ", "", -1)))
-	if len(regexp.MustCompile(`"[a-z]:\\.*`).FindStringSubmatch(original)) > 0 &&
-		!strings.Contains(original, `\\`) &&
-		strings.Contains(original, "[") &&
-		strings.Contains(original, "]") {
-		extra = fmt.Sprintf(`. It looks like '%s' includes a file path without an escaped back-slash. JSON requires back-slashes to be escaped such as ["c:\\path\\to\\file.exe", "/parameter"]`, original)
-	}
-	return fmt.Errorf("%s requires the arguments to be in JSON form%s", command, extra)
-}
-
 // equalEnvKeys compare two strings and returns true if they are equal. On
 // Windows this comparison is case insensitive.
 func equalEnvKeys(from, to string) bool {
diff --git a/builder/dockerfile/dispatchers_windows_test.go b/builder/dockerfile/dispatchers_windows_test.go
index 3319c06..cb0b544 100644
--- a/builder/dockerfile/dispatchers_windows_test.go
+++ b/builder/dockerfile/dispatchers_windows_test.go
@@ -4,37 +4,43 @@
 
 import "testing"
 
-func TestNormaliseWorkdir(t *testing.T) {
-	tests := []struct{ current, requested, expected, etext string }{
-		{``, ``, ``, `cannot normalise nothing`},
-		{``, `C:`, ``, `C:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
-		{``, `C:.`, ``, `C:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
-		{`c:`, `\a`, ``, `c:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
-		{`c:.`, `\a`, ``, `c:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
-		{``, `a`, `C:\a`, ``},
-		{``, `c:\foo`, `C:\foo`, ``},
-		{``, `c:\\foo`, `C:\foo`, ``},
-		{``, `\foo`, `C:\foo`, ``},
-		{``, `\\foo`, `C:\foo`, ``},
-		{``, `/foo`, `C:\foo`, ``},
-		{``, `C:/foo`, `C:\foo`, ``},
-		{`C:\foo`, `bar`, `C:\foo\bar`, ``},
-		{`C:\foo`, `/bar`, `C:\bar`, ``},
-		{`C:\foo`, `\bar`, `C:\bar`, ``},
+func TestNormalizeWorkdir(t *testing.T) {
+	tests := []struct{ platform, current, requested, expected, etext string }{
+		{"windows", ``, ``, ``, `cannot normalize nothing`},
+		{"windows", ``, `C:`, ``, `C:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
+		{"windows", ``, `C:.`, ``, `C:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
+		{"windows", `c:`, `\a`, ``, `c:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
+		{"windows", `c:.`, `\a`, ``, `c:. is not a directory. If you are specifying a drive letter, please add a trailing '\'`},
+		{"windows", ``, `a`, `C:\a`, ``},
+		{"windows", ``, `c:\foo`, `C:\foo`, ``},
+		{"windows", ``, `c:\\foo`, `C:\foo`, ``},
+		{"windows", ``, `\foo`, `C:\foo`, ``},
+		{"windows", ``, `\\foo`, `C:\foo`, ``},
+		{"windows", ``, `/foo`, `C:\foo`, ``},
+		{"windows", ``, `C:/foo`, `C:\foo`, ``},
+		{"windows", `C:\foo`, `bar`, `C:\foo\bar`, ``},
+		{"windows", `C:\foo`, `/bar`, `C:\bar`, ``},
+		{"windows", `C:\foo`, `\bar`, `C:\bar`, ``},
+		{"linux", ``, ``, ``, `cannot normalize nothing`},
+		{"linux", ``, `foo`, `/foo`, ``},
+		{"linux", ``, `/foo`, `/foo`, ``},
+		{"linux", `/foo`, `bar`, `/foo/bar`, ``},
+		{"linux", `/foo`, `/bar`, `/bar`, ``},
+		{"linux", `\a`, `b\c`, `/a/b/c`, ``},
 	}
 	for _, i := range tests {
-		r, e := normaliseWorkdir(i.current, i.requested)
+		r, e := normalizeWorkdir(i.platform, i.current, i.requested)
 
 		if i.etext != "" && e == nil {
-			t.Fatalf("TestNormaliseWorkingDir Expected error %s for '%s' '%s', got no error", i.etext, i.current, i.requested)
+			t.Fatalf("TestNormalizeWorkingDir Expected error %s for '%s' '%s', got no error", i.etext, i.current, i.requested)
 		}
 
 		if i.etext != "" && e.Error() != i.etext {
-			t.Fatalf("TestNormaliseWorkingDir Expected error %s for '%s' '%s', got %s", i.etext, i.current, i.requested, e.Error())
+			t.Fatalf("TestNormalizeWorkingDir Expected error %s for '%s' '%s', got %s", i.etext, i.current, i.requested, e.Error())
 		}
 
 		if r != i.expected {
-			t.Fatalf("TestNormaliseWorkingDir Expected '%s' for '%s' '%s', got '%s'", i.expected, i.current, i.requested, r)
+			t.Fatalf("TestNormalizeWorkingDir Expected '%s' for '%s' '%s', got '%s'", i.expected, i.current, i.requested, r)
 		}
 	}
 }
diff --git a/builder/dockerfile/errors.go b/builder/dockerfile/errors.go
new file mode 100644
index 0000000..25664de
--- /dev/null
+++ b/builder/dockerfile/errors.go
@@ -0,0 +1,15 @@
+package dockerfile
+
+type validationError struct {
+	err error
+}
+
+func (e validationError) Error() string {
+	return e.err.Error()
+}
+
+func (e validationError) InvalidParameter() {}
+
+func (e validationError) Cause() error {
+	return e.err
+}
diff --git a/builder/dockerfile/evaluator.go b/builder/dockerfile/evaluator.go
index ba43159..40af566 100644
--- a/builder/dockerfile/evaluator.go
+++ b/builder/dockerfile/evaluator.go
@@ -20,169 +20,79 @@
 package dockerfile
 
 import (
-	"bytes"
-	"fmt"
+	"reflect"
 	"runtime"
+	"strconv"
 	"strings"
 
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/builder"
-	"github.com/docker/docker/builder/dockerfile/command"
-	"github.com/docker/docker/builder/dockerfile/parser"
+	"github.com/docker/docker/builder/dockerfile/instructions"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/runconfig/opts"
 	"github.com/pkg/errors"
 )
 
-// Environment variable interpolation will happen on these statements only.
-var replaceEnvAllowed = map[string]bool{
-	command.Env:        true,
-	command.Label:      true,
-	command.Add:        true,
-	command.Copy:       true,
-	command.Workdir:    true,
-	command.Expose:     true,
-	command.Volume:     true,
-	command.User:       true,
-	command.StopSignal: true,
-	command.Arg:        true,
-}
-
-// Certain commands are allowed to have their args split into more
-// words after env var replacements. Meaning:
-//   ENV foo="123 456"
-//   EXPOSE $foo
-// should result in the same thing as:
-//   EXPOSE 123 456
-// and not treat "123 456" as a single word.
-// Note that: EXPOSE "$foo" and EXPOSE $foo are not the same thing.
-// Quotes will cause it to still be treated as single word.
-var allowWordExpansion = map[string]bool{
-	command.Expose: true,
-}
-
-type dispatchRequest struct {
-	builder    *Builder // TODO: replace this with a smaller interface
-	args       []string
-	attributes map[string]bool
-	flags      *BFlags
-	original   string
-	shlex      *ShellLex
-	state      *dispatchState
-	source     builder.Source
-}
-
-func newDispatchRequestFromOptions(options dispatchOptions, builder *Builder, args []string) dispatchRequest {
-	return dispatchRequest{
-		builder:    builder,
-		args:       args,
-		attributes: options.node.Attributes,
-		original:   options.node.Original,
-		flags:      NewBFlagsWithArgs(options.node.Flags),
-		shlex:      options.shlex,
-		state:      options.state,
-		source:     options.source,
-	}
-}
-
-type dispatcher func(dispatchRequest) error
-
-var evaluateTable map[string]dispatcher
-
-func init() {
-	evaluateTable = map[string]dispatcher{
-		command.Add:         add,
-		command.Arg:         arg,
-		command.Cmd:         cmd,
-		command.Copy:        dispatchCopy, // copy() is a go builtin
-		command.Entrypoint:  entrypoint,
-		command.Env:         env,
-		command.Expose:      expose,
-		command.From:        from,
-		command.Healthcheck: healthcheck,
-		command.Label:       label,
-		command.Maintainer:  maintainer,
-		command.Onbuild:     onbuild,
-		command.Run:         run,
-		command.Shell:       shell,
-		command.StopSignal:  stopSignal,
-		command.User:        user,
-		command.Volume:      volume,
-		command.Workdir:     workdir,
-	}
-}
-
-func formatStep(stepN int, stepTotal int) string {
-	return fmt.Sprintf("%d/%d", stepN+1, stepTotal)
-}
-
-// This method is the entrypoint to all statement handling routines.
-//
-// Almost all nodes will have this structure:
-// Child[Node, Node, Node] where Child is from parser.Node.Children and each
-// node comes from parser.Node.Next. This forms a "line" with a statement and
-// arguments and we process them in this normalized form by hitting
-// evaluateTable with the leaf nodes of the command and the Builder object.
-//
-// ONBUILD is a special case; in this case the parser will emit:
-// Child[Node, Child[Node, Node...]] where the first node is the literal
-// "onbuild" and the child entrypoint is the command of the ONBUILD statement,
-// such as `RUN` in ONBUILD RUN foo. There is special case logic in here to
-// deal with that, at least until it becomes more of a general concern with new
-// features.
-func (b *Builder) dispatch(options dispatchOptions) (*dispatchState, error) {
-	node := options.node
-	cmd := node.Value
-	upperCasedCmd := strings.ToUpper(cmd)
-
-	// To ensure the user is given a decent error message if the platform
-	// on which the daemon is running does not support a builder command.
-	if err := platformSupports(strings.ToLower(cmd)); err != nil {
-		buildsFailed.WithValues(metricsCommandNotSupportedError).Inc()
-		return nil, err
-	}
-
-	msg := bytes.NewBufferString(fmt.Sprintf("Step %s : %s%s",
-		options.stepMsg, upperCasedCmd, formatFlags(node.Flags)))
-
-	args := []string{}
-	ast := node
-	if cmd == command.Onbuild {
-		var err error
-		ast, args, err = handleOnBuildNode(node, msg)
+func dispatch(d dispatchRequest, cmd instructions.Command) error {
+	if c, ok := cmd.(instructions.PlatformSpecific); ok {
+		err := c.CheckPlatform(d.builder.platform)
 		if err != nil {
-			return nil, err
+			return validationError{err}
+		}
+	}
+	runConfigEnv := d.state.runConfig.Env
+	envs := append(runConfigEnv, d.state.buildArgs.FilterAllowed(runConfigEnv)...)
+
+	if ex, ok := cmd.(instructions.SupportsSingleWordExpansion); ok {
+		err := ex.Expand(func(word string) (string, error) {
+			return d.shlex.ProcessWord(word, envs)
+		})
+		if err != nil {
+			return validationError{err}
 		}
 	}
 
-	runConfigEnv := options.state.runConfig.Env
-	envs := append(runConfigEnv, b.buildArgs.FilterAllowed(runConfigEnv)...)
-	processFunc := createProcessWordFunc(options.shlex, cmd, envs)
-	words, err := getDispatchArgsFromNode(ast, processFunc, msg)
-	if err != nil {
-		buildsFailed.WithValues(metricsErrorProcessingCommandsError).Inc()
-		return nil, err
+	if d.builder.options.ForceRemove {
+		defer d.builder.containerManager.RemoveAll(d.builder.Stdout)
 	}
-	args = append(args, words...)
 
-	fmt.Fprintln(b.Stdout, msg.String())
-
-	f, ok := evaluateTable[cmd]
-	if !ok {
-		buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
-		return nil, fmt.Errorf("unknown instruction: %s", upperCasedCmd)
+	switch c := cmd.(type) {
+	case *instructions.EnvCommand:
+		return dispatchEnv(d, c)
+	case *instructions.MaintainerCommand:
+		return dispatchMaintainer(d, c)
+	case *instructions.LabelCommand:
+		return dispatchLabel(d, c)
+	case *instructions.AddCommand:
+		return dispatchAdd(d, c)
+	case *instructions.CopyCommand:
+		return dispatchCopy(d, c)
+	case *instructions.OnbuildCommand:
+		return dispatchOnbuild(d, c)
+	case *instructions.WorkdirCommand:
+		return dispatchWorkdir(d, c)
+	case *instructions.RunCommand:
+		return dispatchRun(d, c)
+	case *instructions.CmdCommand:
+		return dispatchCmd(d, c)
+	case *instructions.HealthCheckCommand:
+		return dispatchHealthcheck(d, c)
+	case *instructions.EntrypointCommand:
+		return dispatchEntrypoint(d, c)
+	case *instructions.ExposeCommand:
+		return dispatchExpose(d, c, envs)
+	case *instructions.UserCommand:
+		return dispatchUser(d, c)
+	case *instructions.VolumeCommand:
+		return dispatchVolume(d, c)
+	case *instructions.StopSignalCommand:
+		return dispatchStopSignal(d, c)
+	case *instructions.ArgCommand:
+		return dispatchArg(d, c)
+	case *instructions.ShellCommand:
+		return dispatchShell(d, c)
 	}
-	options.state.updateRunConfig()
-	err = f(newDispatchRequestFromOptions(options, b, args))
-	return options.state, err
-}
-
-type dispatchOptions struct {
-	state   *dispatchState
-	stepMsg string
-	node    *parser.Node
-	shlex   *ShellLex
-	source  builder.Source
+	return errors.Errorf("unsupported command type: %v", reflect.TypeOf(cmd))
 }
 
 // dispatchState is a data object which is modified by dispatchers
@@ -193,10 +103,95 @@
 	imageID    string
 	baseImage  builder.Image
 	stageName  string
+	buildArgs  *buildArgs
 }
 
-func newDispatchState() *dispatchState {
-	return &dispatchState{runConfig: &container.Config{}}
+func newDispatchState(baseArgs *buildArgs) *dispatchState {
+	args := baseArgs.Clone()
+	args.ResetAllowed()
+	return &dispatchState{runConfig: &container.Config{}, buildArgs: args}
+}
+
+type stagesBuildResults struct {
+	flat    []*container.Config
+	indexed map[string]*container.Config
+}
+
+func newStagesBuildResults() *stagesBuildResults {
+	return &stagesBuildResults{
+		indexed: make(map[string]*container.Config),
+	}
+}
+
+func (r *stagesBuildResults) getByName(name string) (*container.Config, bool) {
+	c, ok := r.indexed[strings.ToLower(name)]
+	return c, ok
+}
+
+func (r *stagesBuildResults) validateIndex(i int) error {
+	if i == len(r.flat) {
+		return errors.New("refers to current build stage")
+	}
+	if i < 0 || i > len(r.flat) {
+		return errors.New("index out of bounds")
+	}
+	return nil
+}
+
+func (r *stagesBuildResults) get(nameOrIndex string) (*container.Config, error) {
+	if c, ok := r.getByName(nameOrIndex); ok {
+		return c, nil
+	}
+	ix, err := strconv.ParseInt(nameOrIndex, 10, 0)
+	if err != nil {
+		return nil, nil
+	}
+	if err := r.validateIndex(int(ix)); err != nil {
+		return nil, err
+	}
+	return r.flat[ix], nil
+}
+
+func (r *stagesBuildResults) checkStageNameAvailable(name string) error {
+	if name != "" {
+		if _, ok := r.getByName(name); ok {
+			return errors.Errorf("%s stage name already used", name)
+		}
+	}
+	return nil
+}
+
+func (r *stagesBuildResults) commitStage(name string, config *container.Config) error {
+	if name != "" {
+		if _, ok := r.getByName(name); ok {
+			return errors.Errorf("%s stage name already used", name)
+		}
+		r.indexed[strings.ToLower(name)] = config
+	}
+	r.flat = append(r.flat, config)
+	return nil
+}
+
+func commitStage(state *dispatchState, stages *stagesBuildResults) error {
+	return stages.commitStage(state.stageName, state.runConfig)
+}
+
+type dispatchRequest struct {
+	state   *dispatchState
+	shlex   *ShellLex
+	builder *Builder
+	source  builder.Source
+	stages  *stagesBuildResults
+}
+
+func newDispatchRequest(builder *Builder, escapeToken rune, source builder.Source, buildArgs *buildArgs, stages *stagesBuildResults) dispatchRequest {
+	return dispatchRequest{
+		state:   newDispatchState(buildArgs),
+		shlex:   NewShellLex(escapeToken),
+		builder: builder,
+		source:  source,
+		stages:  stages,
+	}
 }
 
 func (s *dispatchState) updateRunConfig() {
@@ -208,24 +203,19 @@
 	return s.imageID != "" || (s.baseImage != nil && s.baseImage.ImageID() == "")
 }
 
-func (s *dispatchState) isCurrentStage(target string) bool {
-	if target == "" {
-		return false
-	}
-	return strings.EqualFold(s.stageName, target)
-}
-
 func (s *dispatchState) beginStage(stageName string, image builder.Image) {
 	s.stageName = stageName
 	s.imageID = image.ImageID()
 
 	if image.RunConfig() != nil {
-		s.runConfig = image.RunConfig()
+		s.runConfig = copyRunConfig(image.RunConfig()) // copy avoids referencing the same instance when 2 stages have the same base
 	} else {
 		s.runConfig = &container.Config{}
 	}
 	s.baseImage = image
 	s.setDefaultPath()
+	s.runConfig.OpenStdin = false
+	s.runConfig.StdinOnce = false
 }
 
 // Add the default PATH to runConfig.ENV if one exists for the platform and there
@@ -244,84 +234,3 @@
 		s.runConfig.Env = append(s.runConfig.Env, "PATH="+system.DefaultPathEnv(platform))
 	}
 }
-
-func handleOnBuildNode(ast *parser.Node, msg *bytes.Buffer) (*parser.Node, []string, error) {
-	if ast.Next == nil {
-		return nil, nil, errors.New("ONBUILD requires at least one argument")
-	}
-	ast = ast.Next.Children[0]
-	msg.WriteString(" " + ast.Value + formatFlags(ast.Flags))
-	return ast, []string{ast.Value}, nil
-}
-
-func formatFlags(flags []string) string {
-	if len(flags) > 0 {
-		return " " + strings.Join(flags, " ")
-	}
-	return ""
-}
-
-func getDispatchArgsFromNode(ast *parser.Node, processFunc processWordFunc, msg *bytes.Buffer) ([]string, error) {
-	args := []string{}
-	for i := 0; ast.Next != nil; i++ {
-		ast = ast.Next
-		words, err := processFunc(ast.Value)
-		if err != nil {
-			return nil, err
-		}
-		args = append(args, words...)
-		msg.WriteString(" " + ast.Value)
-	}
-	return args, nil
-}
-
-type processWordFunc func(string) ([]string, error)
-
-func createProcessWordFunc(shlex *ShellLex, cmd string, envs []string) processWordFunc {
-	switch {
-	case !replaceEnvAllowed[cmd]:
-		return func(word string) ([]string, error) {
-			return []string{word}, nil
-		}
-	case allowWordExpansion[cmd]:
-		return func(word string) ([]string, error) {
-			return shlex.ProcessWords(word, envs)
-		}
-	default:
-		return func(word string) ([]string, error) {
-			word, err := shlex.ProcessWord(word, envs)
-			return []string{word}, err
-		}
-	}
-}
-
-// checkDispatch does a simple check for syntax errors of the Dockerfile.
-// Because some of the instructions can only be validated through runtime,
-// arg, env, etc., this syntax check will not be complete and could not replace
-// the runtime check. Instead, this function is only a helper that allows
-// user to find out the obvious error in Dockerfile earlier on.
-func checkDispatch(ast *parser.Node) error {
-	cmd := ast.Value
-	upperCasedCmd := strings.ToUpper(cmd)
-
-	// To ensure the user is given a decent error message if the platform
-	// on which the daemon is running does not support a builder command.
-	if err := platformSupports(strings.ToLower(cmd)); err != nil {
-		return err
-	}
-
-	// The instruction itself is ONBUILD, we will make sure it follows with at
-	// least one argument
-	if upperCasedCmd == "ONBUILD" {
-		if ast.Next == nil {
-			buildsFailed.WithValues(metricsMissingOnbuildArgumentsError).Inc()
-			return errors.New("ONBUILD requires at least one argument")
-		}
-	}
-
-	if _, ok := evaluateTable[cmd]; ok {
-		return nil
-	}
-	buildsFailed.WithValues(metricsUnknownInstructionError).Inc()
-	return errors.Errorf("unknown instruction: %s", upperCasedCmd)
-}
diff --git a/builder/dockerfile/evaluator_test.go b/builder/dockerfile/evaluator_test.go
index 72d7ce1..fc5512d 100644
--- a/builder/dockerfile/evaluator_test.go
+++ b/builder/dockerfile/evaluator_test.go
@@ -1,21 +1,19 @@
 package dockerfile
 
 import (
-	"io/ioutil"
-	"strings"
 	"testing"
 
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/builder/dockerfile/parser"
+	"github.com/docker/docker/builder/dockerfile/instructions"
 	"github.com/docker/docker/builder/remotecontext"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/reexec"
 )
 
 type dispatchTestCase struct {
-	name, dockerfile, expectedError string
-	files                           map[string]string
+	name, expectedError string
+	cmd                 instructions.Command
+	files               map[string]string
 }
 
 func init() {
@@ -23,108 +21,73 @@
 }
 
 func initDispatchTestCases() []dispatchTestCase {
-	dispatchTestCases := []dispatchTestCase{{
-		name: "copyEmptyWhitespace",
-		dockerfile: `COPY
-	quux \
-      bar`,
-		expectedError: "COPY requires at least two arguments",
-	},
+	dispatchTestCases := []dispatchTestCase{
 		{
-			name:          "ONBUILD forbidden FROM",
-			dockerfile:    "ONBUILD FROM scratch",
-			expectedError: "FROM isn't allowed as an ONBUILD trigger",
-			files:         nil,
-		},
-		{
-			name:          "ONBUILD forbidden MAINTAINER",
-			dockerfile:    "ONBUILD MAINTAINER docker.io",
-			expectedError: "MAINTAINER isn't allowed as an ONBUILD trigger",
-			files:         nil,
-		},
-		{
-			name:          "ARG two arguments",
-			dockerfile:    "ARG foo bar",
-			expectedError: "ARG requires exactly one argument",
-			files:         nil,
-		},
-		{
-			name:          "MAINTAINER unknown flag",
-			dockerfile:    "MAINTAINER --boo joe@example.com",
-			expectedError: "Unknown flag: boo",
-			files:         nil,
-		},
-		{
-			name:          "ADD multiple files to file",
-			dockerfile:    "ADD file1.txt file2.txt test",
+			name: "ADD multiple files to file",
+			cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{
+				"file1.txt",
+				"file2.txt",
+				"test",
+			}},
 			expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
 			files:         map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
 		},
 		{
-			name:          "JSON ADD multiple files to file",
-			dockerfile:    `ADD ["file1.txt", "file2.txt", "test"]`,
+			name: "Wildcard ADD multiple files to file",
+			cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{
+				"file*.txt",
+				"test",
+			}},
 			expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
 			files:         map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
 		},
 		{
-			name:          "Wildcard ADD multiple files to file",
-			dockerfile:    "ADD file*.txt test",
-			expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
-			files:         map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
-		},
-		{
-			name:          "Wildcard JSON ADD multiple files to file",
-			dockerfile:    `ADD ["file*.txt", "test"]`,
-			expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
-			files:         map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
-		},
-		{
-			name:          "COPY multiple files to file",
-			dockerfile:    "COPY file1.txt file2.txt test",
+			name: "COPY multiple files to file",
+			cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
+				"file1.txt",
+				"file2.txt",
+				"test",
+			}},
 			expectedError: "When using COPY with more than one source file, the destination must be a directory and end with a /",
 			files:         map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
 		},
 		{
-			name:          "JSON COPY multiple files to file",
-			dockerfile:    `COPY ["file1.txt", "file2.txt", "test"]`,
-			expectedError: "When using COPY with more than one source file, the destination must be a directory and end with a /",
-			files:         map[string]string{"file1.txt": "test1", "file2.txt": "test2"},
-		},
-		{
-			name:          "ADD multiple files to file with whitespace",
-			dockerfile:    `ADD [ "test file1.txt", "test file2.txt", "test" ]`,
+			name: "ADD multiple files to file with whitespace",
+			cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{
+				"test file1.txt",
+				"test file2.txt",
+				"test",
+			}},
 			expectedError: "When using ADD with more than one source file, the destination must be a directory and end with a /",
 			files:         map[string]string{"test file1.txt": "test1", "test file2.txt": "test2"},
 		},
 		{
-			name:          "COPY multiple files to file with whitespace",
-			dockerfile:    `COPY [ "test file1.txt", "test file2.txt", "test" ]`,
+			name: "COPY multiple files to file with whitespace",
+			cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
+				"test file1.txt",
+				"test file2.txt",
+				"test",
+			}},
 			expectedError: "When using COPY with more than one source file, the destination must be a directory and end with a /",
 			files:         map[string]string{"test file1.txt": "test1", "test file2.txt": "test2"},
 		},
 		{
-			name:          "COPY wildcard no files",
-			dockerfile:    `COPY file*.txt /tmp/`,
+			name: "COPY wildcard no files",
+			cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
+				"file*.txt",
+				"/tmp/",
+			}},
 			expectedError: "COPY failed: no source files were specified",
 			files:         nil,
 		},
 		{
-			name:          "COPY url",
-			dockerfile:    `COPY https://index.docker.io/robots.txt /`,
+			name: "COPY url",
+			cmd: &instructions.CopyCommand{SourcesAndDest: instructions.SourcesAndDest{
+				"https://index.docker.io/robots.txt",
+				"/",
+			}},
 			expectedError: "source can't be a URL for COPY",
 			files:         nil,
-		},
-		{
-			name:          "Chaining ONBUILD",
-			dockerfile:    `ONBUILD ONBUILD RUN touch foobar`,
-			expectedError: "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed",
-			files:         nil,
-		},
-		{
-			name:          "Invalid instruction",
-			dockerfile:    `foo bar`,
-			expectedError: "unknown instruction: FOO",
-			files:         nil,
 		}}
 
 	return dispatchTestCases
@@ -170,41 +133,8 @@
 		}
 	}()
 
-	r := strings.NewReader(testCase.dockerfile)
-	result, err := parser.Parse(r)
-
-	if err != nil {
-		t.Fatalf("Error when parsing Dockerfile: %s", err)
-	}
-
-	options := &types.ImageBuildOptions{
-		BuildArgs: make(map[string]*string),
-	}
-
-	b := &Builder{
-		options:   options,
-		Stdout:    ioutil.Discard,
-		buildArgs: newBuildArgs(options.BuildArgs),
-	}
-
-	shlex := NewShellLex(parser.DefaultEscapeToken)
-	n := result.AST
-	state := &dispatchState{runConfig: &container.Config{}}
-	opts := dispatchOptions{
-		state:   state,
-		stepMsg: formatStep(0, len(n.Children)),
-		node:    n.Children[0],
-		shlex:   shlex,
-		source:  context,
-	}
-	state, err = b.dispatch(opts)
-
-	if err == nil {
-		t.Fatalf("No error when executing test %s", testCase.name)
-	}
-
-	if !strings.Contains(err.Error(), testCase.expectedError) {
-		t.Fatalf("Wrong error message. Should be \"%s\". Got \"%s\"", testCase.expectedError, err.Error())
-	}
-
+	b := newBuilderWithMockBackend()
+	sb := newDispatchRequest(b, '`', context, newBuildArgs(make(map[string]*string)), newStagesBuildResults())
+	err = dispatch(sb, testCase.cmd)
+	testutil.ErrorContains(t, err, testCase.expectedError)
 }
diff --git a/builder/dockerfile/evaluator_unix.go b/builder/dockerfile/evaluator_unix.go
deleted file mode 100644
index 28fd5b1..0000000
--- a/builder/dockerfile/evaluator_unix.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build !windows
-
-package dockerfile
-
-// platformSupports is a short-term function to give users a quality error
-// message if a Dockerfile uses a command not supported on the platform.
-func platformSupports(command string) error {
-	return nil
-}
diff --git a/builder/dockerfile/evaluator_windows.go b/builder/dockerfile/evaluator_windows.go
deleted file mode 100644
index 72483a2..0000000
--- a/builder/dockerfile/evaluator_windows.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package dockerfile
-
-import "fmt"
-
-// platformSupports is gives users a quality error message if a Dockerfile uses
-// a command not supported on the platform.
-func platformSupports(command string) error {
-	switch command {
-	case "stopsignal":
-		return fmt.Errorf("The daemon on this platform does not support the command '%s'", command)
-	}
-	return nil
-}
diff --git a/builder/dockerfile/imagecontext.go b/builder/dockerfile/imagecontext.go
index 64b2572..2301d1a 100644
--- a/builder/dockerfile/imagecontext.go
+++ b/builder/dockerfile/imagecontext.go
@@ -1,91 +1,15 @@
 package dockerfile
 
 import (
-	"strconv"
-	"strings"
-
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/builder/remotecontext"
 	dockerimage "github.com/docker/docker/image"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
-type buildStage struct {
-	id string
-}
-
-func newBuildStage(imageID string) *buildStage {
-	return &buildStage{id: imageID}
-}
-
-func (b *buildStage) ImageID() string {
-	return b.id
-}
-
-func (b *buildStage) update(imageID string) {
-	b.id = imageID
-}
-
-// buildStages tracks each stage of a build so they can be retrieved by index
-// or by name.
-type buildStages struct {
-	sequence []*buildStage
-	byName   map[string]*buildStage
-}
-
-func newBuildStages() *buildStages {
-	return &buildStages{byName: make(map[string]*buildStage)}
-}
-
-func (s *buildStages) getByName(name string) (*buildStage, bool) {
-	stage, ok := s.byName[strings.ToLower(name)]
-	return stage, ok
-}
-
-func (s *buildStages) get(indexOrName string) (*buildStage, error) {
-	index, err := strconv.Atoi(indexOrName)
-	if err == nil {
-		if err := s.validateIndex(index); err != nil {
-			return nil, err
-		}
-		return s.sequence[index], nil
-	}
-	if im, ok := s.byName[strings.ToLower(indexOrName)]; ok {
-		return im, nil
-	}
-	return nil, nil
-}
-
-func (s *buildStages) validateIndex(i int) error {
-	if i < 0 || i >= len(s.sequence)-1 {
-		if i == len(s.sequence)-1 {
-			return errors.New("refers to current build stage")
-		}
-		return errors.New("index out of bounds")
-	}
-	return nil
-}
-
-func (s *buildStages) add(name string, image builder.Image) error {
-	stage := newBuildStage(image.ImageID())
-	name = strings.ToLower(name)
-	if len(name) > 0 {
-		if _, ok := s.byName[name]; ok {
-			return errors.Errorf("duplicate name %s", name)
-		}
-		s.byName[name] = stage
-	}
-	s.sequence = append(s.sequence, stage)
-	return nil
-}
-
-func (s *buildStages) update(imageID string) {
-	s.sequence[len(s.sequence)-1].update(imageID)
-}
-
 type getAndMountFunc func(string, bool) (builder.Image, builder.ReleaseableLayer, error)
 
 // imageSources mounts images and provides a cache for mounted images. It tracks
@@ -94,7 +18,6 @@
 	byImageID map[string]*imageMount
 	mounts    []*imageMount
 	getImage  getAndMountFunc
-	cache     pathCache // TODO: remove
 }
 
 // TODO @jhowardmsft LCOW Support: Eventually, platform can be moved to options.Options.Platform,
diff --git a/builder/dockerfile/imageprobe.go b/builder/dockerfile/imageprobe.go
index 3433612..239eb9e 100644
--- a/builder/dockerfile/imageprobe.go
+++ b/builder/dockerfile/imageprobe.go
@@ -1,9 +1,9 @@
 package dockerfile
 
 import (
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/builder"
+	"github.com/sirupsen/logrus"
 )
 
 // ImageProber exposes an Image cache to the Builder. It supports resetting a
diff --git a/builder/dockerfile/bflag.go b/builder/dockerfile/instructions/bflag.go
similarity index 99%
rename from builder/dockerfile/bflag.go
rename to builder/dockerfile/instructions/bflag.go
index d849661..7a81e3c 100644
--- a/builder/dockerfile/bflag.go
+++ b/builder/dockerfile/instructions/bflag.go
@@ -1,4 +1,4 @@
-package dockerfile
+package instructions
 
 import (
 	"fmt"
diff --git a/builder/dockerfile/bflag_test.go b/builder/dockerfile/instructions/bflag_test.go
similarity index 95%
rename from builder/dockerfile/bflag_test.go
rename to builder/dockerfile/instructions/bflag_test.go
index ac07e48..b194ba7 100644
--- a/builder/dockerfile/bflag_test.go
+++ b/builder/dockerfile/instructions/bflag_test.go
@@ -1,4 +1,4 @@
-package dockerfile
+package instructions
 
 import (
 	"testing"
@@ -34,10 +34,10 @@
 		t.Fatalf("Test3 of %q was supposed to work: %s", bf.Args, err)
 	}
 
-	if flStr1.IsUsed() == true {
+	if flStr1.IsUsed() {
 		t.Fatal("Test3 - str1 was not used!")
 	}
-	if flBool1.IsUsed() == true {
+	if flBool1.IsUsed() {
 		t.Fatal("Test3 - bool1 was not used!")
 	}
 
@@ -58,10 +58,10 @@
 	if flBool1.IsTrue() {
 		t.Fatal("Bool1 was supposed to default to: false")
 	}
-	if flStr1.IsUsed() == true {
+	if flStr1.IsUsed() {
 		t.Fatal("Str1 was not used!")
 	}
-	if flBool1.IsUsed() == true {
+	if flBool1.IsUsed() {
 		t.Fatal("Bool1 was not used!")
 	}
 
diff --git a/builder/dockerfile/instructions/commands.go b/builder/dockerfile/instructions/commands.go
new file mode 100644
index 0000000..8d5d6b0
--- /dev/null
+++ b/builder/dockerfile/instructions/commands.go
@@ -0,0 +1,396 @@
+package instructions
+
+import (
+	"errors"
+
+	"strings"
+
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/strslice"
+)
+
+// KeyValuePair represent an arbitrary named value (usefull in slice insted of map[string] string to preserve ordering)
+type KeyValuePair struct {
+	Key   string
+	Value string
+}
+
+func (kvp *KeyValuePair) String() string {
+	return kvp.Key + "=" + kvp.Value
+}
+
+// Command is implemented by every command present in a dockerfile
+type Command interface {
+	Name() string
+}
+
+// KeyValuePairs is a slice of KeyValuePair
+type KeyValuePairs []KeyValuePair
+
+// withNameAndCode is the base of every command in a Dockerfile (String() returns its source code)
+type withNameAndCode struct {
+	code string
+	name string
+}
+
+func (c *withNameAndCode) String() string {
+	return c.code
+}
+
+// Name of the command
+func (c *withNameAndCode) Name() string {
+	return c.name
+}
+
+func newWithNameAndCode(req parseRequest) withNameAndCode {
+	return withNameAndCode{code: strings.TrimSpace(req.original), name: req.command}
+}
+
+// SingleWordExpander is a provider for variable expansion where 1 word => 1 output
+type SingleWordExpander func(word string) (string, error)
+
+// SupportsSingleWordExpansion interface marks a command as supporting variable expansion
+type SupportsSingleWordExpansion interface {
+	Expand(expander SingleWordExpander) error
+}
+
+// PlatformSpecific adds platform checks to a command
+type PlatformSpecific interface {
+	CheckPlatform(platform string) error
+}
+
+func expandKvp(kvp KeyValuePair, expander SingleWordExpander) (KeyValuePair, error) {
+	key, err := expander(kvp.Key)
+	if err != nil {
+		return KeyValuePair{}, err
+	}
+	value, err := expander(kvp.Value)
+	if err != nil {
+		return KeyValuePair{}, err
+	}
+	return KeyValuePair{Key: key, Value: value}, nil
+}
+func expandKvpsInPlace(kvps KeyValuePairs, expander SingleWordExpander) error {
+	for i, kvp := range kvps {
+		newKvp, err := expandKvp(kvp, expander)
+		if err != nil {
+			return err
+		}
+		kvps[i] = newKvp
+	}
+	return nil
+}
+
+func expandSliceInPlace(values []string, expander SingleWordExpander) error {
+	for i, v := range values {
+		newValue, err := expander(v)
+		if err != nil {
+			return err
+		}
+		values[i] = newValue
+	}
+	return nil
+}
+
+// EnvCommand : ENV key1 value1 [keyN valueN...]
+type EnvCommand struct {
+	withNameAndCode
+	Env KeyValuePairs // kvp slice instead of map to preserve ordering
+}
+
+// Expand variables
+func (c *EnvCommand) Expand(expander SingleWordExpander) error {
+	return expandKvpsInPlace(c.Env, expander)
+}
+
+// MaintainerCommand : MAINTAINER maintainer_name
+type MaintainerCommand struct {
+	withNameAndCode
+	Maintainer string
+}
+
+// LabelCommand : LABEL some json data describing the image
+//
+// Sets the Label variable foo to bar,
+//
+type LabelCommand struct {
+	withNameAndCode
+	Labels KeyValuePairs // kvp slice instead of map to preserve ordering
+}
+
+// Expand variables
+func (c *LabelCommand) Expand(expander SingleWordExpander) error {
+	return expandKvpsInPlace(c.Labels, expander)
+}
+
+// SourcesAndDest represent a list of source files and a destination
+type SourcesAndDest []string
+
+// Sources list the source paths
+func (s SourcesAndDest) Sources() []string {
+	res := make([]string, len(s)-1)
+	copy(res, s[:len(s)-1])
+	return res
+}
+
+// Dest path of the operation
+func (s SourcesAndDest) Dest() string {
+	return s[len(s)-1]
+}
+
+// AddCommand : ADD foo /path
+//
+// Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling
+// exist here. If you do not wish to have this automatic handling, use COPY.
+//
+type AddCommand struct {
+	withNameAndCode
+	SourcesAndDest
+	Chown string
+}
+
+// Expand variables
+func (c *AddCommand) Expand(expander SingleWordExpander) error {
+	return expandSliceInPlace(c.SourcesAndDest, expander)
+}
+
+// CopyCommand : COPY foo /path
+//
+// Same as 'ADD' but without the tar and remote url handling.
+//
+type CopyCommand struct {
+	withNameAndCode
+	SourcesAndDest
+	From  string
+	Chown string
+}
+
+// Expand variables
+func (c *CopyCommand) Expand(expander SingleWordExpander) error {
+	return expandSliceInPlace(c.SourcesAndDest, expander)
+}
+
+// OnbuildCommand : ONBUILD <some other command>
+type OnbuildCommand struct {
+	withNameAndCode
+	Expression string
+}
+
+// WorkdirCommand : WORKDIR /tmp
+//
+// Set the working directory for future RUN/CMD/etc statements.
+//
+type WorkdirCommand struct {
+	withNameAndCode
+	Path string
+}
+
+// Expand variables
+func (c *WorkdirCommand) Expand(expander SingleWordExpander) error {
+	p, err := expander(c.Path)
+	if err != nil {
+		return err
+	}
+	c.Path = p
+	return nil
+}
+
+// ShellDependantCmdLine represents a cmdline optionaly prepended with the shell
+type ShellDependantCmdLine struct {
+	CmdLine      strslice.StrSlice
+	PrependShell bool
+}
+
+// RunCommand : RUN some command yo
+//
+// run a command and commit the image. Args are automatically prepended with
+// the current SHELL which defaults to 'sh -c' under linux or 'cmd /S /C' under
+// Windows, in the event there is only one argument The difference in processing:
+//
+// RUN echo hi          # sh -c echo hi       (Linux)
+// RUN echo hi          # cmd /S /C echo hi   (Windows)
+// RUN [ "echo", "hi" ] # echo hi
+//
+type RunCommand struct {
+	withNameAndCode
+	ShellDependantCmdLine
+}
+
+// CmdCommand : CMD foo
+//
+// Set the default command to run in the container (which may be empty).
+// Argument handling is the same as RUN.
+//
+type CmdCommand struct {
+	withNameAndCode
+	ShellDependantCmdLine
+}
+
+// HealthCheckCommand : HEALTHCHECK foo
+//
+// Set the default healthcheck command to run in the container (which may be empty).
+// Argument handling is the same as RUN.
+//
+type HealthCheckCommand struct {
+	withNameAndCode
+	Health *container.HealthConfig
+}
+
+// EntrypointCommand : ENTRYPOINT /usr/sbin/nginx
+//
+// Set the entrypoint to /usr/sbin/nginx. Will accept the CMD as the arguments
+// to /usr/sbin/nginx. Uses the default shell if not in JSON format.
+//
+// Handles command processing similar to CMD and RUN, only req.runConfig.Entrypoint
+// is initialized at newBuilder time instead of through argument parsing.
+//
+type EntrypointCommand struct {
+	withNameAndCode
+	ShellDependantCmdLine
+}
+
+// ExposeCommand : EXPOSE 6667/tcp 7000/tcp
+//
+// Expose ports for links and port mappings. This all ends up in
+// req.runConfig.ExposedPorts for runconfig.
+//
+type ExposeCommand struct {
+	withNameAndCode
+	Ports []string
+}
+
+// UserCommand : USER foo
+//
+// Set the user to 'foo' for future commands and when running the
+// ENTRYPOINT/CMD at container run time.
+//
+type UserCommand struct {
+	withNameAndCode
+	User string
+}
+
+// Expand variables
+func (c *UserCommand) Expand(expander SingleWordExpander) error {
+	p, err := expander(c.User)
+	if err != nil {
+		return err
+	}
+	c.User = p
+	return nil
+}
+
+// VolumeCommand : VOLUME /foo
+//
+// Expose the volume /foo for use. Will also accept the JSON array form.
+//
+type VolumeCommand struct {
+	withNameAndCode
+	Volumes []string
+}
+
+// Expand variables
+func (c *VolumeCommand) Expand(expander SingleWordExpander) error {
+	return expandSliceInPlace(c.Volumes, expander)
+}
+
+// StopSignalCommand : STOPSIGNAL signal
+//
+// Set the signal that will be used to kill the container.
+type StopSignalCommand struct {
+	withNameAndCode
+	Signal string
+}
+
+// Expand variables
+func (c *StopSignalCommand) Expand(expander SingleWordExpander) error {
+	p, err := expander(c.Signal)
+	if err != nil {
+		return err
+	}
+	c.Signal = p
+	return nil
+}
+
+// CheckPlatform checks that the command is supported in the target platform
+func (c *StopSignalCommand) CheckPlatform(platform string) error {
+	if platform == "windows" {
+		return errors.New("The daemon on this platform does not support the command stopsignal")
+	}
+	return nil
+}
+
+// ArgCommand : ARG name[=value]
+//
+// Adds the variable foo to the trusted list of variables that can be passed
+// to builder using the --build-arg flag for expansion/substitution or passing to 'run'.
+// Dockerfile author may optionally set a default value of this variable.
+type ArgCommand struct {
+	withNameAndCode
+	Key   string
+	Value *string
+}
+
+// Expand variables
+func (c *ArgCommand) Expand(expander SingleWordExpander) error {
+	p, err := expander(c.Key)
+	if err != nil {
+		return err
+	}
+	c.Key = p
+	if c.Value != nil {
+		p, err = expander(*c.Value)
+		if err != nil {
+			return err
+		}
+		c.Value = &p
+	}
+	return nil
+}
+
+// ShellCommand : SHELL powershell -command
+//
+// Set the non-default shell to use.
+type ShellCommand struct {
+	withNameAndCode
+	Shell strslice.StrSlice
+}
+
+// Stage represents a single stage in a multi-stage build
+type Stage struct {
+	Name       string
+	Commands   []Command
+	BaseName   string
+	SourceCode string
+}
+
+// AddCommand to the stage
+func (s *Stage) AddCommand(cmd Command) {
+	// todo: validate cmd type
+	s.Commands = append(s.Commands, cmd)
+}
+
+// IsCurrentStage check if the stage name is the current stage
+func IsCurrentStage(s []Stage, name string) bool {
+	if len(s) == 0 {
+		return false
+	}
+	return s[len(s)-1].Name == name
+}
+
+// CurrentStage return the last stage in a slice
+func CurrentStage(s []Stage) (*Stage, error) {
+	if len(s) == 0 {
+		return nil, errors.New("No build stage in current context")
+	}
+	return &s[len(s)-1], nil
+}
+
+// HasStage looks for the presence of a given stage name
+func HasStage(s []Stage, name string) (int, bool) {
+	for i, stage := range s {
+		if stage.Name == name {
+			return i, true
+		}
+	}
+	return -1, false
+}
diff --git a/builder/dockerfile/instructions/errors_unix.go b/builder/dockerfile/instructions/errors_unix.go
new file mode 100644
index 0000000..0b03b34
--- /dev/null
+++ b/builder/dockerfile/instructions/errors_unix.go
@@ -0,0 +1,9 @@
+// +build !windows
+
+package instructions
+
+import "fmt"
+
+func errNotJSON(command, _ string) error {
+	return fmt.Errorf("%s requires the arguments to be in JSON form", command)
+}
diff --git a/builder/dockerfile/instructions/errors_windows.go b/builder/dockerfile/instructions/errors_windows.go
new file mode 100644
index 0000000..a4843c5
--- /dev/null
+++ b/builder/dockerfile/instructions/errors_windows.go
@@ -0,0 +1,27 @@
+package instructions
+
+import (
+	"fmt"
+	"path/filepath"
+	"regexp"
+	"strings"
+)
+
+func errNotJSON(command, original string) error {
+	// For Windows users, give a hint if it looks like it might contain
+	// a path which hasn't been escaped such as ["c:\windows\system32\prog.exe", "-param"],
+	// as JSON must be escaped. Unfortunate...
+	//
+	// Specifically looking for quote-driveletter-colon-backslash, there's no
+	// double backslash and a [] pair. No, this is not perfect, but it doesn't
+	// have to be. It's simply a hint to make life a little easier.
+	extra := ""
+	original = filepath.FromSlash(strings.ToLower(strings.Replace(strings.ToLower(original), strings.ToLower(command)+" ", "", -1)))
+	if len(regexp.MustCompile(`"[a-z]:\\.*`).FindStringSubmatch(original)) > 0 &&
+		!strings.Contains(original, `\\`) &&
+		strings.Contains(original, "[") &&
+		strings.Contains(original, "]") {
+		extra = fmt.Sprintf(`. It looks like '%s' includes a file path without an escaped back-slash. JSON requires back-slashes to be escaped such as ["c:\\path\\to\\file.exe", "/parameter"]`, original)
+	}
+	return fmt.Errorf("%s requires the arguments to be in JSON form%s", command, extra)
+}
diff --git a/builder/dockerfile/instructions/parse.go b/builder/dockerfile/instructions/parse.go
new file mode 100644
index 0000000..86ddc57
--- /dev/null
+++ b/builder/dockerfile/instructions/parse.go
@@ -0,0 +1,635 @@
+package instructions
+
+import (
+	"fmt"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/strslice"
+	"github.com/docker/docker/builder/dockerfile/command"
+	"github.com/docker/docker/builder/dockerfile/parser"
+	"github.com/pkg/errors"
+)
+
+type parseRequest struct {
+	command    string
+	args       []string
+	attributes map[string]bool
+	flags      *BFlags
+	original   string
+}
+
+func nodeArgs(node *parser.Node) []string {
+	result := []string{}
+	for ; node.Next != nil; node = node.Next {
+		arg := node.Next
+		if len(arg.Children) == 0 {
+			result = append(result, arg.Value)
+		} else if len(arg.Children) == 1 {
+			//sub command
+			result = append(result, arg.Children[0].Value)
+			result = append(result, nodeArgs(arg.Children[0])...)
+		}
+	}
+	return result
+}
+
+func newParseRequestFromNode(node *parser.Node) parseRequest {
+	return parseRequest{
+		command:    node.Value,
+		args:       nodeArgs(node),
+		attributes: node.Attributes,
+		original:   node.Original,
+		flags:      NewBFlagsWithArgs(node.Flags),
+	}
+}
+
+// ParseInstruction converts an AST to a typed instruction (either a command or a build stage beginning when encountering a `FROM` statement)
+func ParseInstruction(node *parser.Node) (interface{}, error) {
+	req := newParseRequestFromNode(node)
+	switch node.Value {
+	case command.Env:
+		return parseEnv(req)
+	case command.Maintainer:
+		return parseMaintainer(req)
+	case command.Label:
+		return parseLabel(req)
+	case command.Add:
+		return parseAdd(req)
+	case command.Copy:
+		return parseCopy(req)
+	case command.From:
+		return parseFrom(req)
+	case command.Onbuild:
+		return parseOnBuild(req)
+	case command.Workdir:
+		return parseWorkdir(req)
+	case command.Run:
+		return parseRun(req)
+	case command.Cmd:
+		return parseCmd(req)
+	case command.Healthcheck:
+		return parseHealthcheck(req)
+	case command.Entrypoint:
+		return parseEntrypoint(req)
+	case command.Expose:
+		return parseExpose(req)
+	case command.User:
+		return parseUser(req)
+	case command.Volume:
+		return parseVolume(req)
+	case command.StopSignal:
+		return parseStopSignal(req)
+	case command.Arg:
+		return parseArg(req)
+	case command.Shell:
+		return parseShell(req)
+	}
+
+	return nil, &UnknownInstruction{Instruction: node.Value, Line: node.StartLine}
+}
+
+// ParseCommand converts an AST to a typed Command
+func ParseCommand(node *parser.Node) (Command, error) {
+	s, err := ParseInstruction(node)
+	if err != nil {
+		return nil, err
+	}
+	if c, ok := s.(Command); ok {
+		return c, nil
+	}
+	return nil, errors.Errorf("%T is not a command type", s)
+}
+
+// UnknownInstruction represents an error occuring when a command is unresolvable
+type UnknownInstruction struct {
+	Line        int
+	Instruction string
+}
+
+func (e *UnknownInstruction) Error() string {
+	return fmt.Sprintf("unknown instruction: %s", strings.ToUpper(e.Instruction))
+}
+
+// IsUnknownInstruction checks if the error is an UnknownInstruction or a parseError containing an UnknownInstruction
+func IsUnknownInstruction(err error) bool {
+	_, ok := err.(*UnknownInstruction)
+	if !ok {
+		var pe *parseError
+		if pe, ok = err.(*parseError); ok {
+			_, ok = pe.inner.(*UnknownInstruction)
+		}
+	}
+	return ok
+}
+
+type parseError struct {
+	inner error
+	node  *parser.Node
+}
+
+func (e *parseError) Error() string {
+	return fmt.Sprintf("Dockerfile parse error line %d: %v", e.node.StartLine, e.inner.Error())
+}
+
+// Parse a docker file into a collection of buildable stages
+func Parse(ast *parser.Node) (stages []Stage, metaArgs []ArgCommand, err error) {
+	for _, n := range ast.Children {
+		cmd, err := ParseInstruction(n)
+		if err != nil {
+			return nil, nil, &parseError{inner: err, node: n}
+		}
+		if len(stages) == 0 {
+			// meta arg case
+			if a, isArg := cmd.(*ArgCommand); isArg {
+				metaArgs = append(metaArgs, *a)
+				continue
+			}
+		}
+		switch c := cmd.(type) {
+		case *Stage:
+			stages = append(stages, *c)
+		case Command:
+			stage, err := CurrentStage(stages)
+			if err != nil {
+				return nil, nil, err
+			}
+			stage.AddCommand(c)
+		default:
+			return nil, nil, errors.Errorf("%T is not a command type", cmd)
+		}
+
+	}
+	return stages, metaArgs, nil
+}
+
+func parseKvps(args []string, cmdName string) (KeyValuePairs, error) {
+	if len(args) == 0 {
+		return nil, errAtLeastOneArgument(cmdName)
+	}
+	if len(args)%2 != 0 {
+		// should never get here, but just in case
+		return nil, errTooManyArguments(cmdName)
+	}
+	var res KeyValuePairs
+	for j := 0; j < len(args); j += 2 {
+		if len(args[j]) == 0 {
+			return nil, errBlankCommandNames(cmdName)
+		}
+		name := args[j]
+		value := args[j+1]
+		res = append(res, KeyValuePair{Key: name, Value: value})
+	}
+	return res, nil
+}
+
+func parseEnv(req parseRequest) (*EnvCommand, error) {
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	envs, err := parseKvps(req.args, "ENV")
+	if err != nil {
+		return nil, err
+	}
+	return &EnvCommand{
+		Env:             envs,
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+}
+
+func parseMaintainer(req parseRequest) (*MaintainerCommand, error) {
+	if len(req.args) != 1 {
+		return nil, errExactlyOneArgument("MAINTAINER")
+	}
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	return &MaintainerCommand{
+		Maintainer:      req.args[0],
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+}
+
+func parseLabel(req parseRequest) (*LabelCommand, error) {
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+
+	labels, err := parseKvps(req.args, "LABEL")
+	if err != nil {
+		return nil, err
+	}
+
+	return &LabelCommand{
+		Labels:          labels,
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+}
+
+func parseAdd(req parseRequest) (*AddCommand, error) {
+	if len(req.args) < 2 {
+		return nil, errNoDestinationArgument("ADD")
+	}
+	flChown := req.flags.AddString("chown", "")
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	return &AddCommand{
+		SourcesAndDest:  SourcesAndDest(req.args),
+		withNameAndCode: newWithNameAndCode(req),
+		Chown:           flChown.Value,
+	}, nil
+}
+
+func parseCopy(req parseRequest) (*CopyCommand, error) {
+	if len(req.args) < 2 {
+		return nil, errNoDestinationArgument("COPY")
+	}
+	flChown := req.flags.AddString("chown", "")
+	flFrom := req.flags.AddString("from", "")
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	return &CopyCommand{
+		SourcesAndDest:  SourcesAndDest(req.args),
+		From:            flFrom.Value,
+		withNameAndCode: newWithNameAndCode(req),
+		Chown:           flChown.Value,
+	}, nil
+}
+
+func parseFrom(req parseRequest) (*Stage, error) {
+	stageName, err := parseBuildStageName(req.args)
+	if err != nil {
+		return nil, err
+	}
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	code := strings.TrimSpace(req.original)
+
+	return &Stage{
+		BaseName:   req.args[0],
+		Name:       stageName,
+		SourceCode: code,
+		Commands:   []Command{},
+	}, nil
+
+}
+
+func parseBuildStageName(args []string) (string, error) {
+	stageName := ""
+	switch {
+	case len(args) == 3 && strings.EqualFold(args[1], "as"):
+		stageName = strings.ToLower(args[2])
+		if ok, _ := regexp.MatchString("^[a-z][a-z0-9-_\\.]*$", stageName); !ok {
+			return "", errors.Errorf("invalid name for build stage: %q, name can't start with a number or contain symbols", stageName)
+		}
+	case len(args) != 1:
+		return "", errors.New("FROM requires either one or three arguments")
+	}
+
+	return stageName, nil
+}
+
+func parseOnBuild(req parseRequest) (*OnbuildCommand, error) {
+	if len(req.args) == 0 {
+		return nil, errAtLeastOneArgument("ONBUILD")
+	}
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+
+	triggerInstruction := strings.ToUpper(strings.TrimSpace(req.args[0]))
+	switch strings.ToUpper(triggerInstruction) {
+	case "ONBUILD":
+		return nil, errors.New("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
+	case "MAINTAINER", "FROM":
+		return nil, fmt.Errorf("%s isn't allowed as an ONBUILD trigger", triggerInstruction)
+	}
+
+	original := regexp.MustCompile(`(?i)^\s*ONBUILD\s*`).ReplaceAllString(req.original, "")
+	return &OnbuildCommand{
+		Expression:      original,
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+
+}
+
+func parseWorkdir(req parseRequest) (*WorkdirCommand, error) {
+	if len(req.args) != 1 {
+		return nil, errExactlyOneArgument("WORKDIR")
+	}
+
+	err := req.flags.Parse()
+	if err != nil {
+		return nil, err
+	}
+	return &WorkdirCommand{
+		Path:            req.args[0],
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+
+}
+
+func parseShellDependentCommand(req parseRequest, emptyAsNil bool) ShellDependantCmdLine {
+	args := handleJSONArgs(req.args, req.attributes)
+	cmd := strslice.StrSlice(args)
+	if emptyAsNil && len(cmd) == 0 {
+		cmd = nil
+	}
+	return ShellDependantCmdLine{
+		CmdLine:      cmd,
+		PrependShell: !req.attributes["json"],
+	}
+}
+
+func parseRun(req parseRequest) (*RunCommand, error) {
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	return &RunCommand{
+		ShellDependantCmdLine: parseShellDependentCommand(req, false),
+		withNameAndCode:       newWithNameAndCode(req),
+	}, nil
+
+}
+
+func parseCmd(req parseRequest) (*CmdCommand, error) {
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	return &CmdCommand{
+		ShellDependantCmdLine: parseShellDependentCommand(req, false),
+		withNameAndCode:       newWithNameAndCode(req),
+	}, nil
+
+}
+
+func parseEntrypoint(req parseRequest) (*EntrypointCommand, error) {
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+
+	cmd := &EntrypointCommand{
+		ShellDependantCmdLine: parseShellDependentCommand(req, true),
+		withNameAndCode:       newWithNameAndCode(req),
+	}
+
+	return cmd, nil
+}
+
+// parseOptInterval(flag) is the duration of flag.Value, or 0 if
+// empty. An error is reported if the value is given and less than minimum duration.
+func parseOptInterval(f *Flag) (time.Duration, error) {
+	s := f.Value
+	if s == "" {
+		return 0, nil
+	}
+	d, err := time.ParseDuration(s)
+	if err != nil {
+		return 0, err
+	}
+	if d < container.MinimumDuration {
+		return 0, fmt.Errorf("Interval %#v cannot be less than %s", f.name, container.MinimumDuration)
+	}
+	return d, nil
+}
+func parseHealthcheck(req parseRequest) (*HealthCheckCommand, error) {
+	if len(req.args) == 0 {
+		return nil, errAtLeastOneArgument("HEALTHCHECK")
+	}
+	cmd := &HealthCheckCommand{
+		withNameAndCode: newWithNameAndCode(req),
+	}
+
+	typ := strings.ToUpper(req.args[0])
+	args := req.args[1:]
+	if typ == "NONE" {
+		if len(args) != 0 {
+			return nil, errors.New("HEALTHCHECK NONE takes no arguments")
+		}
+		test := strslice.StrSlice{typ}
+		cmd.Health = &container.HealthConfig{
+			Test: test,
+		}
+	} else {
+
+		healthcheck := container.HealthConfig{}
+
+		flInterval := req.flags.AddString("interval", "")
+		flTimeout := req.flags.AddString("timeout", "")
+		flStartPeriod := req.flags.AddString("start-period", "")
+		flRetries := req.flags.AddString("retries", "")
+
+		if err := req.flags.Parse(); err != nil {
+			return nil, err
+		}
+
+		switch typ {
+		case "CMD":
+			cmdSlice := handleJSONArgs(args, req.attributes)
+			if len(cmdSlice) == 0 {
+				return nil, errors.New("Missing command after HEALTHCHECK CMD")
+			}
+
+			if !req.attributes["json"] {
+				typ = "CMD-SHELL"
+			}
+
+			healthcheck.Test = strslice.StrSlice(append([]string{typ}, cmdSlice...))
+		default:
+			return nil, fmt.Errorf("Unknown type %#v in HEALTHCHECK (try CMD)", typ)
+		}
+
+		interval, err := parseOptInterval(flInterval)
+		if err != nil {
+			return nil, err
+		}
+		healthcheck.Interval = interval
+
+		timeout, err := parseOptInterval(flTimeout)
+		if err != nil {
+			return nil, err
+		}
+		healthcheck.Timeout = timeout
+
+		startPeriod, err := parseOptInterval(flStartPeriod)
+		if err != nil {
+			return nil, err
+		}
+		healthcheck.StartPeriod = startPeriod
+
+		if flRetries.Value != "" {
+			retries, err := strconv.ParseInt(flRetries.Value, 10, 32)
+			if err != nil {
+				return nil, err
+			}
+			if retries < 1 {
+				return nil, fmt.Errorf("--retries must be at least 1 (not %d)", retries)
+			}
+			healthcheck.Retries = int(retries)
+		} else {
+			healthcheck.Retries = 0
+		}
+
+		cmd.Health = &healthcheck
+	}
+	return cmd, nil
+}
+
+func parseExpose(req parseRequest) (*ExposeCommand, error) {
+	portsTab := req.args
+
+	if len(req.args) == 0 {
+		return nil, errAtLeastOneArgument("EXPOSE")
+	}
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+
+	sort.Strings(portsTab)
+	return &ExposeCommand{
+		Ports:           portsTab,
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+}
+
+func parseUser(req parseRequest) (*UserCommand, error) {
+	if len(req.args) != 1 {
+		return nil, errExactlyOneArgument("USER")
+	}
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	return &UserCommand{
+		User:            req.args[0],
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+}
+
+func parseVolume(req parseRequest) (*VolumeCommand, error) {
+	if len(req.args) == 0 {
+		return nil, errAtLeastOneArgument("VOLUME")
+	}
+
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+
+	cmd := &VolumeCommand{
+		withNameAndCode: newWithNameAndCode(req),
+	}
+
+	for _, v := range req.args {
+		v = strings.TrimSpace(v)
+		if v == "" {
+			return nil, errors.New("VOLUME specified can not be an empty string")
+		}
+		cmd.Volumes = append(cmd.Volumes, v)
+	}
+	return cmd, nil
+
+}
+
+func parseStopSignal(req parseRequest) (*StopSignalCommand, error) {
+	if len(req.args) != 1 {
+		return nil, errExactlyOneArgument("STOPSIGNAL")
+	}
+	sig := req.args[0]
+
+	cmd := &StopSignalCommand{
+		Signal:          sig,
+		withNameAndCode: newWithNameAndCode(req),
+	}
+	return cmd, nil
+
+}
+
+func parseArg(req parseRequest) (*ArgCommand, error) {
+	if len(req.args) != 1 {
+		return nil, errExactlyOneArgument("ARG")
+	}
+
+	var (
+		name     string
+		newValue *string
+	)
+
+	arg := req.args[0]
+	// 'arg' can just be a name or name-value pair. Note that this is different
+	// from 'env' that handles the split of name and value at the parser level.
+	// The reason for doing it differently for 'arg' is that we support just
+	// defining an arg and not assign it a value (while 'env' always expects a
+	// name-value pair). If possible, it will be good to harmonize the two.
+	if strings.Contains(arg, "=") {
+		parts := strings.SplitN(arg, "=", 2)
+		if len(parts[0]) == 0 {
+			return nil, errBlankCommandNames("ARG")
+		}
+
+		name = parts[0]
+		newValue = &parts[1]
+	} else {
+		name = arg
+	}
+
+	return &ArgCommand{
+		Key:             name,
+		Value:           newValue,
+		withNameAndCode: newWithNameAndCode(req),
+	}, nil
+}
+
+func parseShell(req parseRequest) (*ShellCommand, error) {
+	if err := req.flags.Parse(); err != nil {
+		return nil, err
+	}
+	shellSlice := handleJSONArgs(req.args, req.attributes)
+	switch {
+	case len(shellSlice) == 0:
+		// SHELL []
+		return nil, errAtLeastOneArgument("SHELL")
+	case req.attributes["json"]:
+		// SHELL ["powershell", "-command"]
+
+		return &ShellCommand{
+			Shell:           strslice.StrSlice(shellSlice),
+			withNameAndCode: newWithNameAndCode(req),
+		}, nil
+	default:
+		// SHELL powershell -command - not JSON
+		return nil, errNotJSON("SHELL", req.original)
+	}
+}
+
+func errAtLeastOneArgument(command string) error {
+	return errors.Errorf("%s requires at least one argument", command)
+}
+
+func errExactlyOneArgument(command string) error {
+	return errors.Errorf("%s requires exactly one argument", command)
+}
+
+func errNoDestinationArgument(command string) error {
+	return errors.Errorf("%s requires at least two arguments, but only one was provided. Destination could not be determined.", command)
+}
+
+func errBlankCommandNames(command string) error {
+	return errors.Errorf("%s names can not be blank", command)
+}
+
+func errTooManyArguments(command string) error {
+	return errors.Errorf("Bad input to %s, too many arguments", command)
+}
diff --git a/builder/dockerfile/instructions/parse_test.go b/builder/dockerfile/instructions/parse_test.go
new file mode 100644
index 0000000..f15eaca
--- /dev/null
+++ b/builder/dockerfile/instructions/parse_test.go
@@ -0,0 +1,204 @@
+package instructions
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/docker/docker/builder/dockerfile/command"
+	"github.com/docker/docker/builder/dockerfile/parser"
+	"github.com/docker/docker/internal/testutil"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestCommandsExactlyOneArgument(t *testing.T) {
+	commands := []string{
+		"MAINTAINER",
+		"WORKDIR",
+		"USER",
+		"STOPSIGNAL",
+	}
+
+	for _, command := range commands {
+		ast, err := parser.Parse(strings.NewReader(command))
+		require.NoError(t, err)
+		_, err = ParseInstruction(ast.AST.Children[0])
+		assert.EqualError(t, err, errExactlyOneArgument(command).Error())
+	}
+}
+
+func TestCommandsAtLeastOneArgument(t *testing.T) {
+	commands := []string{
+		"ENV",
+		"LABEL",
+		"ONBUILD",
+		"HEALTHCHECK",
+		"EXPOSE",
+		"VOLUME",
+	}
+
+	for _, command := range commands {
+		ast, err := parser.Parse(strings.NewReader(command))
+		require.NoError(t, err)
+		_, err = ParseInstruction(ast.AST.Children[0])
+		assert.EqualError(t, err, errAtLeastOneArgument(command).Error())
+	}
+}
+
+func TestCommandsNoDestinationArgument(t *testing.T) {
+	commands := []string{
+		"ADD",
+		"COPY",
+	}
+
+	for _, command := range commands {
+		ast, err := parser.Parse(strings.NewReader(command + " arg1"))
+		require.NoError(t, err)
+		_, err = ParseInstruction(ast.AST.Children[0])
+		assert.EqualError(t, err, errNoDestinationArgument(command).Error())
+	}
+}
+
+func TestCommandsTooManyArguments(t *testing.T) {
+	commands := []string{
+		"ENV",
+		"LABEL",
+	}
+
+	for _, command := range commands {
+		node := &parser.Node{
+			Original: command + "arg1 arg2 arg3",
+			Value:    strings.ToLower(command),
+			Next: &parser.Node{
+				Value: "arg1",
+				Next: &parser.Node{
+					Value: "arg2",
+					Next: &parser.Node{
+						Value: "arg3",
+					},
+				},
+			},
+		}
+		_, err := ParseInstruction(node)
+		assert.EqualError(t, err, errTooManyArguments(command).Error())
+	}
+}
+
+func TestCommandsBlankNames(t *testing.T) {
+	commands := []string{
+		"ENV",
+		"LABEL",
+	}
+
+	for _, command := range commands {
+		node := &parser.Node{
+			Original: command + " =arg2",
+			Value:    strings.ToLower(command),
+			Next: &parser.Node{
+				Value: "",
+				Next: &parser.Node{
+					Value: "arg2",
+				},
+			},
+		}
+		_, err := ParseInstruction(node)
+		assert.EqualError(t, err, errBlankCommandNames(command).Error())
+	}
+}
+
+func TestHealthCheckCmd(t *testing.T) {
+	node := &parser.Node{
+		Value: command.Healthcheck,
+		Next: &parser.Node{
+			Value: "CMD",
+			Next: &parser.Node{
+				Value: "hello",
+				Next: &parser.Node{
+					Value: "world",
+				},
+			},
+		},
+	}
+	cmd, err := ParseInstruction(node)
+	assert.NoError(t, err)
+	hc, ok := cmd.(*HealthCheckCommand)
+	assert.True(t, ok)
+	expected := []string{"CMD-SHELL", "hello world"}
+	assert.Equal(t, expected, hc.Health.Test)
+}
+
+func TestParseOptInterval(t *testing.T) {
+	flInterval := &Flag{
+		name:     "interval",
+		flagType: stringType,
+		Value:    "50ns",
+	}
+	_, err := parseOptInterval(flInterval)
+	testutil.ErrorContains(t, err, "cannot be less than 1ms")
+
+	flInterval.Value = "1ms"
+	_, err = parseOptInterval(flInterval)
+	require.NoError(t, err)
+}
+
+func TestErrorCases(t *testing.T) {
+	cases := []struct {
+		name          string
+		dockerfile    string
+		expectedError string
+	}{
+		{
+			name: "copyEmptyWhitespace",
+			dockerfile: `COPY	
+		quux \
+      bar`,
+			expectedError: "COPY requires at least two arguments",
+		},
+		{
+			name:          "ONBUILD forbidden FROM",
+			dockerfile:    "ONBUILD FROM scratch",
+			expectedError: "FROM isn't allowed as an ONBUILD trigger",
+		},
+		{
+			name:          "ONBUILD forbidden MAINTAINER",
+			dockerfile:    "ONBUILD MAINTAINER docker.io",
+			expectedError: "MAINTAINER isn't allowed as an ONBUILD trigger",
+		},
+		{
+			name:          "ARG two arguments",
+			dockerfile:    "ARG foo bar",
+			expectedError: "ARG requires exactly one argument",
+		},
+		{
+			name:          "MAINTAINER unknown flag",
+			dockerfile:    "MAINTAINER --boo joe@example.com",
+			expectedError: "Unknown flag: boo",
+		},
+		{
+			name:          "Chaining ONBUILD",
+			dockerfile:    `ONBUILD ONBUILD RUN touch foobar`,
+			expectedError: "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed",
+		},
+		{
+			name:          "Invalid instruction",
+			dockerfile:    `foo bar`,
+			expectedError: "unknown instruction: FOO",
+		},
+	}
+	for _, c := range cases {
+		r := strings.NewReader(c.dockerfile)
+		ast, err := parser.Parse(r)
+
+		if err != nil {
+			t.Fatalf("Error when parsing Dockerfile: %s", err)
+		}
+		n := ast.AST.Children[0]
+		_, err = ParseInstruction(n)
+		if err != nil {
+			testutil.ErrorContains(t, err, c.expectedError)
+			return
+		}
+		t.Fatalf("No error when executing test %s", c.name)
+	}
+
+}
diff --git a/builder/dockerfile/support.go b/builder/dockerfile/instructions/support.go
similarity index 95%
rename from builder/dockerfile/support.go
rename to builder/dockerfile/instructions/support.go
index e875889..beefe77 100644
--- a/builder/dockerfile/support.go
+++ b/builder/dockerfile/instructions/support.go
@@ -1,4 +1,4 @@
-package dockerfile
+package instructions
 
 import "strings"
 
diff --git a/builder/dockerfile/support_test.go b/builder/dockerfile/instructions/support_test.go
similarity index 98%
rename from builder/dockerfile/support_test.go
rename to builder/dockerfile/instructions/support_test.go
index 7cc6fe9..2b888dc 100644
--- a/builder/dockerfile/support_test.go
+++ b/builder/dockerfile/instructions/support_test.go
@@ -1,4 +1,4 @@
-package dockerfile
+package instructions
 
 import "testing"
 
diff --git a/builder/dockerfile/internals.go b/builder/dockerfile/internals.go
index c0d6081..be46d31 100644
--- a/builder/dockerfile/internals.go
+++ b/builder/dockerfile/internals.go
@@ -7,16 +7,74 @@
 	"crypto/sha256"
 	"encoding/hex"
 	"fmt"
+	"io"
+	"os"
+	"path"
+	"path/filepath"
+	"strconv"
 	"strings"
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/image"
+	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/chrootarchive"
+	"github.com/docker/docker/pkg/containerfs"
+	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/docker/docker/pkg/symlink"
+	"github.com/docker/docker/pkg/system"
+	lcUser "github.com/opencontainers/runc/libcontainer/user"
 	"github.com/pkg/errors"
 )
 
+// Archiver defines an interface for copying files from one destination to
+// another using Tar/Untar.
+type Archiver interface {
+	TarUntar(src, dst string) error
+	UntarPath(src, dst string) error
+	CopyWithTar(src, dst string) error
+	CopyFileWithTar(src, dst string) error
+	IDMappings() *idtools.IDMappings
+}
+
+// The builder will use the following interfaces if the container fs implements
+// these for optimized copies to and from the container.
+type extractor interface {
+	ExtractArchive(src io.Reader, dst string, opts *archive.TarOptions) error
+}
+
+type archiver interface {
+	ArchivePath(src string, opts *archive.TarOptions) (io.ReadCloser, error)
+}
+
+// helper functions to get tar/untar func
+func untarFunc(i interface{}) containerfs.UntarFunc {
+	if ea, ok := i.(extractor); ok {
+		return ea.ExtractArchive
+	}
+	return chrootarchive.Untar
+}
+
+func tarFunc(i interface{}) containerfs.TarFunc {
+	if ap, ok := i.(archiver); ok {
+		return ap.ArchivePath
+	}
+	return archive.TarWithOptions
+}
+
+func (b *Builder) getArchiver(src, dst containerfs.Driver) Archiver {
+	t, u := tarFunc(src), untarFunc(dst)
+	return &containerfs.Archiver{
+		SrcDriver:     src,
+		DstDriver:     dst,
+		Tar:           t,
+		Untar:         u,
+		IDMappingsVar: b.idMappings,
+	}
+}
+
 func (b *Builder) commit(dispatchState *dispatchState, comment string) error {
 	if b.disableCommit {
 		return nil
@@ -60,7 +118,6 @@
 	}
 
 	dispatchState.imageID = imageID
-	b.buildStages.update(imageID)
 	return nil
 }
 
@@ -100,17 +157,22 @@
 
 	state.imageID = exportedImage.ImageID()
 	b.imageSources.Add(newImageMount(exportedImage, newLayer))
-	b.buildStages.update(state.imageID)
 	return nil
 }
 
 func (b *Builder) performCopy(state *dispatchState, inst copyInstruction) error {
 	srcHash := getSourceHashFromInfos(inst.infos)
 
+	var chownComment string
+	if inst.chownStr != "" {
+		chownComment = fmt.Sprintf("--chown=%s", inst.chownStr)
+	}
+	commentStr := fmt.Sprintf("%s %s%s in %s ", inst.cmdName, chownComment, srcHash, inst.dest)
+
 	// TODO: should this have been using origPaths instead of srcHash in the comment?
 	runConfigWithCommentCmd := copyRunConfig(
 		state.runConfig,
-		withCmdCommentString(fmt.Sprintf("%s %s in %s ", inst.cmdName, srcHash, inst.dest), b.platform))
+		withCmdCommentString(commentStr, b.platform))
 	hit, err := b.probeCache(state, runConfigWithCommentCmd)
 	if err != nil || hit {
 		return err
@@ -120,16 +182,29 @@
 	if err != nil {
 		return errors.Wrapf(err, "failed to get destination image %q", state.imageID)
 	}
-	destInfo, err := createDestInfo(state.runConfig.WorkingDir, inst, imageMount)
+
+	destInfo, err := createDestInfo(state.runConfig.WorkingDir, inst, imageMount, b.platform)
 	if err != nil {
 		return err
 	}
 
-	opts := copyFileOptions{
-		decompress: inst.allowLocalDecompression,
-		archiver:   b.archiver,
+	chownPair := b.idMappings.RootPair()
+	// if a chown was requested, perform the steps to get the uid, gid
+	// translated (if necessary because of user namespaces), and replace
+	// the root pair with the chown pair for copy operations
+	if inst.chownStr != "" {
+		chownPair, err = parseChownFlag(inst.chownStr, destInfo.root.Path(), b.idMappings)
+		if err != nil {
+			return errors.Wrapf(err, "unable to convert uid/gid chown string to host mapping")
+		}
 	}
+
 	for _, info := range inst.infos {
+		opts := copyFileOptions{
+			decompress: inst.allowLocalDecompression,
+			archiver:   b.getArchiver(info.root, destInfo.root),
+			chownPair:  chownPair,
+		}
 		if err := performCopyForInfo(destInfo, info, opts); err != nil {
 			return errors.Wrapf(err, "failed to copy files")
 		}
@@ -137,10 +212,86 @@
 	return b.exportImage(state, imageMount, runConfigWithCommentCmd)
 }
 
-func createDestInfo(workingDir string, inst copyInstruction, imageMount *imageMount) (copyInfo, error) {
+func parseChownFlag(chown, ctrRootPath string, idMappings *idtools.IDMappings) (idtools.IDPair, error) {
+	var userStr, grpStr string
+	parts := strings.Split(chown, ":")
+	if len(parts) > 2 {
+		return idtools.IDPair{}, errors.New("invalid chown string format: " + chown)
+	}
+	if len(parts) == 1 {
+		// if no group specified, use the user spec as group as well
+		userStr, grpStr = parts[0], parts[0]
+	} else {
+		userStr, grpStr = parts[0], parts[1]
+	}
+
+	passwdPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "passwd"), ctrRootPath)
+	if err != nil {
+		return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/passwd path in container rootfs")
+	}
+	groupPath, err := symlink.FollowSymlinkInScope(filepath.Join(ctrRootPath, "etc", "group"), ctrRootPath)
+	if err != nil {
+		return idtools.IDPair{}, errors.Wrapf(err, "can't resolve /etc/group path in container rootfs")
+	}
+	uid, err := lookupUser(userStr, passwdPath)
+	if err != nil {
+		return idtools.IDPair{}, errors.Wrapf(err, "can't find uid for user "+userStr)
+	}
+	gid, err := lookupGroup(grpStr, groupPath)
+	if err != nil {
+		return idtools.IDPair{}, errors.Wrapf(err, "can't find gid for group "+grpStr)
+	}
+
+	// convert as necessary because of user namespaces
+	chownPair, err := idMappings.ToHost(idtools.IDPair{UID: uid, GID: gid})
+	if err != nil {
+		return idtools.IDPair{}, errors.Wrapf(err, "unable to convert uid/gid to host mapping")
+	}
+	return chownPair, nil
+}
+
+func lookupUser(userStr, filepath string) (int, error) {
+	// if the string is actually a uid integer, parse to int and return
+	// as we don't need to translate with the help of files
+	uid, err := strconv.Atoi(userStr)
+	if err == nil {
+		return uid, nil
+	}
+	users, err := lcUser.ParsePasswdFileFilter(filepath, func(u lcUser.User) bool {
+		return u.Name == userStr
+	})
+	if err != nil {
+		return 0, err
+	}
+	if len(users) == 0 {
+		return 0, errors.New("no such user: " + userStr)
+	}
+	return users[0].Uid, nil
+}
+
+func lookupGroup(groupStr, filepath string) (int, error) {
+	// if the string is actually a gid integer, parse to int and return
+	// as we don't need to translate with the help of files
+	gid, err := strconv.Atoi(groupStr)
+	if err == nil {
+		return gid, nil
+	}
+	groups, err := lcUser.ParseGroupFileFilter(filepath, func(g lcUser.Group) bool {
+		return g.Name == groupStr
+	})
+	if err != nil {
+		return 0, err
+	}
+	if len(groups) == 0 {
+		return 0, errors.New("no such group: " + groupStr)
+	}
+	return groups[0].Gid, nil
+}
+
+func createDestInfo(workingDir string, inst copyInstruction, imageMount *imageMount, platform string) (copyInfo, error) {
 	// Twiddle the destination when it's a relative path - meaning, make it
 	// relative to the WORKINGDIR
-	dest, err := normaliseDest(workingDir, inst.dest)
+	dest, err := normalizeDest(workingDir, inst.dest, platform)
 	if err != nil {
 		return copyInfo{}, errors.Wrapf(err, "invalid %s", inst.cmdName)
 	}
@@ -153,6 +304,63 @@
 	return newCopyInfoFromSource(destMount, dest, ""), nil
 }
 
+// normalizeDest normalises the destination of a COPY/ADD command in a
+// platform semantically consistent way.
+func normalizeDest(workingDir, requested string, platform string) (string, error) {
+	dest := fromSlash(requested, platform)
+	endsInSlash := strings.HasSuffix(dest, string(separator(platform)))
+
+	if platform != "windows" {
+		if !path.IsAbs(requested) {
+			dest = path.Join("/", filepath.ToSlash(workingDir), dest)
+			// Make sure we preserve any trailing slash
+			if endsInSlash {
+				dest += "/"
+			}
+		}
+		return dest, nil
+	}
+
+	// We are guaranteed that the working directory is already consistent,
+	// However, Windows also has, for now, the limitation that ADD/COPY can
+	// only be done to the system drive, not any drives that might be present
+	// as a result of a bind mount.
+	//
+	// So... if the path requested is Linux-style absolute (/foo or \\foo),
+	// we assume it is the system drive. If it is a Windows-style absolute
+	// (DRIVE:\\foo), error if DRIVE is not C. And finally, ensure we
+	// strip any configured working directories drive letter so that it
+	// can be subsequently legitimately converted to a Windows volume-style
+	// pathname.
+
+	// Not a typo - filepath.IsAbs, not system.IsAbs on this next check as
+	// we only want to validate where the DriveColon part has been supplied.
+	if filepath.IsAbs(dest) {
+		if strings.ToUpper(string(dest[0])) != "C" {
+			return "", fmt.Errorf("Windows does not support destinations not on the system drive (C:)")
+		}
+		dest = dest[2:] // Strip the drive letter
+	}
+
+	// Cannot handle relative where WorkingDir is not the system drive.
+	if len(workingDir) > 0 {
+		if ((len(workingDir) > 1) && !system.IsAbs(workingDir[2:])) || (len(workingDir) == 1) {
+			return "", fmt.Errorf("Current WorkingDir %s is not platform consistent", workingDir)
+		}
+		if !system.IsAbs(dest) {
+			if string(workingDir[0]) != "C" {
+				return "", fmt.Errorf("Windows does not support relative paths when WORKDIR is not the system drive")
+			}
+			dest = filepath.Join(string(os.PathSeparator), workingDir[2:], dest)
+			// Make sure we preserve any trailing slash
+			if endsInSlash {
+				dest += string(os.PathSeparator)
+			}
+		}
+	}
+	return dest, nil
+}
+
 // For backwards compat, if there's just one info then use it as the
 // cache look-up string, otherwise hash 'em all into one
 func getSourceHashFromInfos(infos []copyInfo) string {
@@ -243,8 +451,7 @@
 	}
 	fmt.Fprint(b.Stdout, " ---> Using cache\n")
 
-	dispatchState.imageID = string(cachedID)
-	b.buildStages.update(dispatchState.imageID)
+	dispatchState.imageID = cachedID
 	return true, nil
 }
 
@@ -298,3 +505,19 @@
 		ExtraHosts: options.ExtraHosts,
 	}
 }
+
+// fromSlash works like filepath.FromSlash but with a given OS platform field
+func fromSlash(path, platform string) string {
+	if platform == "windows" {
+		return strings.Replace(path, "/", "\\", -1)
+	}
+	return path
+}
+
+// separator returns a OS path separator for the given OS platform
+func separator(platform string) byte {
+	if platform == "windows" {
+		return '\\'
+	}
+	return '/'
+}
diff --git a/builder/dockerfile/internals_test.go b/builder/dockerfile/internals_test.go
index 8073cc6..ed7b4cd 100644
--- a/builder/dockerfile/internals_test.go
+++ b/builder/dockerfile/internals_test.go
@@ -2,6 +2,8 @@
 
 import (
 	"fmt"
+	"os"
+	"path/filepath"
 	"runtime"
 	"testing"
 
@@ -11,6 +13,7 @@
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/builder/remotecontext"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/idtools"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -129,3 +132,130 @@
 	}
 
 }
+
+func TestChownFlagParsing(t *testing.T) {
+	testFiles := map[string]string{
+		"passwd": `root:x:0:0::/bin:/bin/false
+bin:x:1:1::/bin:/bin/false
+wwwwww:x:21:33::/bin:/bin/false
+unicorn:x:1001:1002::/bin:/bin/false
+		`,
+		"group": `root:x:0:
+bin:x:1:
+wwwwww:x:33:
+unicorn:x:1002:
+somegrp:x:5555:
+othergrp:x:6666:
+		`,
+	}
+	// test mappings for validating use of maps
+	idMaps := []idtools.IDMap{
+		{
+			ContainerID: 0,
+			HostID:      100000,
+			Size:        65536,
+		},
+	}
+	remapped := idtools.NewIDMappingsFromMaps(idMaps, idMaps)
+	unmapped := &idtools.IDMappings{}
+
+	contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test")
+	defer cleanup()
+
+	if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0755); err != nil {
+		t.Fatalf("error creating test directory: %v", err)
+	}
+
+	for filename, content := range testFiles {
+		createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0644)
+	}
+
+	// positive tests
+	for _, testcase := range []struct {
+		name      string
+		chownStr  string
+		idMapping *idtools.IDMappings
+		expected  idtools.IDPair
+	}{
+		{
+			name:      "UIDNoMap",
+			chownStr:  "1",
+			idMapping: unmapped,
+			expected:  idtools.IDPair{UID: 1, GID: 1},
+		},
+		{
+			name:      "UIDGIDNoMap",
+			chownStr:  "0:1",
+			idMapping: unmapped,
+			expected:  idtools.IDPair{UID: 0, GID: 1},
+		},
+		{
+			name:      "UIDWithMap",
+			chownStr:  "0",
+			idMapping: remapped,
+			expected:  idtools.IDPair{UID: 100000, GID: 100000},
+		},
+		{
+			name:      "UIDGIDWithMap",
+			chownStr:  "1:33",
+			idMapping: remapped,
+			expected:  idtools.IDPair{UID: 100001, GID: 100033},
+		},
+		{
+			name:      "UserNoMap",
+			chownStr:  "bin:5555",
+			idMapping: unmapped,
+			expected:  idtools.IDPair{UID: 1, GID: 5555},
+		},
+		{
+			name:      "GroupWithMap",
+			chownStr:  "0:unicorn",
+			idMapping: remapped,
+			expected:  idtools.IDPair{UID: 100000, GID: 101002},
+		},
+		{
+			name:      "UserOnlyWithMap",
+			chownStr:  "unicorn",
+			idMapping: remapped,
+			expected:  idtools.IDPair{UID: 101001, GID: 101002},
+		},
+	} {
+		t.Run(testcase.name, func(t *testing.T) {
+			idPair, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
+			require.NoError(t, err, "Failed to parse chown flag: %q", testcase.chownStr)
+			assert.Equal(t, testcase.expected, idPair, "chown flag mapping failure")
+		})
+	}
+
+	// error tests
+	for _, testcase := range []struct {
+		name      string
+		chownStr  string
+		idMapping *idtools.IDMappings
+		descr     string
+	}{
+		{
+			name:      "BadChownFlagFormat",
+			chownStr:  "bob:1:555",
+			idMapping: unmapped,
+			descr:     "invalid chown string format: bob:1:555",
+		},
+		{
+			name:      "UserNoExist",
+			chownStr:  "bob",
+			idMapping: unmapped,
+			descr:     "can't find uid for user bob: no such user: bob",
+		},
+		{
+			name:      "GroupNoExist",
+			chownStr:  "root:bob",
+			idMapping: unmapped,
+			descr:     "can't find gid for group bob: no such group: bob",
+		},
+	} {
+		t.Run(testcase.name, func(t *testing.T) {
+			_, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping)
+			assert.EqualError(t, err, testcase.descr, "Expected error string doesn't match")
+		})
+	}
+}
diff --git a/builder/dockerfile/internals_unix.go b/builder/dockerfile/internals_unix.go
deleted file mode 100644
index f4784e1..0000000
--- a/builder/dockerfile/internals_unix.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// +build !windows
-
-package dockerfile
-
-import (
-	"os"
-	"path/filepath"
-	"strings"
-
-	"github.com/docker/docker/pkg/system"
-)
-
-// normaliseDest normalises the destination of a COPY/ADD command in a
-// platform semantically consistent way.
-func normaliseDest(workingDir, requested string) (string, error) {
-	dest := filepath.FromSlash(requested)
-	endsInSlash := strings.HasSuffix(requested, string(os.PathSeparator))
-	if !system.IsAbs(requested) {
-		dest = filepath.Join(string(os.PathSeparator), filepath.FromSlash(workingDir), dest)
-		// Make sure we preserve any trailing slash
-		if endsInSlash {
-			dest += string(os.PathSeparator)
-		}
-	}
-	return dest, nil
-}
-
-func containsWildcards(name string) bool {
-	for i := 0; i < len(name); i++ {
-		ch := name[i]
-		if ch == '\\' {
-			i++
-		} else if ch == '*' || ch == '?' || ch == '[' {
-			return true
-		}
-	}
-	return false
-}
-
-func validateCopySourcePath(imageSource *imageMount, origPath string) error {
-	return nil
-}
diff --git a/builder/dockerfile/internals_windows.go b/builder/dockerfile/internals_windows.go
deleted file mode 100644
index bb32859..0000000
--- a/builder/dockerfile/internals_windows.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package dockerfile
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"github.com/docker/docker/pkg/system"
-	"github.com/pkg/errors"
-)
-
-// normaliseDest normalises the destination of a COPY/ADD command in a
-// platform semantically consistent way.
-func normaliseDest(workingDir, requested string) (string, error) {
-	dest := filepath.FromSlash(requested)
-	endsInSlash := strings.HasSuffix(dest, string(os.PathSeparator))
-
-	// We are guaranteed that the working directory is already consistent,
-	// However, Windows also has, for now, the limitation that ADD/COPY can
-	// only be done to the system drive, not any drives that might be present
-	// as a result of a bind mount.
-	//
-	// So... if the path requested is Linux-style absolute (/foo or \\foo),
-	// we assume it is the system drive. If it is a Windows-style absolute
-	// (DRIVE:\\foo), error if DRIVE is not C. And finally, ensure we
-	// strip any configured working directories drive letter so that it
-	// can be subsequently legitimately converted to a Windows volume-style
-	// pathname.
-
-	// Not a typo - filepath.IsAbs, not system.IsAbs on this next check as
-	// we only want to validate where the DriveColon part has been supplied.
-	if filepath.IsAbs(dest) {
-		if strings.ToUpper(string(dest[0])) != "C" {
-			return "", fmt.Errorf("Windows does not support destinations not on the system drive (C:)")
-		}
-		dest = dest[2:] // Strip the drive letter
-	}
-
-	// Cannot handle relative where WorkingDir is not the system drive.
-	if len(workingDir) > 0 {
-		if ((len(workingDir) > 1) && !system.IsAbs(workingDir[2:])) || (len(workingDir) == 1) {
-			return "", fmt.Errorf("Current WorkingDir %s is not platform consistent", workingDir)
-		}
-		if !system.IsAbs(dest) {
-			if string(workingDir[0]) != "C" {
-				return "", fmt.Errorf("Windows does not support relative paths when WORKDIR is not the system drive")
-			}
-			dest = filepath.Join(string(os.PathSeparator), workingDir[2:], dest)
-			// Make sure we preserve any trailing slash
-			if endsInSlash {
-				dest += string(os.PathSeparator)
-			}
-		}
-	}
-	return dest, nil
-}
-
-func containsWildcards(name string) bool {
-	for i := 0; i < len(name); i++ {
-		ch := name[i]
-		if ch == '*' || ch == '?' || ch == '[' {
-			return true
-		}
-	}
-	return false
-}
-
-var pathBlacklist = map[string]bool{
-	"c:\\":        true,
-	"c:\\windows": true,
-}
-
-func validateCopySourcePath(imageSource *imageMount, origPath string) error {
-	// validate windows paths from other images
-	if imageSource == nil {
-		return nil
-	}
-	origPath = filepath.FromSlash(origPath)
-	p := strings.ToLower(filepath.Clean(origPath))
-	if !filepath.IsAbs(p) {
-		if filepath.VolumeName(p) != "" {
-			if p[len(p)-2:] == ":." { // case where clean returns weird c:. paths
-				p = p[:len(p)-1]
-			}
-			p += "\\"
-		} else {
-			p = filepath.Join("c:\\", p)
-		}
-	}
-	if _, blacklisted := pathBlacklist[p]; blacklisted {
-		return errors.New("copy from c:\\ or c:\\windows is not allowed on windows")
-	}
-	return nil
-}
diff --git a/builder/dockerfile/internals_windows_test.go b/builder/dockerfile/internals_windows_test.go
index b4c8d4b..6ecc37b 100644
--- a/builder/dockerfile/internals_windows_test.go
+++ b/builder/dockerfile/internals_windows_test.go
@@ -6,11 +6,11 @@
 	"fmt"
 	"testing"
 
-	"github.com/docker/docker/pkg/testutil"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/stretchr/testify/assert"
 )
 
-func TestNormaliseDest(t *testing.T) {
+func TestNormalizeDest(t *testing.T) {
 	tests := []struct{ current, requested, expected, etext string }{
 		{``, `D:\`, ``, `Windows does not support destinations not on the system drive (C:)`},
 		{``, `e:/`, ``, `Windows does not support destinations not on the system drive (C:)`},
@@ -40,7 +40,7 @@
 	}
 	for _, testcase := range tests {
 		msg := fmt.Sprintf("Input: %s, %s", testcase.current, testcase.requested)
-		actual, err := normaliseDest(testcase.current, testcase.requested)
+		actual, err := normalizeDest(testcase.current, testcase.requested, "windows")
 		if testcase.etext == "" {
 			if !assert.NoError(t, err, msg) {
 				continue
diff --git a/builder/dockerfile/mockbackend_test.go b/builder/dockerfile/mockbackend_test.go
index adc2276..0f076b5 100644
--- a/builder/dockerfile/mockbackend_test.go
+++ b/builder/dockerfile/mockbackend_test.go
@@ -10,6 +10,7 @@
 	"github.com/docker/docker/builder"
 	containerpkg "github.com/docker/docker/container"
 	"github.com/docker/docker/layer"
+	"github.com/docker/docker/pkg/containerfs"
 	"golang.org/x/net/context"
 )
 
@@ -117,8 +118,8 @@
 	return nil
 }
 
-func (l *mockLayer) Mount() (string, error) {
-	return "mountPath", nil
+func (l *mockLayer) Mount() (containerfs.ContainerFS, error) {
+	return containerfs.NewLocalContainerFS("mountPath"), nil
 }
 
 func (l *mockLayer) Commit(string) (builder.ReleaseableLayer, error) {
diff --git a/builder/dockerfile/parser/line_parsers.go b/builder/dockerfile/parser/line_parsers.go
index d0e182e..2c375b7 100644
--- a/builder/dockerfile/parser/line_parsers.go
+++ b/builder/dockerfile/parser/line_parsers.go
@@ -19,7 +19,7 @@
 )
 
 var (
-	errDockerfileNotStringArray = errors.New("When using JSON array syntax, arrays must be comprised of strings only.")
+	errDockerfileNotStringArray = errors.New("when using JSON array syntax, arrays must be comprised of strings only")
 )
 
 const (
diff --git a/builder/dockerfile/parser/parser.go b/builder/dockerfile/parser/parser.go
index 7f07ff2..42a84c6 100644
--- a/builder/dockerfile/parser/parser.go
+++ b/builder/dockerfile/parser/parser.go
@@ -143,7 +143,7 @@
 	if len(tecMatch) != 0 {
 		for i, n := range tokenEscapeCommand.SubexpNames() {
 			if n == "escapechar" {
-				if d.escapeSeen == true {
+				if d.escapeSeen {
 					return errors.New("only one escape parser directive can be used")
 				}
 				d.escapeSeen = true
@@ -159,7 +159,7 @@
 		if len(tpcMatch) != 0 {
 			for i, n := range tokenPlatformCommand.SubexpNames() {
 				if n == "platform" {
-					if d.platformSeen == true {
+					if d.platformSeen {
 						return errors.New("only one platform parser directive can be used")
 					}
 					d.platformSeen = true
@@ -290,6 +290,10 @@
 			}
 			currentLine++
 
+			if isComment(scanner.Bytes()) {
+				// original line was a comment (processLine strips comments)
+				continue
+			}
 			if isEmptyContinuationLine(bytesRead) {
 				hasEmptyContinuationLine = true
 				continue
@@ -331,8 +335,12 @@
 	return bytes.TrimLeftFunc(src, unicode.IsSpace)
 }
 
+func isComment(line []byte) bool {
+	return tokenComment.Match(trimWhitespace(line))
+}
+
 func isEmptyContinuationLine(line []byte) bool {
-	return len(trimComments(trimWhitespace(line))) == 0
+	return len(trimWhitespace(line)) == 0
 }
 
 var utf8bom = []byte{0xEF, 0xBB, 0xBF}
diff --git a/builder/dockerfile/parser/parser_test.go b/builder/dockerfile/parser/parser_test.go
index bb057ec..5f354bb 100644
--- a/builder/dockerfile/parser/parser_test.go
+++ b/builder/dockerfile/parser/parser_test.go
@@ -141,6 +141,13 @@
 RUN another \
 
     thing
+RUN non-indented \
+# this is a comment
+   after-comment
+
+RUN indented \
+    # this is an indented comment
+    comment
 	`)
 
 	result, err := Parse(dockerfile)
diff --git a/builder/fscache/fscache.go b/builder/fscache/fscache.go
index 6333109..7cb4c5c 100644
--- a/builder/fscache/fscache.go
+++ b/builder/fscache/fscache.go
@@ -1,21 +1,26 @@
 package fscache
 
 import (
+	"archive/tar"
+	"crypto/sha256"
 	"encoding/json"
+	"hash"
 	"os"
 	"path/filepath"
 	"sort"
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/boltdb/bolt"
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/builder/remotecontext"
-	"github.com/docker/docker/client/session/filesync"
+	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/directory"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/docker/docker/pkg/tarsum"
+	"github.com/moby/buildkit/session/filesync"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"github.com/tonistiigi/fsutil"
 	"golang.org/x/net/context"
 	"golang.org/x/sync/singleflight"
@@ -212,7 +217,6 @@
 }
 
 type fsCacheStore struct {
-	root     string
 	mu       sync.Mutex
 	sources  map[string]*cachedSource
 	db       *bolt.DB
@@ -578,6 +582,10 @@
 	dc.supported = v
 }
 
+func (dc *detectChanges) ContentHasher() fsutil.ContentHasher {
+	return newTarsumHash
+}
+
 type wrappedContext struct {
 	builder.Source
 	closer func() error
@@ -607,3 +615,40 @@
 func (s sortableCacheSources) Swap(i, j int) {
 	s[i], s[j] = s[j], s[i]
 }
+
+func newTarsumHash(stat *fsutil.Stat) (hash.Hash, error) {
+	fi := &fsutil.StatInfo{stat}
+	p := stat.Path
+	if fi.IsDir() {
+		p += string(os.PathSeparator)
+	}
+	h, err := archive.FileInfoHeader(p, fi, stat.Linkname)
+	if err != nil {
+		return nil, err
+	}
+	h.Name = p
+	h.Uid = int(stat.Uid)
+	h.Gid = int(stat.Gid)
+	h.Linkname = stat.Linkname
+	if stat.Xattrs != nil {
+		h.Xattrs = make(map[string]string)
+		for k, v := range stat.Xattrs {
+			h.Xattrs[k] = string(v)
+		}
+	}
+
+	tsh := &tarsumHash{h: h, Hash: sha256.New()}
+	tsh.Reset()
+	return tsh, nil
+}
+
+// Reset resets the Hash to its initial state.
+func (tsh *tarsumHash) Reset() {
+	tsh.Hash.Reset()
+	tarsum.WriteV1Header(tsh.h, tsh.Hash)
+}
+
+type tarsumHash struct {
+	hash.Hash
+	h *tar.Header
+}
diff --git a/builder/fscache/fscache_test.go b/builder/fscache/fscache_test.go
index 2532a21..c327ec7 100644
--- a/builder/fscache/fscache_test.go
+++ b/builder/fscache/fscache_test.go
@@ -7,7 +7,7 @@
 	"testing"
 	"time"
 
-	"github.com/docker/docker/client/session/filesync"
+	"github.com/moby/buildkit/session/filesync"
 	"github.com/stretchr/testify/assert"
 	"golang.org/x/net/context"
 )
@@ -36,25 +36,25 @@
 	src1, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data", "bar"})
 	assert.Nil(t, err)
 
-	dt, err := ioutil.ReadFile(filepath.Join(src1.Root(), "foo"))
+	dt, err := ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo"))
 	assert.Nil(t, err)
 	assert.Equal(t, string(dt), "data")
 
 	// same id doesn't recalculate anything
 	src2, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data2", "bar"})
 	assert.Nil(t, err)
-	assert.Equal(t, src1.Root(), src2.Root())
+	assert.Equal(t, src1.Root().Path(), src2.Root().Path())
 
-	dt, err = ioutil.ReadFile(filepath.Join(src1.Root(), "foo"))
+	dt, err = ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo"))
 	assert.Nil(t, err)
 	assert.Equal(t, string(dt), "data")
 	assert.Nil(t, src2.Close())
 
 	src3, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo2", "data2", "bar"})
 	assert.Nil(t, err)
-	assert.NotEqual(t, src1.Root(), src3.Root())
+	assert.NotEqual(t, src1.Root().Path(), src3.Root().Path())
 
-	dt, err = ioutil.ReadFile(filepath.Join(src3.Root(), "foo2"))
+	dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo2"))
 	assert.Nil(t, err)
 	assert.Equal(t, string(dt), "data2")
 
@@ -71,12 +71,12 @@
 	// new upload with the same shared key shoutl overwrite
 	src4, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo3", "data3", "bar"})
 	assert.Nil(t, err)
-	assert.NotEqual(t, src1.Root(), src3.Root())
+	assert.NotEqual(t, src1.Root().Path(), src3.Root().Path())
 
-	dt, err = ioutil.ReadFile(filepath.Join(src3.Root(), "foo3"))
+	dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo3"))
 	assert.Nil(t, err)
 	assert.Equal(t, string(dt), "data3")
-	assert.Equal(t, src4.Root(), src3.Root())
+	assert.Equal(t, src4.Root().Path(), src3.Root().Path())
 	assert.Nil(t, src4.Close())
 
 	s, err = fscache.DiskUsage()
diff --git a/builder/remotecontext/archive.go b/builder/remotecontext/archive.go
index f48cafe..fc18c5d 100644
--- a/builder/remotecontext/archive.go
+++ b/builder/remotecontext/archive.go
@@ -8,19 +8,19 @@
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/chrootarchive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/ioutils"
-	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/pkg/tarsum"
 	"github.com/pkg/errors"
 )
 
 type archiveContext struct {
-	root string
+	root containerfs.ContainerFS
 	sums tarsum.FileInfoSums
 }
 
 func (c *archiveContext) Close() error {
-	return os.RemoveAll(c.root)
+	return c.root.RemoveAll(c.root.Path())
 }
 
 func convertPathError(err error, cleanpath string) error {
@@ -52,7 +52,8 @@
 		return nil, err
 	}
 
-	tsc := &archiveContext{root: root}
+	// Assume local file system. Since it's coming from a tar file.
+	tsc := &archiveContext{root: containerfs.NewLocalContainerFS(root)}
 
 	// Make sure we clean-up upon error.  In the happy case the caller
 	// is expected to manage the clean-up
@@ -82,7 +83,7 @@
 	return tsc, nil
 }
 
-func (c *archiveContext) Root() string {
+func (c *archiveContext) Root() containerfs.ContainerFS {
 	return c.root
 }
 
@@ -91,7 +92,7 @@
 	if err != nil {
 		return err
 	}
-	return os.RemoveAll(fullpath)
+	return c.root.RemoveAll(fullpath)
 }
 
 func (c *archiveContext) Hash(path string) (string, error) {
@@ -100,7 +101,7 @@
 		return "", err
 	}
 
-	rel, err := filepath.Rel(c.root, fullpath)
+	rel, err := c.root.Rel(c.root.Path(), fullpath)
 	if err != nil {
 		return "", convertPathError(err, cleanpath)
 	}
@@ -115,13 +116,13 @@
 	return path, nil // backwards compat TODO: see if really needed
 }
 
-func normalize(path, root string) (cleanPath, fullPath string, err error) {
-	cleanPath = filepath.Clean(string(os.PathSeparator) + path)[1:]
-	fullPath, err = symlink.FollowSymlinkInScope(filepath.Join(root, path), root)
+func normalize(path string, root containerfs.ContainerFS) (cleanPath, fullPath string, err error) {
+	cleanPath = root.Clean(string(root.Separator()) + path)[1:]
+	fullPath, err = root.ResolveScopedPath(path, true)
 	if err != nil {
 		return "", "", errors.Wrapf(err, "forbidden path outside the build context: %s (%s)", path, cleanPath)
 	}
-	if _, err := os.Lstat(fullPath); err != nil {
+	if _, err := root.Lstat(fullPath); err != nil {
 		return "", "", errors.WithStack(convertPathError(err, path))
 	}
 	return
diff --git a/builder/remotecontext/detect.go b/builder/remotecontext/detect.go
index 4345736..38aff67 100644
--- a/builder/remotecontext/detect.go
+++ b/builder/remotecontext/detect.go
@@ -5,18 +5,17 @@
 	"fmt"
 	"io"
 	"os"
-	"path/filepath"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/containerd/continuity/driver"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/builder/dockerfile/parser"
 	"github.com/docker/docker/builder/dockerignore"
 	"github.com/docker/docker/pkg/fileutils"
-	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/pkg/urlutil"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ClientSessionRemote is identifier for client-session context transport
@@ -157,12 +156,12 @@
 	return parser.Parse(br)
 }
 
-func openAt(remote builder.Source, path string) (*os.File, error) {
+func openAt(remote builder.Source, path string) (driver.File, error) {
 	fullPath, err := FullPath(remote, path)
 	if err != nil {
 		return nil, err
 	}
-	return os.Open(fullPath)
+	return remote.Root().Open(fullPath)
 }
 
 // StatAt is a helper for calling Stat on a path from a source
@@ -171,12 +170,12 @@
 	if err != nil {
 		return nil, err
 	}
-	return os.Stat(fullPath)
+	return remote.Root().Stat(fullPath)
 }
 
 // FullPath is a helper for getting a full path for a path from a source
 func FullPath(remote builder.Source, path string) (string, error) {
-	fullPath, err := symlink.FollowSymlinkInScope(filepath.Join(remote.Root(), path), remote.Root())
+	fullPath, err := remote.Root().ResolveScopedPath(path, true)
 	if err != nil {
 		return "", fmt.Errorf("Forbidden path outside the build context: %s (%s)", path, fullPath) // backwards compat with old error
 	}
diff --git a/builder/remotecontext/detect_test.go b/builder/remotecontext/detect_test.go
index 6b47ac2..3d1ebd1 100644
--- a/builder/remotecontext/detect_test.go
+++ b/builder/remotecontext/detect_test.go
@@ -5,11 +5,11 @@
 	"io/ioutil"
 	"log"
 	"os"
-	"path/filepath"
 	"sort"
 	"testing"
 
 	"github.com/docker/docker/builder"
+	"github.com/docker/docker/pkg/containerfs"
 )
 
 const (
@@ -21,7 +21,7 @@
 const shouldStayFilename = "should_stay"
 
 func extractFilenames(files []os.FileInfo) []string {
-	filenames := make([]string, len(files), len(files))
+	filenames := make([]string, len(files))
 
 	for i, file := range files {
 		filenames[i] = file.Name()
@@ -53,7 +53,7 @@
 }
 
 func executeProcess(t *testing.T, contextDir string) {
-	modifiableCtx := &stubRemote{root: contextDir}
+	modifiableCtx := &stubRemote{root: containerfs.NewLocalContainerFS(contextDir)}
 
 	err := removeDockerfile(modifiableCtx, builder.DefaultDockerfileName)
 
@@ -105,19 +105,19 @@
 
 // TODO: remove after moving to a separate pkg
 type stubRemote struct {
-	root string
+	root containerfs.ContainerFS
 }
 
 func (r *stubRemote) Hash(path string) (string, error) {
 	return "", errors.New("not implemented")
 }
 
-func (r *stubRemote) Root() string {
+func (r *stubRemote) Root() containerfs.ContainerFS {
 	return r.root
 }
 func (r *stubRemote) Close() error {
 	return errors.New("not implemented")
 }
 func (r *stubRemote) Remove(p string) error {
-	return os.Remove(filepath.Join(r.root, p))
+	return r.root.Remove(r.root.Join(r.root.Path(), p))
 }
diff --git a/builder/remotecontext/errors.go b/builder/remotecontext/errors.go
new file mode 100644
index 0000000..8ee33bc
--- /dev/null
+++ b/builder/remotecontext/errors.go
@@ -0,0 +1,75 @@
+package remotecontext
+
+type notFoundError string
+
+func (e notFoundError) Error() string {
+	return string(e)
+}
+
+func (notFoundError) NotFound() {}
+
+type requestError string
+
+func (e requestError) Error() string {
+	return string(e)
+}
+
+func (e requestError) InvalidParameter() {}
+
+type unauthorizedError string
+
+func (e unauthorizedError) Error() string {
+	return string(e)
+}
+
+func (unauthorizedError) Unauthorized() {}
+
+type forbiddenError string
+
+func (e forbiddenError) Error() string {
+	return string(e)
+}
+
+func (forbiddenError) Forbidden() {}
+
+type dnsError struct {
+	cause error
+}
+
+func (e dnsError) Error() string {
+	return e.cause.Error()
+}
+
+func (e dnsError) NotFound() {}
+
+func (e dnsError) Cause() error {
+	return e.cause
+}
+
+type systemError struct {
+	cause error
+}
+
+func (e systemError) Error() string {
+	return e.cause.Error()
+}
+
+func (e systemError) SystemError() {}
+
+func (e systemError) Cause() error {
+	return e.cause
+}
+
+type unknownError struct {
+	cause error
+}
+
+func (e unknownError) Error() string {
+	return e.cause.Error()
+}
+
+func (unknownError) Unknown() {}
+
+func (e unknownError) Cause() error {
+	return e.cause
+}
diff --git a/builder/remotecontext/git/gitutils.go b/builder/remotecontext/git/gitutils.go
index b94d462..7bc2268 100644
--- a/builder/remotecontext/git/gitutils.go
+++ b/builder/remotecontext/git/gitutils.go
@@ -1,7 +1,6 @@
 package git
 
 import (
-	"fmt"
 	"io/ioutil"
 	"net/http"
 	"net/url"
@@ -98,22 +97,46 @@
 
 func fetchArgs(remoteURL string, ref string) []string {
 	args := []string{"fetch", "--recurse-submodules=yes"}
-	shallow := true
 
-	if urlutil.IsURL(remoteURL) {
-		res, err := http.Head(fmt.Sprintf("%s/info/refs?service=git-upload-pack", remoteURL))
-		if err != nil || res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" {
-			shallow = false
-		}
-	}
-
-	if shallow {
+	if supportsShallowClone(remoteURL) {
 		args = append(args, "--depth", "1")
 	}
 
 	return append(args, "origin", ref)
 }
 
+// Check if a given git URL supports a shallow git clone,
+// i.e. it is a non-HTTP server or a smart HTTP server.
+func supportsShallowClone(remoteURL string) bool {
+	if urlutil.IsURL(remoteURL) {
+		// Check if the HTTP server is smart
+
+		// Smart servers must correctly respond to a query for the git-upload-pack service
+		serviceURL := remoteURL + "/info/refs?service=git-upload-pack"
+
+		// Try a HEAD request and fallback to a Get request on error
+		res, err := http.Head(serviceURL)
+		if err != nil || res.StatusCode != http.StatusOK {
+			res, err = http.Get(serviceURL)
+			if err == nil {
+				res.Body.Close()
+			}
+			if err != nil || res.StatusCode != http.StatusOK {
+				// request failed
+				return false
+			}
+		}
+
+		if res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" {
+			// Fallback, not a smart server
+			return false
+		}
+		return true
+	}
+	// Non-HTTP protocols always support shallow clones
+	return true
+}
+
 func checkoutGit(root, ref, subdir string) (string, error) {
 	// Try checking out by ref name first. This will work on branches and sets
 	// .git/HEAD to the current branch name
diff --git a/builder/remotecontext/lazycontext.go b/builder/remotecontext/lazycontext.go
index b29c413..66f36de 100644
--- a/builder/remotecontext/lazycontext.go
+++ b/builder/remotecontext/lazycontext.go
@@ -3,11 +3,10 @@
 import (
 	"encoding/hex"
 	"os"
-	"path/filepath"
-	"runtime"
 	"strings"
 
 	"github.com/docker/docker/builder"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/pools"
 	"github.com/pkg/errors"
 )
@@ -15,7 +14,7 @@
 // NewLazySource creates a new LazyContext. LazyContext defines a hashed build
 // context based on a root directory. Individual files are hashed first time
 // they are asked. It is not safe to call methods of LazyContext concurrently.
-func NewLazySource(root string) (builder.Source, error) {
+func NewLazySource(root containerfs.ContainerFS) (builder.Source, error) {
 	return &lazySource{
 		root: root,
 		sums: make(map[string]string),
@@ -23,11 +22,11 @@
 }
 
 type lazySource struct {
-	root string
+	root containerfs.ContainerFS
 	sums map[string]string
 }
 
-func (c *lazySource) Root() string {
+func (c *lazySource) Root() containerfs.ContainerFS {
 	return c.root
 }
 
@@ -41,7 +40,7 @@
 		return "", err
 	}
 
-	fi, err := os.Lstat(fullPath)
+	fi, err := c.root.Lstat(fullPath)
 	if err != nil {
 		return "", errors.WithStack(err)
 	}
@@ -63,13 +62,13 @@
 }
 
 func (c *lazySource) prepareHash(relPath string, fi os.FileInfo) (string, error) {
-	p := filepath.Join(c.root, relPath)
+	p := c.root.Join(c.root.Path(), relPath)
 	h, err := NewFileHash(p, relPath, fi)
 	if err != nil {
 		return "", errors.Wrapf(err, "failed to create hash for %s", relPath)
 	}
 	if fi.Mode().IsRegular() && fi.Size() > 0 {
-		f, err := os.Open(p)
+		f, err := c.root.Open(p)
 		if err != nil {
 			return "", errors.Wrapf(err, "failed to open %s", relPath)
 		}
@@ -85,10 +84,10 @@
 
 // Rel makes a path relative to base path. Same as `filepath.Rel` but can also
 // handle UUID paths in windows.
-func Rel(basepath, targpath string) (string, error) {
+func Rel(basepath containerfs.ContainerFS, targpath string) (string, error) {
 	// filepath.Rel can't handle UUID paths in windows
-	if runtime.GOOS == "windows" {
-		pfx := basepath + `\`
+	if basepath.OS() == "windows" {
+		pfx := basepath.Path() + `\`
 		if strings.HasPrefix(targpath, pfx) {
 			p := strings.TrimPrefix(targpath, pfx)
 			if p == "" {
@@ -97,5 +96,5 @@
 			return p, nil
 		}
 	}
-	return filepath.Rel(basepath, targpath)
+	return basepath.Rel(basepath.Path(), targpath)
 }
diff --git a/builder/remotecontext/remote.go b/builder/remotecontext/remote.go
index 4afd516..6c4073b 100644
--- a/builder/remotecontext/remote.go
+++ b/builder/remotecontext/remote.go
@@ -5,7 +5,9 @@
 	"fmt"
 	"io"
 	"io/ioutil"
+	"net"
 	"net/http"
+	"net/url"
 	"regexp"
 
 	"github.com/docker/docker/builder"
@@ -68,20 +70,37 @@
 
 // GetWithStatusError does an http.Get() and returns an error if the
 // status code is 4xx or 5xx.
-func GetWithStatusError(url string) (resp *http.Response, err error) {
-	if resp, err = http.Get(url); err != nil {
-		return nil, err
+func GetWithStatusError(address string) (resp *http.Response, err error) {
+	if resp, err = http.Get(address); err != nil {
+		if uerr, ok := err.(*url.Error); ok {
+			if derr, ok := uerr.Err.(*net.DNSError); ok && !derr.IsTimeout {
+				return nil, dnsError{err}
+			}
+		}
+		return nil, systemError{err}
 	}
 	if resp.StatusCode < 400 {
 		return resp, nil
 	}
-	msg := fmt.Sprintf("failed to GET %s with status %s", url, resp.Status)
+	msg := fmt.Sprintf("failed to GET %s with status %s", address, resp.Status)
 	body, err := ioutil.ReadAll(resp.Body)
 	resp.Body.Close()
 	if err != nil {
-		return nil, errors.Wrapf(err, msg+": error reading body")
+		return nil, errors.Wrap(systemError{err}, msg+": error reading body")
 	}
-	return nil, errors.Errorf(msg+": %s", bytes.TrimSpace(body))
+
+	msg += ": " + string(bytes.TrimSpace(body))
+	switch resp.StatusCode {
+	case http.StatusNotFound:
+		return nil, notFoundError(msg)
+	case http.StatusBadRequest:
+		return nil, requestError(msg)
+	case http.StatusUnauthorized:
+		return nil, unauthorizedError(msg)
+	case http.StatusForbidden:
+		return nil, forbiddenError(msg)
+	}
+	return nil, unknownError{errors.New(msg)}
 }
 
 // inspectResponse looks into the http response data at r to determine whether its
@@ -91,19 +110,19 @@
 //    - an io.Reader for the response body
 //    - an error value which will be non-nil either when something goes wrong while
 //      reading bytes from r or when the detected content-type is not acceptable.
-func inspectResponse(ct string, r io.ReadCloser, clen int64) (string, io.ReadCloser, error) {
+func inspectResponse(ct string, r io.Reader, clen int64) (string, io.ReadCloser, error) {
 	plen := clen
 	if plen <= 0 || plen > maxPreambleLength {
 		plen = maxPreambleLength
 	}
 
-	preamble := make([]byte, plen, plen)
+	preamble := make([]byte, plen)
 	rlen, err := r.Read(preamble)
 	if rlen == 0 {
-		return ct, r, errors.New("empty response")
+		return ct, ioutil.NopCloser(r), errors.New("empty response")
 	}
 	if err != nil && err != io.EOF {
-		return ct, r, err
+		return ct, ioutil.NopCloser(r), err
 	}
 
 	preambleR := bytes.NewReader(preamble[:rlen])
diff --git a/builder/remotecontext/remote_test.go b/builder/remotecontext/remote_test.go
index c698726..c38433b 100644
--- a/builder/remotecontext/remote_test.go
+++ b/builder/remotecontext/remote_test.go
@@ -10,8 +10,8 @@
 	"testing"
 
 	"github.com/docker/docker/builder"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/docker/docker/pkg/archive"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -253,7 +253,7 @@
 		if testcase.expectedErr == "" {
 			require.NoError(t, err)
 
-			body, err := testutil.ReadBody(response.Body)
+			body, err := readBody(response.Body)
 			require.NoError(t, err)
 			assert.Contains(t, string(body), testcase.expectedBody)
 		} else {
@@ -261,3 +261,8 @@
 		}
 	}
 }
+
+func readBody(b io.ReadCloser) ([]byte, error) {
+	defer b.Close()
+	return ioutil.ReadAll(b)
+}
diff --git a/builder/remotecontext/tarsum.go b/builder/remotecontext/tarsum.go
index 3ae9d82..78f7470 100644
--- a/builder/remotecontext/tarsum.go
+++ b/builder/remotecontext/tarsum.go
@@ -1,25 +1,24 @@
 package remotecontext
 
 import (
-	"fmt"
 	"os"
-	"path/filepath"
 	"sync"
 
-	"github.com/docker/docker/pkg/symlink"
+	"github.com/docker/docker/pkg/containerfs"
 	iradix "github.com/hashicorp/go-immutable-radix"
+	digest "github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
 	"github.com/tonistiigi/fsutil"
 )
 
 type hashed interface {
-	Hash() string
+	Digest() digest.Digest
 }
 
 // CachableSource is a source that contains cache records for its contents
 type CachableSource struct {
 	mu   sync.Mutex
-	root string
+	root containerfs.ContainerFS
 	tree *iradix.Tree
 	txn  *iradix.Txn
 }
@@ -28,7 +27,7 @@
 func NewCachableSource(root string) *CachableSource {
 	ts := &CachableSource{
 		tree: iradix.New(),
-		root: root,
+		root: containerfs.NewLocalContainerFS(root),
 	}
 	return ts
 }
@@ -67,7 +66,7 @@
 		return err
 	}
 	txn := iradix.New().Txn()
-	err = filepath.Walk(cs.root, func(path string, info os.FileInfo, err error) error {
+	err = cs.root.Walk(cs.root.Path(), func(path string, info os.FileInfo, err error) error {
 		if err != nil {
 			return errors.Wrapf(err, "failed to walk %s", path)
 		}
@@ -110,7 +109,7 @@
 	}
 
 	hfi := &fileInfo{
-		sum: h.Hash(),
+		sum: h.Digest().Hex(),
 	}
 	cs.txn.Insert([]byte(p), hfi)
 	cs.mu.Unlock()
@@ -133,35 +132,19 @@
 	return nil
 }
 
-func (cs *CachableSource) normalize(path string) (cleanpath, fullpath string, err error) {
-	cleanpath = filepath.Clean(string(os.PathSeparator) + path)[1:]
-	fullpath, err = symlink.FollowSymlinkInScope(filepath.Join(cs.root, path), cs.root)
-	if err != nil {
-		return "", "", fmt.Errorf("Forbidden path outside the context: %s (%s)", path, fullpath)
-	}
-	_, err = os.Lstat(fullpath)
-	if err != nil {
-		return "", "", convertPathError(err, path)
-	}
-	return
-}
-
 // Hash returns a hash for a single file in the source
 func (cs *CachableSource) Hash(path string) (string, error) {
 	n := cs.getRoot()
-	sum := ""
 	// TODO: check this for symlinks
 	v, ok := n.Get([]byte(path))
 	if !ok {
-		sum = path
-	} else {
-		sum = v.(*fileInfo).sum
+		return path, nil
 	}
-	return sum, nil
+	return v.(*fileInfo).sum, nil
 }
 
 // Root returns a root directory for the source
-func (cs *CachableSource) Root() string {
+func (cs *CachableSource) Root() containerfs.ContainerFS {
 	return cs.root
 }
 
diff --git a/builder/remotecontext/tarsum.pb.go b/builder/remotecontext/tarsum.pb.go
index 561a7f6..1d23bbe 100644
--- a/builder/remotecontext/tarsum.pb.go
+++ b/builder/remotecontext/tarsum.pb.go
@@ -94,7 +94,7 @@
 	s := make([]string, 0, 5)
 	s = append(s, "&remotecontext.TarsumBackup{")
 	keysForHashes := make([]string, 0, len(this.Hashes))
-	for k, _ := range this.Hashes {
+	for k := range this.Hashes {
 		keysForHashes = append(keysForHashes, k)
 	}
 	github_com_gogo_protobuf_sortkeys.Strings(keysForHashes)
@@ -133,7 +133,7 @@
 	var l int
 	_ = l
 	if len(m.Hashes) > 0 {
-		for k, _ := range m.Hashes {
+		for k := range m.Hashes {
 			dAtA[i] = 0xa
 			i++
 			v := m.Hashes[k]
@@ -211,7 +211,7 @@
 		return "nil"
 	}
 	keysForHashes := make([]string, 0, len(this.Hashes))
-	for k, _ := range this.Hashes {
+	for k := range this.Hashes {
 		keysForHashes = append(keysForHashes, k)
 	}
 	github_com_gogo_protobuf_sortkeys.Strings(keysForHashes)
diff --git a/builder/remotecontext/tarsum_test.go b/builder/remotecontext/tarsum_test.go
index 8a9d69b..6d2b41d 100644
--- a/builder/remotecontext/tarsum_test.go
+++ b/builder/remotecontext/tarsum_test.go
@@ -35,7 +35,7 @@
 		t.Fatalf("Error while executing Close: %s", err)
 	}
 
-	_, err = os.Stat(src.Root())
+	_, err = os.Stat(src.Root().Path())
 
 	if !os.IsNotExist(err) {
 		t.Fatal("Directory should not exist at this point")
diff --git a/cli/debug/debug.go b/cli/debug/debug.go
index 51dfab2..b00ea63 100644
--- a/cli/debug/debug.go
+++ b/cli/debug/debug.go
@@ -3,7 +3,7 @@
 import (
 	"os"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // Enable sets the DEBUG env var to true
diff --git a/cli/debug/debug_test.go b/cli/debug/debug_test.go
index ad8412a..9031152 100644
--- a/cli/debug/debug_test.go
+++ b/cli/debug/debug_test.go
@@ -4,7 +4,7 @@
 	"os"
 	"testing"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 func TestEnable(t *testing.T) {
diff --git a/client/checkpoint_list.go b/client/checkpoint_list.go
index ffe44bc..9835bad 100644
--- a/client/checkpoint_list.go
+++ b/client/checkpoint_list.go
@@ -2,7 +2,6 @@
 
 import (
 	"encoding/json"
-	"net/http"
 	"net/url"
 
 	"github.com/docker/docker/api/types"
@@ -20,10 +19,7 @@
 
 	resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil)
 	if err != nil {
-		if resp.statusCode == http.StatusNotFound {
-			return checkpoints, containerNotFoundError{container}
-		}
-		return checkpoints, err
+		return checkpoints, wrapResponseError(err, resp, "container", container)
 	}
 
 	err = json.NewDecoder(resp.body).Decode(&checkpoints)
diff --git a/client/checkpoint_list_test.go b/client/checkpoint_list_test.go
index 3884657..11426ed 100644
--- a/client/checkpoint_list_test.go
+++ b/client/checkpoint_list_test.go
@@ -62,7 +62,7 @@
 	}
 
 	_, err := client.CheckpointList(context.Background(), "unknown", types.CheckpointListOptions{})
-	if err == nil || !IsErrContainerNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected a containerNotFound error, got %v", err)
 	}
 }
diff --git a/client/client.go b/client/client.go
index 7e14531..8931248 100644
--- a/client/client.go
+++ b/client/client.go
@@ -1,10 +1,6 @@
 /*
 Package client is a Go client for the Docker Engine API.
 
-The "docker" command uses this package to communicate with the daemon. It can also
-be used by your own Go applications to do anything the command-line interface does
-- running containers, pulling images, managing swarms, etc.
-
 For more information about the Engine API, see the documentation:
 https://docs.docker.com/engine/reference/api/
 
@@ -51,6 +47,7 @@
 	"net/http"
 	"net/url"
 	"os"
+	"path"
 	"path/filepath"
 	"strings"
 
@@ -159,18 +156,18 @@
 // highly recommended that you set a version or your client may break if the
 // server is upgraded.
 func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
-	proto, addr, basePath, err := ParseHost(host)
+	hostURL, err := ParseHostURL(host)
 	if err != nil {
 		return nil, err
 	}
 
 	if client != nil {
-		if _, ok := client.Transport.(*http.Transport); !ok {
+		if _, ok := client.Transport.(http.RoundTripper); !ok {
 			return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport)
 		}
 	} else {
 		transport := new(http.Transport)
-		sockets.ConfigureTransport(transport, proto, addr)
+		sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host)
 		client = &http.Client{
 			Transport:     transport,
 			CheckRedirect: CheckRedirect,
@@ -188,28 +185,24 @@
 		scheme = "https"
 	}
 
+	// TODO: store URL instead of proto/addr/basePath
 	return &Client{
 		scheme:            scheme,
 		host:              host,
-		proto:             proto,
-		addr:              addr,
-		basePath:          basePath,
+		proto:             hostURL.Scheme,
+		addr:              hostURL.Host,
+		basePath:          hostURL.Path,
 		client:            client,
 		version:           version,
 		customHTTPHeaders: httpHeaders,
 	}, nil
 }
 
-// Close ensures that transport.Client is closed
-// especially needed while using NewClient with *http.Client = nil
-// for example
-// client.NewClient("unix:///var/run/docker.sock", nil, "v1.18", map[string]string{"User-Agent": "engine-api-cli-1.0"})
+// Close the transport used by the client
 func (cli *Client) Close() error {
-
 	if t, ok := cli.client.Transport.(*http.Transport); ok {
 		t.CloseIdleConnections()
 	}
-
 	return nil
 }
 
@@ -219,37 +212,27 @@
 	var apiPath string
 	if cli.version != "" {
 		v := strings.TrimPrefix(cli.version, "v")
-		apiPath = cli.basePath + "/v" + v + p
+		apiPath = path.Join(cli.basePath, "/v"+v, p)
 	} else {
-		apiPath = cli.basePath + p
+		apiPath = path.Join(cli.basePath, p)
 	}
-
-	u := &url.URL{
-		Path: apiPath,
-	}
-	if len(query) > 0 {
-		u.RawQuery = query.Encode()
-	}
-	return u.String()
+	return (&url.URL{Path: apiPath, RawQuery: query.Encode()}).String()
 }
 
-// ClientVersion returns the version string associated with this
-// instance of the Client. Note that this value can be changed
-// via the DOCKER_API_VERSION env var.
-// This operation doesn't acquire a mutex.
+// ClientVersion returns the API version used by this client.
 func (cli *Client) ClientVersion() string {
 	return cli.version
 }
 
-// NegotiateAPIVersion updates the version string associated with this
-// instance of the Client to match the latest version the server supports
+// NegotiateAPIVersion queries the API and updates the version to match the
+// API version. Any errors are silently ignored.
 func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
 	ping, _ := cli.Ping(ctx)
 	cli.NegotiateAPIVersionPing(ping)
 }
 
-// NegotiateAPIVersionPing updates the version string associated with this
-// instance of the Client to match the latest version the server supports
+// NegotiateAPIVersionPing updates the client version to match the Ping.APIVersion
+// if the ping version is less than the default version.
 func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
 	if cli.manualOverride {
 		return
@@ -265,23 +248,34 @@
 		cli.version = api.DefaultVersion
 	}
 
-	// if server version is lower than the maximum version supported by the Client, downgrade
-	if versions.LessThan(p.APIVersion, api.DefaultVersion) {
+	// if server version is lower than the client version, downgrade
+	if versions.LessThan(p.APIVersion, cli.version) {
 		cli.version = p.APIVersion
 	}
 }
 
-// DaemonHost returns the host associated with this instance of the Client.
-// This operation doesn't acquire a mutex.
+// DaemonHost returns the host address used by the client
 func (cli *Client) DaemonHost() string {
 	return cli.host
 }
 
-// ParseHost verifies that the given host strings is valid.
+// ParseHost parses a url string, validates the strings is a host url, and returns
+// the parsed host as: protocol, address, and base path
+// Deprecated: use ParseHostURL
 func ParseHost(host string) (string, string, string, error) {
+	hostURL, err := ParseHostURL(host)
+	if err != nil {
+		return "", "", "", err
+	}
+	return hostURL.Scheme, hostURL.Host, hostURL.Path, nil
+}
+
+// ParseHostURL parses a url string, validates the string is a host url, and
+// returns the parsed URL
+func ParseHostURL(host string) (*url.URL, error) {
 	protoAddrParts := strings.SplitN(host, "://", 2)
 	if len(protoAddrParts) == 1 {
-		return "", "", "", fmt.Errorf("unable to parse docker host `%s`", host)
+		return nil, fmt.Errorf("unable to parse docker host `%s`", host)
 	}
 
 	var basePath string
@@ -289,16 +283,19 @@
 	if proto == "tcp" {
 		parsed, err := url.Parse("tcp://" + addr)
 		if err != nil {
-			return "", "", "", err
+			return nil, err
 		}
 		addr = parsed.Host
 		basePath = parsed.Path
 	}
-	return proto, addr, basePath, nil
+	return &url.URL{
+		Scheme: proto,
+		Host:   addr,
+		Path:   basePath,
+	}, nil
 }
 
-// CustomHTTPHeaders returns the custom http headers associated with this
-// instance of the Client. This operation doesn't acquire a mutex.
+// CustomHTTPHeaders returns the custom http headers stored by the client.
 func (cli *Client) CustomHTTPHeaders() map[string]string {
 	m := make(map[string]string)
 	for k, v := range cli.customHTTPHeaders {
@@ -307,8 +304,7 @@
 	return m
 }
 
-// SetCustomHTTPHeaders updates the custom http headers associated with this
-// instance of the Client. This operation doesn't acquire a mutex.
+// SetCustomHTTPHeaders that will be set on every HTTP request made by the client.
 func (cli *Client) SetCustomHTTPHeaders(headers map[string]string) {
 	cli.customHTTPHeaders = headers
 }
diff --git a/client/client_mock_test.go b/client/client_mock_test.go
index 0ab935d..e75c3ec 100644
--- a/client/client_mock_test.go
+++ b/client/client_mock_test.go
@@ -9,6 +9,14 @@
 	"github.com/docker/docker/api/types"
 )
 
+// transportFunc allows us to inject a mock transport for testing. We define it
+// here so we can detect the tlsconfig and return nil for only this type.
+type transportFunc func(*http.Request) (*http.Response, error)
+
+func (tf transportFunc) RoundTrip(req *http.Request) (*http.Response, error) {
+	return tf(req)
+}
+
 func newMockClient(doer func(*http.Request) (*http.Response, error)) *http.Client {
 	return &http.Client{
 		Transport: transportFunc(doer),
diff --git a/client/client_test.go b/client/client_test.go
index bc911c0..cb38d4d 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -11,6 +11,7 @@
 
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -104,11 +105,11 @@
 }
 
 func TestGetAPIPath(t *testing.T) {
-	cases := []struct {
-		v string
-		p string
-		q url.Values
-		e string
+	testcases := []struct {
+		version  string
+		path     string
+		query    url.Values
+		expected string
 	}{
 		{"", "/containers/json", nil, "/containers/json"},
 		{"", "/containers/json", url.Values{}, "/containers/json"},
@@ -122,16 +123,10 @@
 		{"v1.22", "/networks/kiwl$%^", nil, "/v1.22/networks/kiwl$%25%5E"},
 	}
 
-	for _, cs := range cases {
-		c, err := NewClient("unix:///var/run/docker.sock", cs.v, nil, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
-		g := c.getAPIPath(cs.p, cs.q)
-		assert.Equal(t, g, cs.e)
-
-		err = c.Close()
-		assert.NoError(t, err)
+	for _, testcase := range testcases {
+		c := Client{version: testcase.version, basePath: "/"}
+		actual := c.getAPIPath(testcase.path, testcase.query)
+		assert.Equal(t, actual, testcase.expected)
 	}
 }
 
@@ -152,7 +147,6 @@
 
 	for _, cs := range cases {
 		p, a, b, e := ParseHost(cs.host)
-		// if we expected an error to be returned...
 		if cs.err {
 			assert.Error(t, e)
 		}
@@ -162,6 +156,43 @@
 	}
 }
 
+func TestParseHostURL(t *testing.T) {
+	testcases := []struct {
+		host        string
+		expected    *url.URL
+		expectedErr string
+	}{
+		{
+			host:        "",
+			expectedErr: "unable to parse docker host",
+		},
+		{
+			host:        "foobar",
+			expectedErr: "unable to parse docker host",
+		},
+		{
+			host:     "foo://bar",
+			expected: &url.URL{Scheme: "foo", Host: "bar"},
+		},
+		{
+			host:     "tcp://localhost:2476",
+			expected: &url.URL{Scheme: "tcp", Host: "localhost:2476"},
+		},
+		{
+			host:     "tcp://localhost:2476/path",
+			expected: &url.URL{Scheme: "tcp", Host: "localhost:2476", Path: "/path"},
+		},
+	}
+
+	for _, testcase := range testcases {
+		actual, err := ParseHostURL(testcase.host)
+		if testcase.expectedErr != "" {
+			testutil.ErrorContains(t, err, testcase.expectedErr)
+		}
+		assert.Equal(t, testcase.expected, actual)
+	}
+}
+
 func TestNewEnvClientSetsDefaultVersion(t *testing.T) {
 	env := envToMap()
 	defer mapToEnv(env)
@@ -245,6 +276,14 @@
 	// test downgrade
 	client.NegotiateAPIVersionPing(ping)
 	assert.Equal(t, expected, client.version)
+
+	// set the client version to something older, and verify that we keep the
+	// original setting.
+	expected = "1.20"
+	client.version = expected
+	client.NegotiateAPIVersionPing(ping)
+	assert.Equal(t, expected, client.version)
+
 }
 
 // TestNegotiateAPIVersionOverride asserts that we honor
diff --git a/client/config_inspect.go b/client/config_inspect.go
index ebb6d63..b44d6fd 100644
--- a/client/config_inspect.go
+++ b/client/config_inspect.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 
 	"github.com/docker/docker/api/types/swarm"
 	"golang.org/x/net/context"
@@ -17,10 +16,7 @@
 	}
 	resp, err := cli.get(ctx, "/configs/"+id, nil, nil)
 	if err != nil {
-		if resp.statusCode == http.StatusNotFound {
-			return swarm.Config{}, nil, configNotFoundError{id}
-		}
-		return swarm.Config{}, nil, err
+		return swarm.Config{}, nil, wrapResponseError(err, resp, "config", id)
 	}
 	defer ensureReaderClosed(resp)
 
diff --git a/client/config_inspect_test.go b/client/config_inspect_test.go
index 010b188..fab0c28 100644
--- a/client/config_inspect_test.go
+++ b/client/config_inspect_test.go
@@ -42,7 +42,7 @@
 	}
 
 	_, _, err := client.ConfigInspectWithRaw(context.Background(), "unknown")
-	if err == nil || !IsErrConfigNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected a configNotFoundError error, got %v", err)
 	}
 }
@@ -53,7 +53,7 @@
 		version: "1.30",
 		client: newMockClient(func(req *http.Request) (*http.Response, error) {
 			if !strings.HasPrefix(req.URL.Path, expectedURL) {
-				return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
+				return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL)
 			}
 			content, err := json.Marshal(swarm.Config{
 				ID: "config_id",
diff --git a/client/config_list.go b/client/config_list.go
index 8483ca1..57febc9 100644
--- a/client/config_list.go
+++ b/client/config_list.go
@@ -18,7 +18,7 @@
 	query := url.Values{}
 
 	if options.Filters.Len() > 0 {
-		filterJSON, err := filters.ToParam(options.Filters)
+		filterJSON, err := filters.ToJSON(options.Filters)
 		if err != nil {
 			return nil, err
 		}
diff --git a/client/config_remove.go b/client/config_remove.go
index 726b5c8..e025d44 100644
--- a/client/config_remove.go
+++ b/client/config_remove.go
@@ -9,5 +9,5 @@
 	}
 	resp, err := cli.delete(ctx, "/configs/"+id, nil, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "config", id)
 }
diff --git a/client/container_commit.go b/client/container_commit.go
index 531d796..b3b16ab 100644
--- a/client/container_commit.go
+++ b/client/container_commit.go
@@ -39,7 +39,7 @@
 	for _, change := range options.Changes {
 		query.Add("changes", change)
 	}
-	if options.Pause != true {
+	if !options.Pause {
 		query.Set("pause", "0")
 	}
 
diff --git a/client/container_create.go b/client/container_create.go
index 6841b0b..bd817e7 100644
--- a/client/container_create.go
+++ b/client/container_create.go
@@ -45,7 +45,7 @@
 	serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
 	if err != nil {
 		if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") {
-			return response, imageNotFoundError{config.Image}
+			return response, objectNotFoundError{object: "image", id: config.Image}
 		}
 		return response, err
 	}
diff --git a/client/container_create_test.go b/client/container_create_test.go
index 3ab608c..9464dc6 100644
--- a/client/container_create_test.go
+++ b/client/container_create_test.go
@@ -37,7 +37,7 @@
 		client: newMockClient(errorMock(http.StatusNotFound, "No such image")),
 	}
 	_, err := client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, "unknown")
-	if err == nil || !IsErrImageNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected an imageNotFound error, got %v", err)
 	}
 }
diff --git a/client/container_inspect.go b/client/container_inspect.go
index 17f1809..a15db14 100644
--- a/client/container_inspect.go
+++ b/client/container_inspect.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 	"net/url"
 
 	"github.com/docker/docker/api/types"
@@ -15,10 +14,7 @@
 func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) {
 	serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
 	if err != nil {
-		if serverResp.statusCode == http.StatusNotFound {
-			return types.ContainerJSON{}, containerNotFoundError{containerID}
-		}
-		return types.ContainerJSON{}, err
+		return types.ContainerJSON{}, wrapResponseError(err, serverResp, "container", containerID)
 	}
 
 	var response types.ContainerJSON
@@ -35,10 +31,7 @@
 	}
 	serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil)
 	if err != nil {
-		if serverResp.statusCode == http.StatusNotFound {
-			return types.ContainerJSON{}, nil, containerNotFoundError{containerID}
-		}
-		return types.ContainerJSON{}, nil, err
+		return types.ContainerJSON{}, nil, wrapResponseError(err, serverResp, "container", containerID)
 	}
 	defer ensureReaderClosed(serverResp)
 
diff --git a/client/container_inspect_test.go b/client/container_inspect_test.go
index 98f83bd..37259e4 100644
--- a/client/container_inspect_test.go
+++ b/client/container_inspect_test.go
@@ -30,7 +30,7 @@
 	}
 
 	_, err := client.ContainerInspect(context.Background(), "unknown")
-	if err == nil || !IsErrContainerNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected a containerNotFound error, got %v", err)
 	}
 }
diff --git a/client/container_remove.go b/client/container_remove.go
index 3a79590..070108b 100644
--- a/client/container_remove.go
+++ b/client/container_remove.go
@@ -23,5 +23,5 @@
 
 	resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "container", containerID)
 }
diff --git a/client/container_remove_test.go b/client/container_remove_test.go
index 798c08b..0eab7ee 100644
--- a/client/container_remove_test.go
+++ b/client/container_remove_test.go
@@ -9,6 +9,7 @@
 	"testing"
 
 	"github.com/docker/docker/api/types"
+	"github.com/stretchr/testify/assert"
 	"golang.org/x/net/context"
 )
 
@@ -17,9 +18,16 @@
 		client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
 	}
 	err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{})
-	if err == nil || err.Error() != "Error response from daemon: Server error" {
-		t.Fatalf("expected a Server Error, got %v", err)
+	assert.EqualError(t, err, "Error response from daemon: Server error")
+}
+
+func TestContainerRemoveNotFoundError(t *testing.T) {
+	client := &Client{
+		client: newMockClient(errorMock(http.StatusNotFound, "missing")),
 	}
+	err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{})
+	assert.EqualError(t, err, "Error: No such container: container_id")
+	assert.True(t, IsErrNotFound(err))
 }
 
 func TestContainerRemove(t *testing.T) {
@@ -53,7 +61,5 @@
 		RemoveVolumes: true,
 		Force:         true,
 	})
-	if err != nil {
-		t.Fatal(err)
-	}
+	assert.NoError(t, err)
 }
diff --git a/client/errors.go b/client/errors.go
index fc7df9f..e41b728 100644
--- a/client/errors.go
+++ b/client/errors.go
@@ -3,6 +3,8 @@
 import (
 	"fmt"
 
+	"net/http"
+
 	"github.com/docker/docker/api/types/versions"
 	"github.com/pkg/errors"
 )
@@ -36,95 +38,37 @@
 	NotFound() bool // Is the error a NotFound error
 }
 
-// IsErrNotFound returns true if the error is caused with an
-// object (image, container, network, volume, …) is not found in the docker host.
+// IsErrNotFound returns true if the error is a NotFound error, which is returned
+// by the API when some object is not found.
 func IsErrNotFound(err error) bool {
 	te, ok := err.(notFound)
 	return ok && te.NotFound()
 }
 
-// imageNotFoundError implements an error returned when an image is not in the docker host.
-type imageNotFoundError struct {
-	imageID string
+type objectNotFoundError struct {
+	object string
+	id     string
 }
 
-// NotFound indicates that this error type is of NotFound
-func (e imageNotFoundError) NotFound() bool {
+func (e objectNotFoundError) NotFound() bool {
 	return true
 }
 
-// Error returns a string representation of an imageNotFoundError
-func (e imageNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such image: %s", e.imageID)
+func (e objectNotFoundError) Error() string {
+	return fmt.Sprintf("Error: No such %s: %s", e.object, e.id)
 }
 
-// IsErrImageNotFound returns true if the error is caused
-// when an image is not found in the docker host.
-func IsErrImageNotFound(err error) bool {
-	return IsErrNotFound(err)
-}
-
-// containerNotFoundError implements an error returned when a container is not in the docker host.
-type containerNotFoundError struct {
-	containerID string
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e containerNotFoundError) NotFound() bool {
-	return true
-}
-
-// Error returns a string representation of a containerNotFoundError
-func (e containerNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such container: %s", e.containerID)
-}
-
-// IsErrContainerNotFound returns true if the error is caused
-// when a container is not found in the docker host.
-func IsErrContainerNotFound(err error) bool {
-	return IsErrNotFound(err)
-}
-
-// networkNotFoundError implements an error returned when a network is not in the docker host.
-type networkNotFoundError struct {
-	networkID string
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e networkNotFoundError) NotFound() bool {
-	return true
-}
-
-// Error returns a string representation of a networkNotFoundError
-func (e networkNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such network: %s", e.networkID)
-}
-
-// IsErrNetworkNotFound returns true if the error is caused
-// when a network is not found in the docker host.
-func IsErrNetworkNotFound(err error) bool {
-	return IsErrNotFound(err)
-}
-
-// volumeNotFoundError implements an error returned when a volume is not in the docker host.
-type volumeNotFoundError struct {
-	volumeID string
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e volumeNotFoundError) NotFound() bool {
-	return true
-}
-
-// Error returns a string representation of a volumeNotFoundError
-func (e volumeNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such volume: %s", e.volumeID)
-}
-
-// IsErrVolumeNotFound returns true if the error is caused
-// when a volume is not found in the docker host.
-func IsErrVolumeNotFound(err error) bool {
-	return IsErrNotFound(err)
+func wrapResponseError(err error, resp serverResponse, object, id string) error {
+	switch {
+	case err == nil:
+		return nil
+	case resp.statusCode == http.StatusNotFound:
+		return objectNotFoundError{object: object, id: id}
+	case resp.statusCode == http.StatusNotImplemented:
+		return notImplementedError{message: err.Error()}
+	default:
+		return err
+	}
 }
 
 // unauthorizedError represents an authorization error in a remote registry.
@@ -144,72 +88,6 @@
 	return ok
 }
 
-// nodeNotFoundError implements an error returned when a node is not found.
-type nodeNotFoundError struct {
-	nodeID string
-}
-
-// Error returns a string representation of a nodeNotFoundError
-func (e nodeNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such node: %s", e.nodeID)
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e nodeNotFoundError) NotFound() bool {
-	return true
-}
-
-// IsErrNodeNotFound returns true if the error is caused
-// when a node is not found.
-func IsErrNodeNotFound(err error) bool {
-	_, ok := err.(nodeNotFoundError)
-	return ok
-}
-
-// serviceNotFoundError implements an error returned when a service is not found.
-type serviceNotFoundError struct {
-	serviceID string
-}
-
-// Error returns a string representation of a serviceNotFoundError
-func (e serviceNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such service: %s", e.serviceID)
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e serviceNotFoundError) NotFound() bool {
-	return true
-}
-
-// IsErrServiceNotFound returns true if the error is caused
-// when a service is not found.
-func IsErrServiceNotFound(err error) bool {
-	_, ok := err.(serviceNotFoundError)
-	return ok
-}
-
-// taskNotFoundError implements an error returned when a task is not found.
-type taskNotFoundError struct {
-	taskID string
-}
-
-// Error returns a string representation of a taskNotFoundError
-func (e taskNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such task: %s", e.taskID)
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e taskNotFoundError) NotFound() bool {
-	return true
-}
-
-// IsErrTaskNotFound returns true if the error is caused
-// when a task is not found.
-func IsErrTaskNotFound(err error) bool {
-	_, ok := err.(taskNotFoundError)
-	return ok
-}
-
 type pluginPermissionDenied struct {
 	name string
 }
@@ -225,6 +103,26 @@
 	return ok
 }
 
+type notImplementedError struct {
+	message string
+}
+
+func (e notImplementedError) Error() string {
+	return e.message
+}
+
+func (e notImplementedError) NotImplemented() bool {
+	return true
+}
+
+// IsErrNotImplemented returns true if the error is a NotImplemented error.
+// This is returned by the API when a requested feature has not been
+// implemented.
+func IsErrNotImplemented(err error) bool {
+	te, ok := err.(notImplementedError)
+	return ok && te.NotImplemented()
+}
+
 // NewVersionError returns an error if the APIVersion required
 // if less than the current supported version
 func (cli *Client) NewVersionError(APIrequired, feature string) error {
@@ -233,68 +131,3 @@
 	}
 	return nil
 }
-
-// secretNotFoundError implements an error returned when a secret is not found.
-type secretNotFoundError struct {
-	name string
-}
-
-// Error returns a string representation of a secretNotFoundError
-func (e secretNotFoundError) Error() string {
-	return fmt.Sprintf("Error: no such secret: %s", e.name)
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e secretNotFoundError) NotFound() bool {
-	return true
-}
-
-// IsErrSecretNotFound returns true if the error is caused
-// when a secret is not found.
-func IsErrSecretNotFound(err error) bool {
-	_, ok := err.(secretNotFoundError)
-	return ok
-}
-
-// configNotFoundError implements an error returned when a config is not found.
-type configNotFoundError struct {
-	name string
-}
-
-// Error returns a string representation of a configNotFoundError
-func (e configNotFoundError) Error() string {
-	return fmt.Sprintf("Error: no such config: %s", e.name)
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e configNotFoundError) NotFound() bool {
-	return true
-}
-
-// IsErrConfigNotFound returns true if the error is caused
-// when a config is not found.
-func IsErrConfigNotFound(err error) bool {
-	_, ok := err.(configNotFoundError)
-	return ok
-}
-
-// pluginNotFoundError implements an error returned when a plugin is not in the docker host.
-type pluginNotFoundError struct {
-	name string
-}
-
-// NotFound indicates that this error type is of NotFound
-func (e pluginNotFoundError) NotFound() bool {
-	return true
-}
-
-// Error returns a string representation of a pluginNotFoundError
-func (e pluginNotFoundError) Error() string {
-	return fmt.Sprintf("Error: No such plugin: %s", e.name)
-}
-
-// IsErrPluginNotFound returns true if the error is caused
-// when a plugin is not found in the docker host.
-func IsErrPluginNotFound(err error) bool {
-	return IsErrNotFound(err)
-}
diff --git a/client/hijack.go b/client/hijack.go
index 8cf0119..d04cebd 100644
--- a/client/hijack.go
+++ b/client/hijack.go
@@ -12,7 +12,6 @@
 	"time"
 
 	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/pkg/tlsconfig"
 	"github.com/docker/go-connections/sockets"
 	"github.com/pkg/errors"
 	"golang.org/x/net/context"
@@ -71,7 +70,7 @@
 	timeout := dialer.Timeout
 
 	if !dialer.Deadline.IsZero() {
-		deadlineTimeout := dialer.Deadline.Sub(time.Now())
+		deadlineTimeout := time.Until(dialer.Deadline)
 		if timeout == 0 || deadlineTimeout < timeout {
 			timeout = deadlineTimeout
 		}
@@ -115,7 +114,7 @@
 	// from the hostname we're connecting to.
 	if config.ServerName == "" {
 		// Make a copy to avoid polluting argument or default.
-		config = tlsconfig.Clone(config)
+		config = tlsConfigClone(config)
 		config.ServerName = hostname
 	}
 
diff --git a/client/image_inspect.go b/client/image_inspect.go
index b3a64ce..1bc5919 100644
--- a/client/image_inspect.go
+++ b/client/image_inspect.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 
 	"github.com/docker/docker/api/types"
 	"golang.org/x/net/context"
@@ -14,10 +13,7 @@
 func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {
 	serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil)
 	if err != nil {
-		if serverResp.statusCode == http.StatusNotFound {
-			return types.ImageInspect{}, nil, imageNotFoundError{imageID}
-		}
-		return types.ImageInspect{}, nil, err
+		return types.ImageInspect{}, nil, wrapResponseError(err, serverResp, "image", imageID)
 	}
 	defer ensureReaderClosed(serverResp)
 
diff --git a/client/image_inspect_test.go b/client/image_inspect_test.go
index 74a4e49..b5721f3 100644
--- a/client/image_inspect_test.go
+++ b/client/image_inspect_test.go
@@ -31,7 +31,7 @@
 	}
 
 	_, _, err := client.ImageInspectWithRaw(context.Background(), "unknown")
-	if err == nil || !IsErrImageNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected an imageNotFound error, got %v", err)
 	}
 }
diff --git a/client/image_remove.go b/client/image_remove.go
index 6921209..81d6c54 100644
--- a/client/image_remove.go
+++ b/client/image_remove.go
@@ -19,12 +19,12 @@
 		query.Set("noprune", "1")
 	}
 
+	var dels []types.ImageDeleteResponseItem
 	resp, err := cli.delete(ctx, "/images/"+imageID, query, nil)
 	if err != nil {
-		return nil, err
+		return dels, wrapResponseError(err, resp, "image", imageID)
 	}
 
-	var dels []types.ImageDeleteResponseItem
 	err = json.NewDecoder(resp.body).Decode(&dels)
 	ensureReaderClosed(resp)
 	return dels, err
diff --git a/client/image_remove_test.go b/client/image_remove_test.go
index 9856311..6149db7 100644
--- a/client/image_remove_test.go
+++ b/client/image_remove_test.go
@@ -10,6 +10,7 @@
 	"testing"
 
 	"github.com/docker/docker/api/types"
+	"github.com/stretchr/testify/assert"
 	"golang.org/x/net/context"
 )
 
@@ -19,9 +20,17 @@
 	}
 
 	_, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{})
-	if err == nil || err.Error() != "Error response from daemon: Server error" {
-		t.Fatalf("expected a Server Error, got %v", err)
+	assert.EqualError(t, err, "Error response from daemon: Server error")
+}
+
+func TestImageRemoveImageNotFound(t *testing.T) {
+	client := &Client{
+		client: newMockClient(errorMock(http.StatusNotFound, "missing")),
 	}
+
+	_, err := client.ImageRemove(context.Background(), "unknown", types.ImageRemoveOptions{})
+	assert.EqualError(t, err, "Error: No such image: unknown")
+	assert.True(t, IsErrNotFound(err))
 }
 
 func TestImageRemove(t *testing.T) {
diff --git a/client/image_search.go b/client/image_search.go
index b0fcd5c..5566e92 100644
--- a/client/image_search.go
+++ b/client/image_search.go
@@ -21,7 +21,7 @@
 	query.Set("limit", fmt.Sprintf("%d", options.Limit))
 
 	if options.Filters.Len() > 0 {
-		filterJSON, err := filters.ToParam(options.Filters)
+		filterJSON, err := filters.ToJSON(options.Filters)
 		if err != nil {
 			return results, err
 		}
diff --git a/client/image_search_test.go b/client/image_search_test.go
index b17bbd8..191e7f4 100644
--- a/client/image_search_test.go
+++ b/client/image_search_test.go
@@ -2,18 +2,17 @@
 
 import (
 	"bytes"
+	"encoding/json"
 	"fmt"
 	"io/ioutil"
 	"net/http"
 	"strings"
 	"testing"
 
-	"golang.org/x/net/context"
-
-	"encoding/json"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/registry"
+	"golang.org/x/net/context"
 )
 
 func TestImageSearchAnyError(t *testing.T) {
diff --git a/client/network_inspect.go b/client/network_inspect.go
index 848c979..afabe65 100644
--- a/client/network_inspect.go
+++ b/client/network_inspect.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 	"net/url"
 
 	"github.com/docker/docker/api/types"
@@ -33,10 +32,7 @@
 	}
 	resp, err = cli.get(ctx, "/networks/"+networkID, query, nil)
 	if err != nil {
-		if resp.statusCode == http.StatusNotFound {
-			return networkResource, nil, networkNotFoundError{networkID}
-		}
-		return networkResource, nil, err
+		return networkResource, nil, wrapResponseError(err, resp, "network", networkID)
 	}
 	defer ensureReaderClosed(resp)
 
diff --git a/client/network_inspect_test.go b/client/network_inspect_test.go
index 9bfb55d..56399c7 100644
--- a/client/network_inspect_test.go
+++ b/client/network_inspect_test.go
@@ -21,20 +21,17 @@
 	}
 
 	_, err := client.NetworkInspect(context.Background(), "nothing", types.NetworkInspectOptions{})
-	if err == nil || err.Error() != "Error response from daemon: Server error" {
-		t.Fatalf("expected a Server Error, got %v", err)
-	}
+	assert.EqualError(t, err, "Error response from daemon: Server error")
 }
 
-func TestNetworkInspectContainerNotFound(t *testing.T) {
+func TestNetworkInspectNotFoundError(t *testing.T) {
 	client := &Client{
-		client: newMockClient(errorMock(http.StatusNotFound, "Server error")),
+		client: newMockClient(errorMock(http.StatusNotFound, "missing")),
 	}
 
 	_, err := client.NetworkInspect(context.Background(), "unknown", types.NetworkInspectOptions{})
-	if err == nil || !IsErrNetworkNotFound(err) {
-		t.Fatalf("expected a networkNotFound error, got %v", err)
-	}
+	assert.EqualError(t, err, "Error: No such network: unknown")
+	assert.True(t, IsErrNotFound(err))
 }
 
 func TestNetworkInspect(t *testing.T) {
diff --git a/client/network_remove.go b/client/network_remove.go
index 6bd6748..0811b5b 100644
--- a/client/network_remove.go
+++ b/client/network_remove.go
@@ -6,5 +6,5 @@
 func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error {
 	resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "network", networkID)
 }
diff --git a/client/node_inspect.go b/client/node_inspect.go
index abf505d..791d2c0 100644
--- a/client/node_inspect.go
+++ b/client/node_inspect.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 
 	"github.com/docker/docker/api/types/swarm"
 	"golang.org/x/net/context"
@@ -14,10 +13,7 @@
 func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) {
 	serverResp, err := cli.get(ctx, "/nodes/"+nodeID, nil, nil)
 	if err != nil {
-		if serverResp.statusCode == http.StatusNotFound {
-			return swarm.Node{}, nil, nodeNotFoundError{nodeID}
-		}
-		return swarm.Node{}, nil, err
+		return swarm.Node{}, nil, wrapResponseError(err, serverResp, "node", nodeID)
 	}
 	defer ensureReaderClosed(serverResp)
 
diff --git a/client/node_inspect_test.go b/client/node_inspect_test.go
index dca16a8..6260da5 100644
--- a/client/node_inspect_test.go
+++ b/client/node_inspect_test.go
@@ -30,7 +30,7 @@
 	}
 
 	_, _, err := client.NodeInspectWithRaw(context.Background(), "unknown")
-	if err == nil || !IsErrNodeNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected a nodeNotFoundError error, got %v", err)
 	}
 }
diff --git a/client/node_list.go b/client/node_list.go
index 3e8440f..fed2299 100644
--- a/client/node_list.go
+++ b/client/node_list.go
@@ -15,7 +15,7 @@
 	query := url.Values{}
 
 	if options.Filters.Len() > 0 {
-		filterJSON, err := filters.ToParam(options.Filters)
+		filterJSON, err := filters.ToJSON(options.Filters)
 
 		if err != nil {
 			return nil, err
diff --git a/client/node_remove.go b/client/node_remove.go
index 0a77f3d..adbf52f 100644
--- a/client/node_remove.go
+++ b/client/node_remove.go
@@ -17,5 +17,5 @@
 
 	resp, err := cli.delete(ctx, "/nodes/"+nodeID, query, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "node", nodeID)
 }
diff --git a/client/parse_logs.go b/client/parse_logs.go
deleted file mode 100644
index e427f80..0000000
--- a/client/parse_logs.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package client
-
-// parse_logs.go contains utility helpers for getting information out of docker
-// log lines. really, it only contains ParseDetails right now. maybe in the
-// future there will be some desire to parse log messages back into a struct?
-// that would go here if we did
-
-import (
-	"net/url"
-	"strings"
-
-	"github.com/pkg/errors"
-)
-
-// ParseLogDetails takes a details string of key value pairs in the form
-// "k=v,l=w", where the keys and values are url query escaped, and each pair
-// is separated by a comma, returns a map. returns an error if the details
-// string is not in a valid format
-// the exact form of details encoding is implemented in
-// api/server/httputils/write_log_stream.go
-func ParseLogDetails(details string) (map[string]string, error) {
-	pairs := strings.Split(details, ",")
-	detailsMap := make(map[string]string, len(pairs))
-	for _, pair := range pairs {
-		p := strings.SplitN(pair, "=", 2)
-		// if there is no equals sign, we will only get 1 part back
-		if len(p) != 2 {
-			return nil, errors.New("invalid details format")
-		}
-		k, err := url.QueryUnescape(p[0])
-		if err != nil {
-			return nil, err
-		}
-		v, err := url.QueryUnescape(p[1])
-		if err != nil {
-			return nil, err
-		}
-		detailsMap[k] = v
-	}
-	return detailsMap, nil
-}
diff --git a/client/parse_logs_test.go b/client/parse_logs_test.go
deleted file mode 100644
index ac7f616..0000000
--- a/client/parse_logs_test.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package client
-
-import (
-	"reflect"
-	"testing"
-
-	"github.com/pkg/errors"
-)
-
-func TestParseLogDetails(t *testing.T) {
-	testCases := []struct {
-		line     string
-		expected map[string]string
-		err      error
-	}{
-		{"key=value", map[string]string{"key": "value"}, nil},
-		{"key1=value1,key2=value2", map[string]string{"key1": "value1", "key2": "value2"}, nil},
-		{"key+with+spaces=value%3Dequals,asdf%2C=", map[string]string{"key with spaces": "value=equals", "asdf,": ""}, nil},
-		{"key=,=nothing", map[string]string{"key": "", "": "nothing"}, nil},
-		{"=", map[string]string{"": ""}, nil},
-		{"errors", nil, errors.New("invalid details format")},
-	}
-	for _, tc := range testCases {
-		tc := tc // capture range variable
-		t.Run(tc.line, func(t *testing.T) {
-			t.Parallel()
-			res, err := ParseLogDetails(tc.line)
-			if err != nil && (err.Error() != tc.err.Error()) {
-				t.Fatalf("unexpected error parsing logs:\nExpected:\n\t%v\nActual:\n\t%v", tc.err, err)
-			}
-			if !reflect.DeepEqual(tc.expected, res) {
-				t.Errorf("result does not match expected:\nExpected:\n\t%#v\nActual:\n\t%#v", tc.expected, res)
-			}
-		})
-	}
-}
diff --git a/client/ping.go b/client/ping.go
index a4c2e2c..0b6e450 100644
--- a/client/ping.go
+++ b/client/ping.go
@@ -1,6 +1,8 @@
 package client
 
 import (
+	"path"
+
 	"github.com/docker/docker/api/types"
 	"golang.org/x/net/context"
 )
@@ -8,7 +10,7 @@
 // Ping pings the server and returns the value of the "Docker-Experimental", "OS-Type" & "API-Version" headers
 func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
 	var ping types.Ping
-	req, err := cli.buildRequest("GET", cli.basePath+"/_ping", nil, nil)
+	req, err := cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
 	if err != nil {
 		return ping, err
 	}
@@ -26,7 +28,5 @@
 		}
 		ping.OSType = serverResp.header.Get("OSType")
 	}
-
-	err = cli.checkResponseErr(serverResp)
-	return ping, err
+	return ping, cli.checkResponseErr(serverResp)
 }
diff --git a/client/plugin_inspect.go b/client/plugin_inspect.go
index 89f39ee..6a6fc18 100644
--- a/client/plugin_inspect.go
+++ b/client/plugin_inspect.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 
 	"github.com/docker/docker/api/types"
 	"golang.org/x/net/context"
@@ -14,10 +13,7 @@
 func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
 	resp, err := cli.get(ctx, "/plugins/"+name+"/json", nil, nil)
 	if err != nil {
-		if resp.statusCode == http.StatusNotFound {
-			return nil, nil, pluginNotFoundError{name}
-		}
-		return nil, nil, err
+		return nil, nil, wrapResponseError(err, resp, "plugin", name)
 	}
 
 	defer ensureReaderClosed(resp)
diff --git a/client/plugin_list.go b/client/plugin_list.go
index 3acde3b..78dbeb8 100644
--- a/client/plugin_list.go
+++ b/client/plugin_list.go
@@ -23,7 +23,7 @@
 	}
 	resp, err := cli.get(ctx, "/plugins", query, nil)
 	if err != nil {
-		return plugins, err
+		return plugins, wrapResponseError(err, resp, "plugin", "")
 	}
 
 	err = json.NewDecoder(resp.body).Decode(&plugins)
diff --git a/client/plugin_remove.go b/client/plugin_remove.go
index b017e4d..b498c48 100644
--- a/client/plugin_remove.go
+++ b/client/plugin_remove.go
@@ -16,5 +16,5 @@
 
 	resp, err := cli.delete(ctx, "/plugins/"+name, query, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "plugin", name)
 }
diff --git a/client/request.go b/client/request.go
index 3e7d43f..615d0b9 100644
--- a/client/request.go
+++ b/client/request.go
@@ -203,7 +203,7 @@
 		return err
 	}
 	if len(body) == 0 {
-		return fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL)
+		return fmt.Errorf("request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL)
 	}
 
 	var ct string
diff --git a/client/secret_inspect.go b/client/secret_inspect.go
index 9b60297..6927ea9 100644
--- a/client/secret_inspect.go
+++ b/client/secret_inspect.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 
 	"github.com/docker/docker/api/types/swarm"
 	"golang.org/x/net/context"
@@ -17,10 +16,7 @@
 	}
 	resp, err := cli.get(ctx, "/secrets/"+id, nil, nil)
 	if err != nil {
-		if resp.statusCode == http.StatusNotFound {
-			return swarm.Secret{}, nil, secretNotFoundError{id}
-		}
-		return swarm.Secret{}, nil, err
+		return swarm.Secret{}, nil, wrapResponseError(err, resp, "secret", id)
 	}
 	defer ensureReaderClosed(resp)
 
diff --git a/client/secret_inspect_test.go b/client/secret_inspect_test.go
index 1581da1..66dbb48 100644
--- a/client/secret_inspect_test.go
+++ b/client/secret_inspect_test.go
@@ -42,7 +42,7 @@
 	}
 
 	_, _, err := client.SecretInspectWithRaw(context.Background(), "unknown")
-	if err == nil || !IsErrSecretNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected a secretNotFoundError error, got %v", err)
 	}
 }
diff --git a/client/secret_list.go b/client/secret_list.go
index 0d33ecf..fdee6e2 100644
--- a/client/secret_list.go
+++ b/client/secret_list.go
@@ -18,7 +18,7 @@
 	query := url.Values{}
 
 	if options.Filters.Len() > 0 {
-		filterJSON, err := filters.ToParam(options.Filters)
+		filterJSON, err := filters.ToJSON(options.Filters)
 		if err != nil {
 			return nil, err
 		}
diff --git a/client/secret_remove.go b/client/secret_remove.go
index c5e37af..9b4ee71 100644
--- a/client/secret_remove.go
+++ b/client/secret_remove.go
@@ -9,5 +9,5 @@
 	}
 	resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "secret", id)
 }
diff --git a/client/service_create.go b/client/service_create.go
index a368394..834709d 100644
--- a/client/service_create.go
+++ b/client/service_create.go
@@ -3,11 +3,12 @@
 import (
 	"encoding/json"
 	"fmt"
+	"strings"
 
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/swarm"
-	"github.com/opencontainers/go-digest"
+	digest "github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 )
@@ -85,21 +86,30 @@
 	return response, err
 }
 
-func imageDigestAndPlatforms(ctx context.Context, cli *Client, image, encodedAuth string) (string, []swarm.Platform, error) {
+func imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, image, encodedAuth string) (string, []swarm.Platform, error) {
 	distributionInspect, err := cli.DistributionInspect(ctx, image, encodedAuth)
-	imageWithDigest := image
 	var platforms []swarm.Platform
 	if err != nil {
 		return "", nil, err
 	}
 
-	imageWithDigest = imageWithDigestString(image, distributionInspect.Descriptor.Digest)
+	imageWithDigest := imageWithDigestString(image, distributionInspect.Descriptor.Digest)
 
 	if len(distributionInspect.Platforms) > 0 {
 		platforms = make([]swarm.Platform, 0, len(distributionInspect.Platforms))
 		for _, p := range distributionInspect.Platforms {
+			// clear architecture field for arm. This is a temporary patch to address
+			// https://github.com/docker/swarmkit/issues/2294. The issue is that while
+			// image manifests report "arm" as the architecture, the node reports
+			// something like "armv7l" (includes the variant), which causes arm images
+			// to stop working with swarm mode. This patch removes the architecture
+			// constraint for arm images to ensure tasks get scheduled.
+			arch := p.Architecture
+			if strings.ToLower(arch) == "arm" {
+				arch = ""
+			}
 			platforms = append(platforms, swarm.Platform{
-				Architecture: p.Architecture,
+				Architecture: arch,
 				OS:           p.OS,
 			})
 		}
diff --git a/client/service_inspect.go b/client/service_inspect.go
index d7e051e..3e9699e 100644
--- a/client/service_inspect.go
+++ b/client/service_inspect.go
@@ -5,7 +5,6 @@
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
-	"net/http"
 	"net/url"
 
 	"github.com/docker/docker/api/types"
@@ -19,10 +18,7 @@
 	query.Set("insertDefaults", fmt.Sprintf("%v", opts.InsertDefaults))
 	serverResp, err := cli.get(ctx, "/services/"+serviceID, query, nil)
 	if err != nil {
-		if serverResp.statusCode == http.StatusNotFound {
-			return swarm.Service{}, nil, serviceNotFoundError{serviceID}
-		}
-		return swarm.Service{}, nil, err
+		return swarm.Service{}, nil, wrapResponseError(err, serverResp, "service", serviceID)
 	}
 	defer ensureReaderClosed(serverResp)
 
diff --git a/client/service_inspect_test.go b/client/service_inspect_test.go
index d53f583..ade6253 100644
--- a/client/service_inspect_test.go
+++ b/client/service_inspect_test.go
@@ -31,7 +31,7 @@
 	}
 
 	_, _, err := client.ServiceInspectWithRaw(context.Background(), "unknown", types.ServiceInspectOptions{})
-	if err == nil || !IsErrServiceNotFound(err) {
+	if err == nil || !IsErrNotFound(err) {
 		t.Fatalf("expected a serviceNotFoundError error, got %v", err)
 	}
 }
diff --git a/client/service_list.go b/client/service_list.go
index c29e6d4..eb3ff97 100644
--- a/client/service_list.go
+++ b/client/service_list.go
@@ -15,7 +15,7 @@
 	query := url.Values{}
 
 	if options.Filters.Len() > 0 {
-		filterJSON, err := filters.ToParam(options.Filters)
+		filterJSON, err := filters.ToJSON(options.Filters)
 		if err != nil {
 			return nil, err
 		}
diff --git a/client/service_remove.go b/client/service_remove.go
index a9331f9..ad992c0 100644
--- a/client/service_remove.go
+++ b/client/service_remove.go
@@ -6,5 +6,5 @@
 func (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error {
 	resp, err := cli.delete(ctx, "/services/"+serviceID, nil, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "service", serviceID)
 }
diff --git a/client/service_remove_test.go b/client/service_remove_test.go
index 8e2ac25..d7c51ef 100644
--- a/client/service_remove_test.go
+++ b/client/service_remove_test.go
@@ -8,6 +8,7 @@
 	"strings"
 	"testing"
 
+	"github.com/stretchr/testify/assert"
 	"golang.org/x/net/context"
 )
 
@@ -17,9 +18,17 @@
 	}
 
 	err := client.ServiceRemove(context.Background(), "service_id")
-	if err == nil || err.Error() != "Error response from daemon: Server error" {
-		t.Fatalf("expected a Server Error, got %v", err)
+	assert.EqualError(t, err, "Error response from daemon: Server error")
+}
+
+func TestServiceRemoveNotFoundError(t *testing.T) {
+	client := &Client{
+		client: newMockClient(errorMock(http.StatusNotFound, "missing")),
 	}
+
+	err := client.ServiceRemove(context.Background(), "service_id")
+	assert.EqualError(t, err, "Error: No such service: service_id")
+	assert.True(t, IsErrNotFound(err))
 }
 
 func TestServiceRemove(t *testing.T) {
diff --git a/client/session/filesync/diffcopy.go b/client/session/filesync/diffcopy.go
deleted file mode 100644
index 533847a..0000000
--- a/client/session/filesync/diffcopy.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package filesync
-
-import (
-	"time"
-
-	"google.golang.org/grpc"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/tonistiigi/fsutil"
-)
-
-func sendDiffCopy(stream grpc.Stream, dir string, includes, excludes []string, progress progressCb) error {
-	return fsutil.Send(stream.Context(), stream, dir, &fsutil.WalkOpt{
-		ExcludePatterns: excludes,
-		IncludePaths:    includes, // TODO: rename IncludePatterns
-	}, progress)
-}
-
-func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater) error {
-	st := time.Now()
-	defer func() {
-		logrus.Debugf("diffcopy took: %v", time.Since(st))
-	}()
-	var cf fsutil.ChangeFunc
-	if cu != nil {
-		cu.MarkSupported(true)
-		cf = cu.HandleChange
-	}
-
-	return fsutil.Receive(ds.Context(), ds, dest, cf)
-}
diff --git a/client/session/filesync/filesync_test.go b/client/session/filesync/filesync_test.go
deleted file mode 100644
index b48c08b..0000000
--- a/client/session/filesync/filesync_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package filesync
-
-import (
-	"context"
-	"io/ioutil"
-	"path/filepath"
-	"testing"
-
-	"github.com/docker/docker/client/session"
-	"github.com/docker/docker/client/session/testutil"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"golang.org/x/sync/errgroup"
-)
-
-func TestFileSyncIncludePatterns(t *testing.T) {
-	tmpDir, err := ioutil.TempDir("", "fsynctest")
-	require.NoError(t, err)
-
-	destDir, err := ioutil.TempDir("", "fsynctest")
-	require.NoError(t, err)
-
-	err = ioutil.WriteFile(filepath.Join(tmpDir, "foo"), []byte("content1"), 0600)
-	require.NoError(t, err)
-
-	err = ioutil.WriteFile(filepath.Join(tmpDir, "bar"), []byte("content2"), 0600)
-	require.NoError(t, err)
-
-	s, err := session.NewSession("foo", "bar")
-	require.NoError(t, err)
-
-	m, err := session.NewManager()
-	require.NoError(t, err)
-
-	fs := NewFSSyncProvider(tmpDir, nil)
-	s.Allow(fs)
-
-	dialer := session.Dialer(testutil.TestStream(testutil.Handler(m.HandleConn)))
-
-	g, ctx := errgroup.WithContext(context.Background())
-
-	g.Go(func() error {
-		return s.Run(ctx, dialer)
-	})
-
-	g.Go(func() (reterr error) {
-		c, err := m.Get(ctx, s.UUID())
-		if err != nil {
-			return err
-		}
-		if err := FSSync(ctx, c, FSSendRequestOpt{
-			DestDir:         destDir,
-			IncludePatterns: []string{"ba*"},
-		}); err != nil {
-			return err
-		}
-
-		_, err = ioutil.ReadFile(filepath.Join(destDir, "foo"))
-		assert.Error(t, err)
-
-		dt, err := ioutil.ReadFile(filepath.Join(destDir, "bar"))
-		if err != nil {
-			return err
-		}
-		assert.Equal(t, "content2", string(dt))
-		return s.Close()
-	})
-
-	err = g.Wait()
-	require.NoError(t, err)
-}
diff --git a/client/session/filesync/tarstream.go b/client/session/filesync/tarstream.go
deleted file mode 100644
index da139eb..0000000
--- a/client/session/filesync/tarstream.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package filesync
-
-import (
-	"io"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/pkg/archive"
-	"github.com/docker/docker/pkg/chrootarchive"
-	"github.com/pkg/errors"
-	"google.golang.org/grpc"
-)
-
-func sendTarStream(stream grpc.Stream, dir string, includes, excludes []string, progress progressCb) error {
-	a, err := archive.TarWithOptions(dir, &archive.TarOptions{
-		ExcludePatterns: excludes,
-	})
-	if err != nil {
-		return err
-	}
-
-	size := 0
-	buf := make([]byte, 1<<15)
-	t := new(BytesMessage)
-	for {
-		n, err := a.Read(buf)
-		if err != nil {
-			if err == io.EOF {
-				break
-			}
-			return err
-		}
-		t.Data = buf[:n]
-
-		if err := stream.SendMsg(t); err != nil {
-			return err
-		}
-		size += n
-		if progress != nil {
-			progress(size, false)
-		}
-	}
-	if progress != nil {
-		progress(size, true)
-	}
-	return nil
-}
-
-func recvTarStream(ds grpc.Stream, dest string, cs CacheUpdater) error {
-
-	pr, pw := io.Pipe()
-
-	go func() {
-		var (
-			err error
-			t   = new(BytesMessage)
-		)
-		for {
-			if err = ds.RecvMsg(t); err != nil {
-				if err == io.EOF {
-					err = nil
-				}
-				break
-			}
-			_, err = pw.Write(t.Data)
-			if err != nil {
-				break
-			}
-		}
-		if err = pw.CloseWithError(err); err != nil {
-			logrus.Errorf("failed to close tar transfer pipe")
-		}
-	}()
-
-	decompressedStream, err := archive.DecompressStream(pr)
-	if err != nil {
-		return errors.Wrap(err, "failed to decompress stream")
-	}
-
-	if err := chrootarchive.Untar(decompressedStream, dest, nil); err != nil {
-		return errors.Wrap(err, "failed to untar context")
-	}
-	return nil
-}
diff --git a/client/session/testutil/testutil.go b/client/session/testutil/testutil.go
deleted file mode 100644
index 2e145d9..0000000
--- a/client/session/testutil/testutil.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package testutil
-
-import (
-	"io"
-	"net"
-	"time"
-
-	"github.com/Sirupsen/logrus"
-	"golang.org/x/net/context"
-)
-
-// Handler is function called to handle incoming connection
-type Handler func(ctx context.Context, conn net.Conn, meta map[string][]string) error
-
-// Dialer is a function for dialing an outgoing connection
-type Dialer func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error)
-
-// TestStream creates an in memory session dialer for a handler function
-func TestStream(handler Handler) Dialer {
-	s1, s2 := sockPair()
-	return func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) {
-		go func() {
-			err := handler(context.TODO(), s1, meta)
-			if err != nil {
-				logrus.Error(err)
-			}
-			s1.Close()
-		}()
-		return s2, nil
-	}
-}
-
-func sockPair() (*sock, *sock) {
-	pr1, pw1 := io.Pipe()
-	pr2, pw2 := io.Pipe()
-	return &sock{pw1, pr2, pw1}, &sock{pw2, pr1, pw2}
-}
-
-type sock struct {
-	io.Writer
-	io.Reader
-	io.Closer
-}
-
-func (s *sock) LocalAddr() net.Addr {
-	return dummyAddr{}
-}
-func (s *sock) RemoteAddr() net.Addr {
-	return dummyAddr{}
-}
-func (s *sock) SetDeadline(t time.Time) error {
-	return nil
-}
-func (s *sock) SetReadDeadline(t time.Time) error {
-	return nil
-}
-func (s *sock) SetWriteDeadline(t time.Time) error {
-	return nil
-}
-
-type dummyAddr struct {
-}
-
-func (d dummyAddr) Network() string {
-	return "tcp"
-}
-
-func (d dummyAddr) String() string {
-	return "localhost"
-}
diff --git a/client/swarm_get_unlock_key_test.go b/client/swarm_get_unlock_key_test.go
index 8dd08d9..fbb290a 100644
--- a/client/swarm_get_unlock_key_test.go
+++ b/client/swarm_get_unlock_key_test.go
@@ -10,7 +10,7 @@
 	"testing"
 
 	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/pkg/testutil"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"golang.org/x/net/context"
diff --git a/client/task_inspect.go b/client/task_inspect.go
index bc8058f..dc08ced 100644
--- a/client/task_inspect.go
+++ b/client/task_inspect.go
@@ -4,10 +4,8 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
 
 	"github.com/docker/docker/api/types/swarm"
-
 	"golang.org/x/net/context"
 )
 
@@ -15,10 +13,7 @@
 func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) {
 	serverResp, err := cli.get(ctx, "/tasks/"+taskID, nil, nil)
 	if err != nil {
-		if serverResp.statusCode == http.StatusNotFound {
-			return swarm.Task{}, nil, taskNotFoundError{taskID}
-		}
-		return swarm.Task{}, nil, err
+		return swarm.Task{}, nil, wrapResponseError(err, serverResp, "task", taskID)
 	}
 	defer ensureReaderClosed(serverResp)
 
diff --git a/client/task_list.go b/client/task_list.go
index 66324da..01bd695 100644
--- a/client/task_list.go
+++ b/client/task_list.go
@@ -15,7 +15,7 @@
 	query := url.Values{}
 
 	if options.Filters.Len() > 0 {
-		filterJSON, err := filters.ToParam(options.Filters)
+		filterJSON, err := filters.ToJSON(options.Filters)
 		if err != nil {
 			return nil, err
 		}
diff --git a/client/tlsconfig_clone.go b/client/tlsconfig_clone.go
new file mode 100644
index 0000000..99b6be1
--- /dev/null
+++ b/client/tlsconfig_clone.go
@@ -0,0 +1,11 @@
+// +build go1.8
+
+package client
+
+import "crypto/tls"
+
+// tlsConfigClone returns a clone of tls.Config. This function is provided for
+// compatibility for go1.7 that doesn't include this method in stdlib.
+func tlsConfigClone(c *tls.Config) *tls.Config {
+	return c.Clone()
+}
diff --git a/pkg/tlsconfig/tlsconfig_clone_go17.go b/client/tlsconfig_clone_go17.go
similarity index 88%
rename from pkg/tlsconfig/tlsconfig_clone_go17.go
rename to client/tlsconfig_clone_go17.go
index 0d5b448..b837b2a 100644
--- a/pkg/tlsconfig/tlsconfig_clone_go17.go
+++ b/client/tlsconfig_clone_go17.go
@@ -1,12 +1,12 @@
 // +build go1.7,!go1.8
 
-package tlsconfig
+package client
 
 import "crypto/tls"
 
-// Clone returns a clone of tls.Config. This function is provided for
+// tlsConfigClone returns a clone of tls.Config. This function is provided for
 // compatibility for go1.7 that doesn't include this method in stdlib.
-func Clone(c *tls.Config) *tls.Config {
+func tlsConfigClone(c *tls.Config) *tls.Config {
 	return &tls.Config{
 		Rand:                        c.Rand,
 		Time:                        c.Time,
diff --git a/client/transport.go b/client/transport.go
index 401ab15..73f6ef7 100644
--- a/client/transport.go
+++ b/client/transport.go
@@ -5,14 +5,6 @@
 	"net/http"
 )
 
-// transportFunc allows us to inject a mock transport for testing. We define it
-// here so we can detect the tlsconfig and return nil for only this type.
-type transportFunc func(*http.Request) (*http.Response, error)
-
-func (tf transportFunc) RoundTrip(req *http.Request) (*http.Response, error) {
-	return tf(req)
-}
-
 // resolveTLSConfig attempts to resolve the TLS configuration from the
 // RoundTripper.
 func resolveTLSConfig(transport http.RoundTripper) *tls.Config {
diff --git a/client/utils.go b/client/utils.go
index f3d8877..1377050 100644
--- a/client/utils.go
+++ b/client/utils.go
@@ -24,7 +24,7 @@
 func getFiltersQuery(f filters.Args) (url.Values, error) {
 	query := url.Values{}
 	if f.Len() > 0 {
-		filterJSON, err := filters.ToParam(f)
+		filterJSON, err := filters.ToJSON(f)
 		if err != nil {
 			return query, err
 		}
diff --git a/client/volume_inspect.go b/client/volume_inspect.go
index 3860e9b..9889343 100644
--- a/client/volume_inspect.go
+++ b/client/volume_inspect.go
@@ -4,7 +4,7 @@
 	"bytes"
 	"encoding/json"
 	"io/ioutil"
-	"net/http"
+	"path"
 
 	"github.com/docker/docker/api/types"
 	"golang.org/x/net/context"
@@ -18,13 +18,17 @@
 
 // VolumeInspectWithRaw returns the information about a specific volume in the docker host and its raw representation
 func (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (types.Volume, []byte, error) {
+	// The empty ID needs to be handled here because with an empty ID the
+	// request url will not contain a trailing / which calls the volume list API
+	// instead of volume inspect
+	if volumeID == "" {
+		return types.Volume{}, nil, objectNotFoundError{object: "volume", id: volumeID}
+	}
+
 	var volume types.Volume
-	resp, err := cli.get(ctx, "/volumes/"+volumeID, nil, nil)
+	resp, err := cli.get(ctx, path.Join("/volumes", volumeID), nil, nil)
 	if err != nil {
-		if resp.statusCode == http.StatusNotFound {
-			return volume, nil, volumeNotFoundError{volumeID}
-		}
-		return volume, nil, err
+		return volume, nil, wrapResponseError(err, resp, "volume", volumeID)
 	}
 	defer ensureReaderClosed(resp)
 
diff --git a/client/volume_inspect_test.go b/client/volume_inspect_test.go
index 0d1d118..7d01f44 100644
--- a/client/volume_inspect_test.go
+++ b/client/volume_inspect_test.go
@@ -10,6 +10,9 @@
 	"testing"
 
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/internal/testutil"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	"golang.org/x/net/context"
 )
 
@@ -19,9 +22,7 @@
 	}
 
 	_, err := client.VolumeInspect(context.Background(), "nothing")
-	if err == nil || err.Error() != "Error response from daemon: Server error" {
-		t.Fatalf("expected a Server Error, got %v", err)
-	}
+	testutil.ErrorContains(t, err, "Error response from daemon: Server error")
 }
 
 func TestVolumeInspectNotFound(t *testing.T) {
@@ -30,13 +31,34 @@
 	}
 
 	_, err := client.VolumeInspect(context.Background(), "unknown")
-	if err == nil || !IsErrVolumeNotFound(err) {
-		t.Fatalf("expected a volumeNotFound error, got %v", err)
+	assert.True(t, IsErrNotFound(err))
+}
+
+func TestVolumeInspectWithEmptyID(t *testing.T) {
+	expectedURL := "/volumes/"
+
+	client := &Client{
+		client: newMockClient(func(req *http.Request) (*http.Response, error) {
+			assert.Equal(t, req.URL.Path, expectedURL)
+			return &http.Response{
+				StatusCode: http.StatusNotFound,
+				Body:       ioutil.NopCloser(bytes.NewReader(nil)),
+			}, nil
+		}),
 	}
+	_, err := client.VolumeInspect(context.Background(), "")
+	testutil.ErrorContains(t, err, "No such volume: ")
+
 }
 
 func TestVolumeInspect(t *testing.T) {
 	expectedURL := "/volumes/volume_id"
+	expected := types.Volume{
+		Name:       "name",
+		Driver:     "driver",
+		Mountpoint: "mountpoint",
+	}
+
 	client := &Client{
 		client: newMockClient(func(req *http.Request) (*http.Response, error) {
 			if !strings.HasPrefix(req.URL.Path, expectedURL) {
@@ -45,11 +67,7 @@
 			if req.Method != "GET" {
 				return nil, fmt.Errorf("expected GET method, got %s", req.Method)
 			}
-			content, err := json.Marshal(types.Volume{
-				Name:       "name",
-				Driver:     "driver",
-				Mountpoint: "mountpoint",
-			})
+			content, err := json.Marshal(expected)
 			if err != nil {
 				return nil, err
 			}
@@ -60,17 +78,7 @@
 		}),
 	}
 
-	v, err := client.VolumeInspect(context.Background(), "volume_id")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if v.Name != "name" {
-		t.Fatalf("expected `name`, got %s", v.Name)
-	}
-	if v.Driver != "driver" {
-		t.Fatalf("expected `driver`, got %s", v.Driver)
-	}
-	if v.Mountpoint != "mountpoint" {
-		t.Fatalf("expected `mountpoint`, got %s", v.Mountpoint)
-	}
+	volume, err := client.VolumeInspect(context.Background(), "volume_id")
+	require.NoError(t, err)
+	assert.Equal(t, expected, volume)
 }
diff --git a/client/volume_remove.go b/client/volume_remove.go
index 6c26575..3ffb8bc 100644
--- a/client/volume_remove.go
+++ b/client/volume_remove.go
@@ -17,5 +17,5 @@
 	}
 	resp, err := cli.delete(ctx, "/volumes/"+volumeID, query, nil)
 	ensureReaderClosed(resp)
-	return err
+	return wrapResponseError(err, resp, "volume", volumeID)
 }
diff --git a/cmd/dockerd/config.go b/cmd/dockerd/config.go
index fa5565e..f80641b 100644
--- a/cmd/dockerd/config.go
+++ b/cmd/dockerd/config.go
@@ -5,6 +5,7 @@
 
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/opts"
+	"github.com/docker/docker/registry"
 	"github.com/spf13/pflag"
 )
 
@@ -19,7 +20,7 @@
 func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
 	var maxConcurrentDownloads, maxConcurrentUploads int
 
-	conf.ServiceOptions.InstallCliFlags(flags)
+	installRegistryServiceFlags(&conf.ServiceOptions, flags)
 
 	flags.Var(opts.NewNamedListOptsRef("storage-opts", &conf.GraphOptions, nil), "storage-opt", "Storage driver options")
 	flags.Var(opts.NewNamedListOptsRef("authorization-plugins", &conf.AuthorizationPlugins, nil), "authorization-plugin", "Authorization plugins to load")
@@ -75,3 +76,17 @@
 	conf.MaxConcurrentDownloads = &maxConcurrentDownloads
 	conf.MaxConcurrentUploads = &maxConcurrentUploads
 }
+
+func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.FlagSet) {
+	ana := opts.NewNamedListOptsRef("allow-nondistributable-artifacts", &options.AllowNondistributableArtifacts, registry.ValidateIndexName)
+	mirrors := opts.NewNamedListOptsRef("registry-mirrors", &options.Mirrors, registry.ValidateMirror)
+	insecureRegistries := opts.NewNamedListOptsRef("insecure-registries", &options.InsecureRegistries, registry.ValidateIndexName)
+
+	flags.Var(ana, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry")
+	flags.Var(mirrors, "registry-mirror", "Preferred Docker registry mirror")
+	flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
+
+	if runtime.GOOS != "windows" {
+		flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries")
+	}
+}
diff --git a/cmd/dockerd/config_solaris.go b/cmd/dockerd/config_solaris.go
index 582211c..ed67064 100644
--- a/cmd/dockerd/config_solaris.go
+++ b/cmd/dockerd/config_solaris.go
@@ -2,8 +2,6 @@
 
 import (
 	"github.com/docker/docker/daemon/config"
-	runconfigopts "github.com/docker/docker/runconfig/opts"
-	units "github.com/docker/go-units"
 	"github.com/spf13/pflag"
 )
 
diff --git a/cmd/dockerd/config_unix.go b/cmd/dockerd/config_unix.go
index ba37121..ad27a46 100644
--- a/cmd/dockerd/config_unix.go
+++ b/cmd/dockerd/config_unix.go
@@ -33,8 +33,6 @@
 	flags.StringVar(&conf.BridgeConfig.FixedCIDRv6, "fixed-cidr-v6", "", "IPv6 subnet for fixed IPs")
 	flags.BoolVar(&conf.BridgeConfig.EnableUserlandProxy, "userland-proxy", true, "Use userland proxy for loopback traffic")
 	flags.StringVar(&conf.BridgeConfig.UserlandProxyPath, "userland-proxy-path", "", "Path to the userland proxy binary")
-	flags.BoolVar(&conf.EnableCors, "api-enable-cors", false, "Enable CORS headers in the Engine API, this is deprecated by --api-cors-header")
-	flags.MarkDeprecated("api-enable-cors", "Please use --api-cors-header")
 	flags.StringVar(&conf.CgroupParent, "cgroup-parent", "", "Set parent cgroup for all containers")
 	flags.StringVar(&conf.RemappedRoot, "userns-remap", "", "User/Group setting for user namespaces")
 	flags.StringVar(&conf.ContainerdAddr, "containerd", "", "Path to containerd socket")
@@ -47,6 +45,7 @@
 	flags.StringVar(&conf.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile")
 	flags.Var(&conf.ShmSize, "default-shm-size", "Default shm size for containers")
 	flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers")
+	flags.StringVar(&conf.IpcMode, "default-ipc-mode", config.DefaultIpcMode, `Default mode for containers ipc ("shareable" | "private")`)
 
 	attachExperimentalFlags(conf, flags)
 }
diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go
index 215f9c2..c76886f 100644
--- a/cmd/dockerd/daemon.go
+++ b/cmd/dockerd/daemon.go
@@ -9,7 +9,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/uuid"
 	"github.com/docker/docker/api"
 	apiserver "github.com/docker/docker/api/server"
@@ -30,17 +29,16 @@
 	"github.com/docker/docker/builder/dockerfile"
 	"github.com/docker/docker/builder/fscache"
 	"github.com/docker/docker/cli/debug"
-	"github.com/docker/docker/client/session"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon/cluster"
 	"github.com/docker/docker/daemon/config"
+	"github.com/docker/docker/daemon/listeners"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/libcontainerd"
 	dopts "github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/authorization"
-	"github.com/docker/docker/pkg/jsonlog"
-	"github.com/docker/docker/pkg/listeners"
+	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/docker/docker/pkg/pidfile"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/signal"
@@ -50,7 +48,9 @@
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/go-connections/tlsconfig"
 	swarmapi "github.com/docker/swarmkit/api"
+	"github.com/moby/buildkit/session"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/pflag"
 )
 
@@ -94,10 +94,13 @@
 	}
 
 	logrus.SetFormatter(&logrus.TextFormatter{
-		TimestampFormat: jsonlog.RFC3339NanoFixed,
+		TimestampFormat: jsonmessage.RFC3339NanoFixed,
 		DisableColors:   cli.Config.RawLogs,
+		FullTimestamp:   true,
 	})
 
+	system.InitLCOW(cli.Config.Experimental)
+
 	if err := setDefaultUmask(); err != nil {
 		return fmt.Errorf("Failed to set umask: %v", err)
 	}
@@ -131,7 +134,6 @@
 		Logging:     true,
 		SocketGroup: cli.Config.SocketGroup,
 		Version:     dockerversion.Version,
-		EnableCors:  cli.Config.EnableCors,
 		CorsHeaders: cli.Config.CorsHeaders,
 	}
 
@@ -197,7 +199,11 @@
 		cli.api.Accept(addr, ls...)
 	}
 
-	registryService := registry.NewService(cli.Config.ServiceOptions)
+	registryService, err := registry.NewService(cli.Config.ServiceOptions)
+	if err != nil {
+		return err
+	}
+
 	containerdRemote, err := libcontainerd.New(cli.getLibcontainerdRoot(), cli.getPlatformRemoteOptions()...)
 	if err != nil {
 		return err
@@ -205,7 +211,7 @@
 	signal.Trap(func() {
 		cli.stop()
 		<-stopc // wait for daemonCli.start() to return
-	})
+	}, logrus.StandardLogger())
 
 	// Notify that the API is active, but before daemon is set up.
 	preNotifySystem()
@@ -452,7 +458,7 @@
 		c, err := config.MergeDaemonConfigurations(conf, flags, opts.configFile)
 		if err != nil {
 			if flags.Changed("config-file") || !os.IsNotExist(err) {
-				return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v\n", opts.configFile, err)
+				return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v", opts.configFile, err)
 			}
 		}
 		// the merged configuration can be nil if the config file didn't exist.
@@ -466,7 +472,7 @@
 		return nil, err
 	}
 
-	if conf.V2Only == false {
+	if !conf.V2Only {
 		logrus.Warnf(`The "disable-legacy-registry" option is deprecated and wil be removed in Docker v17.12. Interacting with legacy (v1) registries will no longer be supported in Docker v17.12"`)
 	}
 
@@ -538,7 +544,7 @@
 }
 
 // TODO: remove this from cli and return the authzMiddleware
-func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config, pluginStore *plugin.Store) error {
+func (cli *DaemonCli) initMiddlewares(s *apiserver.Server, cfg *apiserver.Config, pluginStore plugingetter.PluginGetter) error {
 	v := cfg.Version
 
 	exp := middleware.NewExperimentalMiddleware(cli.Config.Experimental)
@@ -547,7 +553,7 @@
 	vm := middleware.NewVersionMiddleware(v, api.DefaultVersion, api.MinVersion)
 	s.UseMiddleware(vm)
 
-	if cfg.EnableCors || cfg.CorsHeaders != "" {
+	if cfg.CorsHeaders != "" {
 		c := middleware.NewCORSMiddleware(cfg.CorsHeaders)
 		s.UseMiddleware(c)
 	}
diff --git a/cmd/dockerd/daemon_solaris.go b/cmd/dockerd/daemon_solaris.go
index dab4d4a..9ee18da 100644
--- a/cmd/dockerd/daemon_solaris.go
+++ b/cmd/dockerd/daemon_solaris.go
@@ -5,27 +5,14 @@
 import (
 	"fmt"
 	"net"
-	"os"
 	"path/filepath"
 
 	"github.com/docker/docker/libcontainerd"
-	"github.com/docker/docker/pkg/system"
 	"golang.org/x/sys/unix"
 )
 
 const defaultDaemonConfigFile = ""
 
-// currentUserIsOwner checks whether the current user is the owner of the given
-// file.
-func currentUserIsOwner(f string) bool {
-	if fileInfo, err := system.Stat(f); err == nil && fileInfo != nil {
-		if int(fileInfo.UID()) == os.Getuid() {
-			return true
-		}
-	}
-	return false
-}
-
 // setDefaultUmask sets the umask to 0022 to avoid problems
 // caused by custom umask
 func setDefaultUmask() error {
diff --git a/cmd/dockerd/daemon_test.go b/cmd/dockerd/daemon_test.go
index 7ae91fe..c559ee8 100644
--- a/cmd/dockerd/daemon_test.go
+++ b/cmd/dockerd/daemon_test.go
@@ -3,10 +3,10 @@
 import (
 	"testing"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/config"
-	"github.com/docker/docker/pkg/testutil"
-	"github.com/docker/docker/pkg/testutil/tempfile"
+	"github.com/docker/docker/internal/testutil"
+	"github.com/gotestyourself/gotestyourself/fs"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/pflag"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -46,9 +46,9 @@
 }
 
 func TestLoadDaemonCliConfigWithConflicts(t *testing.T) {
-	tempFile := tempfile.NewTempFile(t, "config", `{"labels": ["l3=foo"]}`)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(`{"labels": ["l3=foo"]}`))
 	defer tempFile.Remove()
-	configFile := tempFile.Name()
+	configFile := tempFile.Path()
 
 	opts := defaultOptions(configFile)
 	flags := opts.flags
@@ -62,10 +62,10 @@
 }
 
 func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) {
-	tempFile := tempfile.NewTempFile(t, "config", `{"tlsverify": true}`)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(`{"tlsverify": true}`))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	opts.TLSOptions.CAFile = "/tmp/ca.pem"
 
 	loadedConfig, err := loadDaemonCliConfig(opts)
@@ -75,10 +75,10 @@
 }
 
 func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) {
-	tempFile := tempfile.NewTempFile(t, "config", `{"tlsverify": false}`)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(`{"tlsverify": false}`))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	opts.TLSOptions.CAFile = "/tmp/ca.pem"
 
 	loadedConfig, err := loadDaemonCliConfig(opts)
@@ -88,10 +88,10 @@
 }
 
 func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) {
-	tempFile := tempfile.NewTempFile(t, "config", `{}`)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(`{}`))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	opts.TLSOptions.CAFile = "/tmp/ca.pem"
 
 	loadedConfig, err := loadDaemonCliConfig(opts)
@@ -101,10 +101,10 @@
 }
 
 func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) {
-	tempFile := tempfile.NewTempFile(t, "config", `{"log-level": "warn"}`)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(`{"log-level": "warn"}`))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
@@ -114,10 +114,10 @@
 
 func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) {
 	content := `{"tlscacert": "/etc/certs/ca.pem", "log-driver": "syslog"}`
-	tempFile := tempfile.NewTempFile(t, "config", content)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(content))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
@@ -131,10 +131,10 @@
 		"registry-mirrors": ["https://mirrors.docker.com"],
 		"insecure-registries": ["https://insecure.docker.com"]
 	}`
-	tempFile := tempfile.NewTempFile(t, "config", content)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(content))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
diff --git a/cmd/dockerd/daemon_unix_test.go b/cmd/dockerd/daemon_unix_test.go
index ebe7336..5d99e51 100644
--- a/cmd/dockerd/daemon_unix_test.go
+++ b/cmd/dockerd/daemon_unix_test.go
@@ -9,17 +9,17 @@
 	"testing"
 
 	"github.com/docker/docker/daemon/config"
-	"github.com/docker/docker/pkg/testutil/tempfile"
+	"github.com/gotestyourself/gotestyourself/fs"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
 	content := `{"log-opts": {"max-size": "1k"}}`
-	tempFile := tempfile.NewTempFile(t, "config", content)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(content))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	opts.Debug = true
 	opts.LogLevel = "info"
 	assert.NoError(t, opts.flags.Set("selinux-enabled", "true"))
@@ -37,10 +37,10 @@
 
 func TestLoadDaemonConfigWithNetwork(t *testing.T) {
 	content := `{"bip": "127.0.0.2", "ip": "127.0.0.1"}`
-	tempFile := tempfile.NewTempFile(t, "config", content)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(content))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
@@ -54,10 +54,10 @@
 		"cluster-store-opts": {"kv.cacertfile": "/var/lib/docker/discovery_certs/ca.pem"},
 		"log-opts": {"tag": "test"}
 }`
-	tempFile := tempfile.NewTempFile(t, "config", content)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(content))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
@@ -71,10 +71,10 @@
 
 func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) {
 	content := `{ "userland-proxy": false }`
-	tempFile := tempfile.NewTempFile(t, "config", content)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(content))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
@@ -90,10 +90,10 @@
 }
 
 func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {
-	tempFile := tempfile.NewTempFile(t, "config", `{}`)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(`{}`))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
@@ -103,10 +103,10 @@
 
 func TestLoadDaemonConfigWithLegacyRegistryOptions(t *testing.T) {
 	content := `{"disable-legacy-registry": false}`
-	tempFile := tempfile.NewTempFile(t, "config", content)
+	tempFile := fs.NewFile(t, "config", fs.WithContent(content))
 	defer tempFile.Remove()
 
-	opts := defaultOptions(tempFile.Name())
+	opts := defaultOptions(tempFile.Path())
 	loadedConfig, err := loadDaemonCliConfig(opts)
 	require.NoError(t, err)
 	require.NotNil(t, loadedConfig)
diff --git a/cmd/dockerd/daemon_windows.go b/cmd/dockerd/daemon_windows.go
index 2e9598d..77bade2 100644
--- a/cmd/dockerd/daemon_windows.go
+++ b/cmd/dockerd/daemon_windows.go
@@ -6,20 +6,13 @@
 	"os"
 	"path/filepath"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/libcontainerd"
-	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/windows"
 )
 
 var defaultDaemonConfigFile = ""
 
-// currentUserIsOwner checks whether the current user is the owner of the given
-// file.
-func currentUserIsOwner(f string) bool {
-	return false
-}
-
 // setDefaultUmask doesn't do anything on windows
 func setDefaultUmask() error {
 	return nil
@@ -61,8 +54,8 @@
 		sa := windows.SecurityAttributes{
 			Length: 0,
 		}
-		ev := "Global\\docker-daemon-config-" + fmt.Sprint(os.Getpid())
-		if h, _ := system.CreateEvent(&sa, false, false, ev); h != 0 {
+		ev, _ := windows.UTF16PtrFromString("Global\\docker-daemon-config-" + fmt.Sprint(os.Getpid()))
+		if h, _ := windows.CreateEvent(&sa, 0, 0, ev); h != 0 {
 			logrus.Debugf("Config reload - waiting signal at %s", ev)
 			for {
 				windows.WaitForSingleObject(h, windows.INFINITE)
diff --git a/cmd/dockerd/docker.go b/cmd/dockerd/docker.go
index 8a5c8f5..2ccca46 100644
--- a/cmd/dockerd/docker.go
+++ b/cmd/dockerd/docker.go
@@ -6,12 +6,12 @@
 	"path/filepath"
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/term"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 )
 
diff --git a/cmd/dockerd/metrics.go b/cmd/dockerd/metrics.go
index 0c88604..99d41cb 100644
--- a/cmd/dockerd/metrics.go
+++ b/cmd/dockerd/metrics.go
@@ -4,8 +4,8 @@
 	"net"
 	"net/http"
 
-	"github.com/Sirupsen/logrus"
 	metrics "github.com/docker/go-metrics"
+	"github.com/sirupsen/logrus"
 )
 
 func startMetricsServer(addr string) error {
diff --git a/cmd/dockerd/options.go b/cmd/dockerd/options.go
index 629b022..4fd597d 100644
--- a/cmd/dockerd/options.go
+++ b/cmd/dockerd/options.go
@@ -5,11 +5,11 @@
 	"os"
 	"path/filepath"
 
-	"github.com/Sirupsen/logrus"
 	cliconfig "github.com/docker/docker/cli/config"
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/opts"
 	"github.com/docker/go-connections/tlsconfig"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/pflag"
 )
 
diff --git a/cmd/dockerd/service_windows.go b/cmd/dockerd/service_windows.go
index 0172169..00432af 100644
--- a/cmd/dockerd/service_windows.go
+++ b/cmd/dockerd/service_windows.go
@@ -12,8 +12,8 @@
 	"time"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/pflag"
 	"golang.org/x/sys/windows"
 	"golang.org/x/sys/windows/svc"
diff --git a/container/archive.go b/container/archive.go
index 56e6598..ec4c236 100644
--- a/container/archive.go
+++ b/container/archive.go
@@ -2,7 +2,6 @@
 
 import (
 	"os"
-	"path/filepath"
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/pkg/archive"
@@ -15,17 +14,20 @@
 // an error if the path points to outside the container's rootfs.
 func (container *Container) ResolvePath(path string) (resolvedPath, absPath string, err error) {
 	// Check if a drive letter supplied, it must be the system drive. No-op except on Windows
-	path, err = system.CheckSystemDriveAndRemoveDriveLetter(path)
+	path, err = system.CheckSystemDriveAndRemoveDriveLetter(path, container.BaseFS)
 	if err != nil {
 		return "", "", err
 	}
 
 	// Consider the given path as an absolute path in the container.
-	absPath = archive.PreserveTrailingDotOrSeparator(filepath.Join(string(filepath.Separator), path), path)
+	absPath = archive.PreserveTrailingDotOrSeparator(
+		container.BaseFS.Join(string(container.BaseFS.Separator()), path),
+		path,
+		container.BaseFS.Separator())
 
 	// Split the absPath into its Directory and Base components. We will
 	// resolve the dir in the scope of the container then append the base.
-	dirPath, basePath := filepath.Split(absPath)
+	dirPath, basePath := container.BaseFS.Split(absPath)
 
 	resolvedDirPath, err := container.GetResourcePath(dirPath)
 	if err != nil {
@@ -34,8 +36,7 @@
 
 	// resolvedDirPath will have been cleaned (no trailing path separators) so
 	// we can manually join it with the base path element.
-	resolvedPath = resolvedDirPath + string(filepath.Separator) + basePath
-
+	resolvedPath = resolvedDirPath + string(container.BaseFS.Separator()) + basePath
 	return resolvedPath, absPath, nil
 }
 
@@ -44,7 +45,9 @@
 // resolved to a path on the host corresponding to the given absolute path
 // inside the container.
 func (container *Container) StatPath(resolvedPath, absPath string) (stat *types.ContainerPathStat, err error) {
-	lstat, err := os.Lstat(resolvedPath)
+	driver := container.BaseFS
+
+	lstat, err := driver.Lstat(resolvedPath)
 	if err != nil {
 		return nil, err
 	}
@@ -57,17 +60,17 @@
 			return nil, err
 		}
 
-		linkTarget, err = filepath.Rel(container.BaseFS, hostPath)
+		linkTarget, err = driver.Rel(driver.Path(), hostPath)
 		if err != nil {
 			return nil, err
 		}
 
 		// Make it an absolute path.
-		linkTarget = filepath.Join(string(filepath.Separator), linkTarget)
+		linkTarget = driver.Join(string(driver.Separator()), linkTarget)
 	}
 
 	return &types.ContainerPathStat{
-		Name:       filepath.Base(absPath),
+		Name:       driver.Base(absPath),
 		Size:       lstat.Size(),
 		Mode:       lstat.Mode(),
 		Mtime:      lstat.ModTime(),
diff --git a/container/container.go b/container/container.go
index 86e0111..150910f 100644
--- a/container/container.go
+++ b/container/container.go
@@ -15,7 +15,6 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	containertypes "github.com/docker/docker/api/types/container"
 	mounttypes "github.com/docker/docker/api/types/mount"
 	networktypes "github.com/docker/docker/api/types/network"
@@ -29,6 +28,7 @@
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/opts"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/signal"
@@ -44,6 +44,8 @@
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/types"
 	agentexec "github.com/docker/swarmkit/agent/exec"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -55,18 +57,18 @@
 )
 
 var (
-	errInvalidEndpoint = fmt.Errorf("invalid endpoint while building port map info")
-	errInvalidNetwork  = fmt.Errorf("invalid network settings while building port map info")
+	errInvalidEndpoint = errors.New("invalid endpoint while building port map info")
+	errInvalidNetwork  = errors.New("invalid network settings while building port map info")
 )
 
 // Container holds the structure defining a container object.
 type Container struct {
 	StreamConfig *stream.Config
 	// embed for Container to support states directly.
-	*State          `json:"State"` // Needed for Engine API version <= 1.11
-	Root            string         `json:"-"` // Path to the "home" of the container, including metadata.
-	BaseFS          string         `json:"-"` // Path to the graphdriver mountpoint
-	RWLayer         layer.RWLayer  `json:"-"`
+	*State          `json:"State"`          // Needed for Engine API version <= 1.11
+	Root            string                  `json:"-"` // Path to the "home" of the container, including metadata.
+	BaseFS          containerfs.ContainerFS `json:"-"` // interface containing graphdriver mount
+	RWLayer         layer.RWLayer           `json:"-"`
 	ID              string
 	Created         time.Time
 	Managed         bool
@@ -167,7 +169,7 @@
 	}
 
 	// Save container settings
-	f, err := ioutils.NewAtomicFileWriter(pth, 0644)
+	f, err := ioutils.NewAtomicFileWriter(pth, 0600)
 	if err != nil {
 		return nil, err
 	}
@@ -260,12 +262,17 @@
 
 // SetupWorkingDirectory sets up the container's working directory as set in container.Config.WorkingDir
 func (container *Container) SetupWorkingDirectory(rootIDs idtools.IDPair) error {
+	// TODO @jhowardmsft, @gupta-ak LCOW Support. This will need revisiting.
+	// We will need to do remote filesystem operations here.
+	if container.Platform != runtime.GOOS {
+		return nil
+	}
+
 	if container.Config.WorkingDir == "" {
 		return nil
 	}
 
 	container.Config.WorkingDir = filepath.Clean(container.Config.WorkingDir)
-
 	pth, err := container.GetResourcePath(container.Config.WorkingDir)
 	if err != nil {
 		return err
@@ -274,7 +281,7 @@
 	if err := idtools.MkdirAllAndChownNew(pth, 0755, rootIDs); err != nil {
 		pthInfo, err2 := os.Stat(pth)
 		if err2 == nil && pthInfo != nil && !pthInfo.IsDir() {
-			return fmt.Errorf("Cannot mkdir: %s is not a directory", container.Config.WorkingDir)
+			return errors.Errorf("Cannot mkdir: %s is not a directory", container.Config.WorkingDir)
 		}
 
 		return err
@@ -299,15 +306,13 @@
 func (container *Container) GetResourcePath(path string) (string, error) {
 	// IMPORTANT - These are paths on the OS where the daemon is running, hence
 	// any filepath operations must be done in an OS agnostic way.
-
-	cleanPath := cleanResourcePath(path)
-	r, e := symlink.FollowSymlinkInScope(filepath.Join(container.BaseFS, cleanPath), container.BaseFS)
+	r, e := container.BaseFS.ResolveScopedPath(path, false)
 
 	// Log this here on the daemon side as there's otherwise no indication apart
 	// from the error being propagated all the way back to the client. This makes
 	// debugging significantly easier and clearly indicates the error comes from the daemon.
 	if e != nil {
-		logrus.Errorf("Failed to FollowSymlinkInScope BaseFS %s cleanPath %s path %s %s\n", container.BaseFS, cleanPath, path, e)
+		logrus.Errorf("Failed to ResolveScopedPath BaseFS %s path %s %s\n", container.BaseFS.Path(), path, e)
 	}
 	return r, e
 }
@@ -357,7 +362,7 @@
 	cfg := container.HostConfig.LogConfig
 	initDriver, err := logger.GetLogDriver(cfg.Type)
 	if err != nil {
-		return nil, fmt.Errorf("failed to get logging factory: %v", err)
+		return nil, errors.Wrap(err, "failed to get logging factory")
 	}
 	info := logger.Info{
 		Config:              cfg.Config,
@@ -429,6 +434,11 @@
 
 // AddMountPointWithVolume adds a new mount point configured with a volume to the container.
 func (container *Container) AddMountPointWithVolume(destination string, vol volume.Volume, rw bool) {
+	operatingSystem := container.Platform
+	if operatingSystem == "" {
+		operatingSystem = runtime.GOOS
+	}
+	volumeParser := volume.NewParser(operatingSystem)
 	container.MountPoints[destination] = &volume.MountPoint{
 		Type:        mounttypes.TypeVolume,
 		Name:        vol.Name(),
@@ -436,7 +446,7 @@
 		Destination: destination,
 		RW:          rw,
 		Volume:      vol,
-		CopyData:    volume.DefaultCopyMode,
+		CopyData:    volumeParser.DefaultCopyMode(),
 	}
 }
 
@@ -649,8 +659,12 @@
 	return nil
 }
 
+type named interface {
+	Name() string
+}
+
 // UpdateJoinInfo updates network settings when container joins network n with endpoint ep.
-func (container *Container) UpdateJoinInfo(n libnetwork.Network, ep libnetwork.Endpoint) error {
+func (container *Container) UpdateJoinInfo(n named, ep libnetwork.Endpoint) error {
 	if err := container.buildPortMapInfo(ep); err != nil {
 		return err
 	}
@@ -678,7 +692,7 @@
 }
 
 // BuildJoinOptions builds endpoint Join options from a given network.
-func (container *Container) BuildJoinOptions(n libnetwork.Network) ([]libnetwork.EndpointOption, error) {
+func (container *Container) BuildJoinOptions(n named) ([]libnetwork.EndpointOption, error) {
 	var joinOptions []libnetwork.EndpointOption
 	if epConfig, ok := container.NetworkSettings.Networks[n.Name()]; ok {
 		for _, str := range epConfig.Links {
@@ -723,18 +737,18 @@
 
 			for _, ips := range ipam.LinkLocalIPs {
 				if linkip = net.ParseIP(ips); linkip == nil && ips != "" {
-					return nil, fmt.Errorf("Invalid link-local IP address:%s", ipam.LinkLocalIPs)
+					return nil, errors.Errorf("Invalid link-local IP address: %s", ipam.LinkLocalIPs)
 				}
 				ipList = append(ipList, linkip)
 
 			}
 
 			if ip = net.ParseIP(ipam.IPv4Address); ip == nil && ipam.IPv4Address != "" {
-				return nil, fmt.Errorf("Invalid IPv4 address:%s)", ipam.IPv4Address)
+				return nil, errors.Errorf("Invalid IPv4 address: %s)", ipam.IPv4Address)
 			}
 
 			if ip6 = net.ParseIP(ipam.IPv6Address); ip6 == nil && ipam.IPv6Address != "" {
-				return nil, fmt.Errorf("Invalid IPv6 address:%s)", ipam.IPv6Address)
+				return nil, errors.Errorf("Invalid IPv6 address: %s)", ipam.IPv6Address)
 			}
 
 			createOptions = append(createOptions,
@@ -838,7 +852,7 @@
 				portStart, portEnd, err = newP.Range()
 			}
 			if err != nil {
-				return nil, fmt.Errorf("Error parsing HostPort value(%s):%v", binding[i].HostPort, err)
+				return nil, errors.Wrapf(err, "Error parsing HostPort value (%s)", binding[i].HostPort)
 			}
 			pbCopy.HostPort = uint16(portStart)
 			pbCopy.HostPortEnd = uint16(portEnd)
diff --git a/container/container_unix.go b/container/container_unix.go
index 327f950..6bb253f 100644
--- a/container/container_unix.go
+++ b/container/container_unix.go
@@ -3,23 +3,20 @@
 package container
 
 import (
-	"fmt"
 	"io/ioutil"
 	"os"
-	"path/filepath"
-	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	mounttypes "github.com/docker/docker/api/types/mount"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/volume"
 	"github.com/opencontainers/selinux/go-selinux/label"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
@@ -69,6 +66,7 @@
 func (container *Container) NetworkMounts() []Mount {
 	var mounts []Mount
 	shared := container.HostConfig.NetworkMode.IsContainer()
+	parser := volume.NewParser(container.Platform)
 	if container.ResolvConfPath != "" {
 		if _, err := os.Stat(container.ResolvConfPath); err != nil {
 			logrus.Warnf("ResolvConfPath set to %q, but can't stat this filename (err = %v); skipping", container.ResolvConfPath, err)
@@ -84,7 +82,7 @@
 				Source:      container.ResolvConfPath,
 				Destination: "/etc/resolv.conf",
 				Writable:    writable,
-				Propagation: string(volume.DefaultPropagationMode),
+				Propagation: string(parser.DefaultPropagationMode()),
 			})
 		}
 	}
@@ -103,7 +101,7 @@
 				Source:      container.HostnamePath,
 				Destination: "/etc/hostname",
 				Writable:    writable,
-				Propagation: string(volume.DefaultPropagationMode),
+				Propagation: string(parser.DefaultPropagationMode()),
 			})
 		}
 	}
@@ -122,7 +120,7 @@
 				Source:      container.HostsPath,
 				Destination: "/etc/hosts",
 				Writable:    writable,
-				Propagation: string(volume.DefaultPropagationMode),
+				Propagation: string(parser.DefaultPropagationMode()),
 			})
 		}
 	}
@@ -131,7 +129,7 @@
 
 // CopyImagePathContent copies files in destination to the volume.
 func (container *Container) CopyImagePathContent(v volume.Volume, destination string) error {
-	rootfs, err := symlink.FollowSymlinkInScope(filepath.Join(container.BaseFS, destination), container.BaseFS)
+	rootfs, err := container.GetResourcePath(destination)
 	if err != nil {
 		return err
 	}
@@ -171,47 +169,48 @@
 	return exists
 }
 
-// UnmountIpcMounts uses the provided unmount function to unmount shm and mqueue if they were mounted
-func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
-	if container.HostConfig.IpcMode.IsContainer() || container.HostConfig.IpcMode.IsHost() {
-		return
+// UnmountIpcMount uses the provided unmount function to unmount shm if it was mounted
+func (container *Container) UnmountIpcMount(unmount func(pth string) error) error {
+	if container.HasMountFor("/dev/shm") {
+		return nil
 	}
 
-	var warnings []string
-
-	if !container.HasMountFor("/dev/shm") {
-		shmPath, err := container.ShmResourcePath()
-		if err != nil {
-			logrus.Error(err)
-			warnings = append(warnings, err.Error())
-		} else if shmPath != "" {
-			if err := unmount(shmPath); err != nil && !os.IsNotExist(err) {
-				if mounted, mErr := mount.Mounted(shmPath); mounted || mErr != nil {
-					warnings = append(warnings, fmt.Sprintf("failed to umount %s: %v", shmPath, err))
-				}
-			}
-
+	// container.ShmPath should not be used here as it may point
+	// to the host's or other container's /dev/shm
+	shmPath, err := container.ShmResourcePath()
+	if err != nil {
+		return err
+	}
+	if shmPath == "" {
+		return nil
+	}
+	if err = unmount(shmPath); err != nil && !os.IsNotExist(err) {
+		if mounted, mErr := mount.Mounted(shmPath); mounted || mErr != nil {
+			return errors.Wrapf(err, "umount %s", shmPath)
 		}
 	}
-
-	if len(warnings) > 0 {
-		logrus.Warnf("failed to cleanup ipc mounts:\n%v", strings.Join(warnings, "\n"))
-	}
+	return nil
 }
 
 // IpcMounts returns the list of IPC mounts
 func (container *Container) IpcMounts() []Mount {
 	var mounts []Mount
+	parser := volume.NewParser(container.Platform)
 
-	if !container.HasMountFor("/dev/shm") {
-		label.SetFileLabel(container.ShmPath, container.MountLabel)
-		mounts = append(mounts, Mount{
-			Source:      container.ShmPath,
-			Destination: "/dev/shm",
-			Writable:    true,
-			Propagation: string(volume.DefaultPropagationMode),
-		})
+	if container.HasMountFor("/dev/shm") {
+		return mounts
 	}
+	if container.ShmPath == "" {
+		return mounts
+	}
+
+	label.SetFileLabel(container.ShmPath, container.MountLabel)
+	mounts = append(mounts, Mount{
+		Source:      container.ShmPath,
+		Destination: "/dev/shm",
+		Writable:    true,
+		Propagation: string(parser.DefaultPropagationMode()),
+	})
 
 	return mounts
 }
@@ -262,6 +261,14 @@
 	return mounts
 }
 
+type conflictingUpdateOptions string
+
+func (e conflictingUpdateOptions) Error() string {
+	return string(e)
+}
+
+func (e conflictingUpdateOptions) Conflict() {}
+
 // UpdateContainer updates configuration of a container. Callers must hold a Lock on the Container.
 func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfig) error {
 	// update resources of container
@@ -273,16 +280,16 @@
 	// once NanoCPU is already set, updating CPUPeriod/CPUQuota will be blocked, and vice versa.
 	// In the following we make sure the intended update (resources) does not conflict with the existing (cResource).
 	if resources.NanoCPUs > 0 && cResources.CPUPeriod > 0 {
-		return fmt.Errorf("Conflicting options: Nano CPUs cannot be updated as CPU Period has already been set")
+		return conflictingUpdateOptions("Conflicting options: Nano CPUs cannot be updated as CPU Period has already been set")
 	}
 	if resources.NanoCPUs > 0 && cResources.CPUQuota > 0 {
-		return fmt.Errorf("Conflicting options: Nano CPUs cannot be updated as CPU Quota has already been set")
+		return conflictingUpdateOptions("Conflicting options: Nano CPUs cannot be updated as CPU Quota has already been set")
 	}
 	if resources.CPUPeriod > 0 && cResources.NanoCPUs > 0 {
-		return fmt.Errorf("Conflicting options: CPU Period cannot be updated as NanoCPUs has already been set")
+		return conflictingUpdateOptions("Conflicting options: CPU Period cannot be updated as NanoCPUs has already been set")
 	}
 	if resources.CPUQuota > 0 && cResources.NanoCPUs > 0 {
-		return fmt.Errorf("Conflicting options: CPU Quota cannot be updated as NanoCPUs has already been set")
+		return conflictingUpdateOptions("Conflicting options: CPU Quota cannot be updated as NanoCPUs has already been set")
 	}
 
 	if resources.BlkioWeight != 0 {
@@ -310,7 +317,7 @@
 		// if memory limit smaller than already set memoryswap limit and doesn't
 		// update the memoryswap limit, then error out.
 		if resources.Memory > cResources.MemorySwap && resources.MemorySwap == 0 {
-			return fmt.Errorf("Memory limit should be smaller than already set memoryswap limit, update the memoryswap at the same time")
+			return conflictingUpdateOptions("Memory limit should be smaller than already set memoryswap limit, update the memoryswap at the same time")
 		}
 		cResources.Memory = resources.Memory
 	}
@@ -327,7 +334,7 @@
 	// update HostConfig of container
 	if hostConfig.RestartPolicy.Name != "" {
 		if container.HostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
-			return fmt.Errorf("Restart policy cannot be updated because AutoRemove is enabled for the container")
+			return conflictingUpdateOptions("Restart policy cannot be updated because AutoRemove is enabled for the container")
 		}
 		container.HostConfig.RestartPolicy = hostConfig.RestartPolicy
 	}
@@ -422,6 +429,7 @@
 
 // TmpfsMounts returns the list of tmpfs mounts
 func (container *Container) TmpfsMounts() ([]Mount, error) {
+	parser := volume.NewParser(container.Platform)
 	var mounts []Mount
 	for dest, data := range container.HostConfig.Tmpfs {
 		mounts = append(mounts, Mount{
@@ -432,7 +440,7 @@
 	}
 	for dest, mnt := range container.MountPoints {
 		if mnt.Type == mounttypes.TypeTmpfs {
-			data, err := volume.ConvertTmpfsOptions(mnt.Spec.TmpfsOptions, mnt.Spec.ReadOnly)
+			data, err := parser.ConvertTmpfsOptions(mnt.Spec.TmpfsOptions, mnt.Spec.ReadOnly)
 			if err != nil {
 				return nil, err
 			}
@@ -446,11 +454,6 @@
 	return mounts, nil
 }
 
-// cleanResourcePath cleans a resource path and prepares to combine with mnt path
-func cleanResourcePath(path string) string {
-	return filepath.Join(string(os.PathSeparator), path)
-}
-
 // EnableServiceDiscoveryOnDefaultNetwork Enable service discovery on default network
 func (container *Container) EnableServiceDiscoveryOnDefaultNetwork() bool {
 	return false
diff --git a/container/container_windows.go b/container/container_windows.go
index 0f2a45d..2dbea59 100644
--- a/container/container_windows.go
+++ b/container/container_windows.go
@@ -24,9 +24,10 @@
 	ExitCode int
 }
 
-// UnmountIpcMounts unmounts Ipc related mounts.
+// UnmountIpcMount unmounts Ipc related mounts.
 // This is a NOOP on windows.
-func (container *Container) UnmountIpcMounts(unmount func(pth string) error) {
+func (container *Container) UnmountIpcMount(unmount func(pth string) error) error {
+	return nil
 }
 
 // IpcMounts returns the list of Ipc related mounts.
@@ -171,18 +172,6 @@
 	return nil
 }
 
-// cleanResourcePath cleans a resource path by removing C:\ syntax, and prepares
-// to combine with a volume path
-func cleanResourcePath(path string) string {
-	if len(path) >= 2 {
-		c := path[0]
-		if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
-			path = path[2:]
-		}
-	}
-	return filepath.Join(string(os.PathSeparator), path)
-}
-
 // BuildHostnameFile writes the container's hostname file.
 func (container *Container) BuildHostnameFile() error {
 	return nil
diff --git a/container/health.go b/container/health.go
index 31c5600..5919008 100644
--- a/container/health.go
+++ b/container/health.go
@@ -1,8 +1,8 @@
 package container
 
 import (
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
+	"github.com/sirupsen/logrus"
 )
 
 // Health holds the current container health-check state
diff --git a/container/monitor.go b/container/monitor.go
index f05e72b..f35097b 100644
--- a/container/monitor.go
+++ b/container/monitor.go
@@ -3,7 +3,7 @@
 import (
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/container/state.go b/container/state.go
index 32f3f5b..cdf51d3 100644
--- a/container/state.go
+++ b/container/state.go
@@ -357,6 +357,15 @@
 	s.Unlock()
 }
 
+// IsRemovalInProgress returns whether the RemovalInProgress flag is set.
+// Used by Container to check whether a container is being removed.
+func (s *State) IsRemovalInProgress() bool {
+	s.Lock()
+	res := s.RemovalInProgress
+	s.Unlock()
+	return res
+}
+
 // SetDead sets the container state to "dead"
 func (s *State) SetDead() {
 	s.Lock()
@@ -364,6 +373,14 @@
 	s.Unlock()
 }
 
+// IsDead returns whether the Dead flag is set. Used by Container to check whether a container is dead.
+func (s *State) IsDead() bool {
+	s.Lock()
+	res := s.Dead
+	s.Unlock()
+	return res
+}
+
 // SetRemoved assumes this container is already in the "dead" state and
 // closes the internal waitRemove channel to unblock callers waiting for a
 // container to be removed.
diff --git a/container/stream/attach.go b/container/stream/attach.go
index 3dd53d3..4b4a454 100644
--- a/container/stream/attach.go
+++ b/container/stream/attach.go
@@ -6,10 +6,9 @@
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/pools"
-	"github.com/docker/docker/pkg/promise"
 	"github.com/docker/docker/pkg/term"
+	"github.com/sirupsen/logrus"
 )
 
 var defaultEscapeSequence = []byte{16, 17} // ctrl-p, ctrl-q
@@ -58,7 +57,7 @@
 }
 
 // CopyStreams starts goroutines to copy data in and out to/from the container
-func (c *Config) CopyStreams(ctx context.Context, cfg *AttachConfig) chan error {
+func (c *Config) CopyStreams(ctx context.Context, cfg *AttachConfig) <-chan error {
 	var (
 		wg     sync.WaitGroup
 		errors = make(chan error, 3)
@@ -137,35 +136,42 @@
 	go attachStream("stdout", cfg.Stdout, cfg.CStdout)
 	go attachStream("stderr", cfg.Stderr, cfg.CStderr)
 
-	return promise.Go(func() error {
-		done := make(chan struct{})
-		go func() {
-			wg.Wait()
-			close(done)
+	errs := make(chan error, 1)
+
+	go func() {
+		defer close(errs)
+		errs <- func() error {
+			done := make(chan struct{})
+			go func() {
+				wg.Wait()
+				close(done)
+			}()
+			select {
+			case <-done:
+			case <-ctx.Done():
+				// close all pipes
+				if cfg.CStdin != nil {
+					cfg.CStdin.Close()
+				}
+				if cfg.CStdout != nil {
+					cfg.CStdout.Close()
+				}
+				if cfg.CStderr != nil {
+					cfg.CStderr.Close()
+				}
+				<-done
+			}
+			close(errors)
+			for err := range errors {
+				if err != nil {
+					return err
+				}
+			}
+			return nil
 		}()
-		select {
-		case <-done:
-		case <-ctx.Done():
-			// close all pipes
-			if cfg.CStdin != nil {
-				cfg.CStdin.Close()
-			}
-			if cfg.CStdout != nil {
-				cfg.CStdout.Close()
-			}
-			if cfg.CStderr != nil {
-				cfg.CStderr.Close()
-			}
-			<-done
-		}
-		close(errors)
-		for err := range errors {
-			if err != nil {
-				return err
-			}
-		}
-		return nil
-	})
+	}()
+
+	return errs
 }
 
 func copyEscapable(dst io.Writer, src io.ReadCloser, keys []byte) (written int64, err error) {
diff --git a/container/stream/streams.go b/container/stream/streams.go
index 735bab5..7e734d8 100644
--- a/container/stream/streams.go
+++ b/container/stream/streams.go
@@ -7,11 +7,11 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/pkg/broadcaster"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/pools"
+	"github.com/sirupsen/logrus"
 )
 
 // Config holds information about I/O streams managed together.
diff --git a/container/view.go b/container/view.go
index 4b6c702..164827c 100644
--- a/container/view.go
+++ b/container/view.go
@@ -6,11 +6,11 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/network"
 	"github.com/docker/go-connections/nat"
 	"github.com/hashicorp/go-memdb"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -203,10 +203,7 @@
 // Once released, a name can be reserved again
 func (db *memDB) ReleaseName(name string) error {
 	return db.withTxn(func(txn *memdb.Txn) error {
-		if err := txn.Delete(memdbNamesTable, nameAssociation{name: name}); err != nil {
-			return err
-		}
-		return nil
+		return txn.Delete(memdbNamesTable, nameAssociation{name: name})
 	})
 }
 
diff --git a/contrib/docker-device-tool/device_tool.go b/contrib/docker-device-tool/device_tool.go
index fc17166..905b689 100644
--- a/contrib/docker-device-tool/device_tool.go
+++ b/contrib/docker-device-tool/device_tool.go
@@ -11,9 +11,9 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver/devmapper"
 	"github.com/docker/docker/pkg/devicemapper"
+	"github.com/sirupsen/logrus"
 )
 
 func usage() {
@@ -90,14 +90,12 @@
 		fmt.Printf("Sector size: %d\n", status.SectorSize)
 		fmt.Printf("Data use: %d of %d (%.1f %%)\n", status.Data.Used, status.Data.Total, 100.0*float64(status.Data.Used)/float64(status.Data.Total))
 		fmt.Printf("Metadata use: %d of %d (%.1f %%)\n", status.Metadata.Used, status.Metadata.Total, 100.0*float64(status.Metadata.Used)/float64(status.Metadata.Total))
-		break
 	case "list":
 		ids := devices.List()
 		sort.Strings(ids)
 		for _, id := range ids {
 			fmt.Println(id)
 		}
-		break
 	case "device":
 		if flag.NArg() < 2 {
 			usage()
@@ -113,7 +111,6 @@
 		fmt.Printf("Size in Sectors: %d\n", status.SizeInSectors)
 		fmt.Printf("Mapped Sectors: %d\n", status.MappedSectors)
 		fmt.Printf("Highest Mapped Sector: %d\n", status.HighestMappedSector)
-		break
 	case "resize":
 		if flag.NArg() < 2 {
 			usage()
@@ -131,7 +128,6 @@
 			os.Exit(1)
 		}
 
-		break
 	case "snap":
 		if flag.NArg() < 3 {
 			usage()
@@ -142,7 +138,6 @@
 			fmt.Println("Can't create snap device: ", err)
 			os.Exit(1)
 		}
-		break
 	case "remove":
 		if flag.NArg() < 2 {
 			usage()
@@ -153,7 +148,6 @@
 			fmt.Println("Can't remove device: ", err)
 			os.Exit(1)
 		}
-		break
 	case "mount":
 		if flag.NArg() < 3 {
 			usage()
@@ -164,13 +158,10 @@
 			fmt.Println("Can't mount device: ", err)
 			os.Exit(1)
 		}
-		break
 	default:
 		fmt.Printf("Unknown command %s\n", args[0])
 		usage()
 
 		os.Exit(1)
 	}
-
-	return
 }
diff --git a/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage b/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage
index 5a27333..a4a7b7a 100644
--- a/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage
+++ b/contrib/syntax/textmate/Docker.tmbundle/Syntaxes/Dockerfile.tmLanguage
@@ -25,7 +25,7 @@
 				</dict>
 			</dict>
 			<key>match</key>
-			<string>^\s*\b(FROM)\b.*?\b(AS)\b</string>
+			<string>^\s*\b(?i:(FROM))\b.*?\b(?i:(AS))\b</string>
 		</dict>
 		<dict>
 			<key>captures</key>
@@ -42,7 +42,7 @@
 				</dict>
 			</dict>
 			<key>match</key>
-			<string>^\s*(?:(ONBUILD)\s+)?(ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR)\s</string>
+			<string>^\s*(?i:(ONBUILD)\s+)?(?i:(ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR))\s</string>
 		</dict>
 		<dict>
 			<key>captures</key>
@@ -59,7 +59,7 @@
 				</dict>
 			</dict>
 			<key>match</key>
-			<string>^\s*(?:(ONBUILD)\s+)?(CMD|ENTRYPOINT)\s</string>
+			<string>^\s*(?i:(ONBUILD)\s+)?(?i:(CMD|ENTRYPOINT))\s</string>
 		</dict>
 		<dict>
 			<key>begin</key>
diff --git a/daemon/archive.go b/daemon/archive.go
index bd00dac..c52d3b8 100644
--- a/daemon/archive.go
+++ b/daemon/archive.go
@@ -3,7 +3,6 @@
 import (
 	"io"
 	"os"
-	"path/filepath"
 	"strings"
 
 	"github.com/docker/docker/api/types"
@@ -20,6 +19,31 @@
 // path does not refer to a directory.
 var ErrExtractPointNotDirectory = errors.New("extraction point is not a directory")
 
+// The daemon will use the following interfaces if the container fs implements
+// these for optimized copies to and from the container.
+type extractor interface {
+	ExtractArchive(src io.Reader, dst string, opts *archive.TarOptions) error
+}
+
+type archiver interface {
+	ArchivePath(src string, opts *archive.TarOptions) (io.ReadCloser, error)
+}
+
+// helper functions to extract or archive
+func extractArchive(i interface{}, src io.Reader, dst string, opts *archive.TarOptions) error {
+	if ea, ok := i.(extractor); ok {
+		return ea.ExtractArchive(src, dst, opts)
+	}
+	return chrootarchive.Untar(src, dst, opts)
+}
+
+func archivePath(i interface{}, src string, opts *archive.TarOptions) (io.ReadCloser, error) {
+	if ap, ok := i.(archiver); ok {
+		return ap.ArchivePath(src, opts)
+	}
+	return archive.TarWithOptions(src, opts)
+}
+
 // ContainerCopy performs a deprecated operation of archiving the resource at
 // the specified path in the container identified by the given name.
 func (daemon *Daemon) ContainerCopy(name string, res string) (io.ReadCloser, error) {
@@ -28,16 +52,20 @@
 		return nil, err
 	}
 
-	if res[0] == '/' || res[0] == '\\' {
-		res = res[1:]
-	}
-
 	// Make sure an online file-system operation is permitted.
 	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
-		return nil, err
+		return nil, systemError{err}
 	}
 
-	return daemon.containerCopy(container, res)
+	data, err := daemon.containerCopy(container, res)
+	if err == nil {
+		return data, nil
+	}
+
+	if os.IsNotExist(err) {
+		return nil, containerFileNotFound{res, name}
+	}
+	return nil, systemError{err}
 }
 
 // ContainerStatPath stats the filesystem resource at the specified path in the
@@ -50,10 +78,18 @@
 
 	// Make sure an online file-system operation is permitted.
 	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
-		return nil, err
+		return nil, systemError{err}
 	}
 
-	return daemon.containerStatPath(container, path)
+	stat, err = daemon.containerStatPath(container, path)
+	if err == nil {
+		return stat, nil
+	}
+
+	if os.IsNotExist(err) {
+		return nil, containerFileNotFound{path, name}
+	}
+	return nil, systemError{err}
 }
 
 // ContainerArchivePath creates an archive of the filesystem resource at the
@@ -67,10 +103,18 @@
 
 	// Make sure an online file-system operation is permitted.
 	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
-		return nil, nil, err
+		return nil, nil, systemError{err}
 	}
 
-	return daemon.containerArchivePath(container, path)
+	content, stat, err = daemon.containerArchivePath(container, path)
+	if err == nil {
+		return content, stat, nil
+	}
+
+	if os.IsNotExist(err) {
+		return nil, nil, containerFileNotFound{path, name}
+	}
+	return nil, nil, systemError{err}
 }
 
 // ContainerExtractToDir extracts the given archive to the specified location
@@ -87,10 +131,18 @@
 
 	// Make sure an online file-system operation is permitted.
 	if err := daemon.isOnlineFSOperationPermitted(container); err != nil {
-		return err
+		return systemError{err}
 	}
 
-	return daemon.containerExtractToDir(container, path, copyUIDGID, noOverwriteDirNonDir, content)
+	err = daemon.containerExtractToDir(container, path, copyUIDGID, noOverwriteDirNonDir, content)
+	if err == nil {
+		return nil
+	}
+
+	if os.IsNotExist(err) {
+		return containerFileNotFound{path, name}
+	}
+	return systemError{err}
 }
 
 // containerStatPath stats the filesystem resource at the specified path in this
@@ -110,6 +162,9 @@
 		return nil, err
 	}
 
+	// Normalize path before sending to rootfs
+	path = container.BaseFS.FromSlash(path)
+
 	resolvedPath, absPath, err := container.ResolvePath(path)
 	if err != nil {
 		return nil, err
@@ -150,6 +205,9 @@
 		return nil, nil, err
 	}
 
+	// Normalize path before sending to rootfs
+	path = container.BaseFS.FromSlash(path)
+
 	resolvedPath, absPath, err := container.ResolvePath(path)
 	if err != nil {
 		return nil, nil, err
@@ -168,7 +226,18 @@
 	// also catches the case when the root directory of the container is
 	// requested: we want the archive entries to start with "/" and not the
 	// container ID.
-	data, err := archive.TarResourceRebase(resolvedPath, filepath.Base(absPath))
+	driver := container.BaseFS
+
+	// Get the source and the base paths of the container resolved path in order
+	// to get the proper tar options for the rebase tar.
+	resolvedPath = driver.Clean(resolvedPath)
+	if driver.Base(resolvedPath) == "." {
+		resolvedPath += string(driver.Separator()) + "."
+	}
+	sourceDir, sourceBase := driver.Dir(resolvedPath), driver.Base(resolvedPath)
+	opts := archive.TarResourceRebaseOpts(sourceBase, driver.Base(absPath))
+
+	data, err := archivePath(driver, sourceDir, opts)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -207,8 +276,12 @@
 		return err
 	}
 
+	// Normalize path before sending to rootfs'
+	path = container.BaseFS.FromSlash(path)
+	driver := container.BaseFS
+
 	// Check if a drive letter supplied, it must be the system drive. No-op except on Windows
-	path, err = system.CheckSystemDriveAndRemoveDriveLetter(path)
+	path, err = system.CheckSystemDriveAndRemoveDriveLetter(path, driver)
 	if err != nil {
 		return err
 	}
@@ -220,7 +293,10 @@
 	// that you can extract an archive to a symlink that points to a directory.
 
 	// Consider the given path as an absolute path in the container.
-	absPath := archive.PreserveTrailingDotOrSeparator(filepath.Join(string(filepath.Separator), path), path)
+	absPath := archive.PreserveTrailingDotOrSeparator(
+		driver.Join(string(driver.Separator()), path),
+		path,
+		driver.Separator())
 
 	// This will evaluate the last path element if it is a symlink.
 	resolvedPath, err := container.GetResourcePath(absPath)
@@ -228,7 +304,7 @@
 		return err
 	}
 
-	stat, err := os.Lstat(resolvedPath)
+	stat, err := driver.Lstat(resolvedPath)
 	if err != nil {
 		return err
 	}
@@ -251,21 +327,24 @@
 	// a volume file path.
 	var baseRel string
 	if strings.HasPrefix(resolvedPath, `\\?\Volume{`) {
-		if strings.HasPrefix(resolvedPath, container.BaseFS) {
-			baseRel = resolvedPath[len(container.BaseFS):]
+		if strings.HasPrefix(resolvedPath, driver.Path()) {
+			baseRel = resolvedPath[len(driver.Path()):]
 			if baseRel[:1] == `\` {
 				baseRel = baseRel[1:]
 			}
 		}
 	} else {
-		baseRel, err = filepath.Rel(container.BaseFS, resolvedPath)
+		baseRel, err = driver.Rel(driver.Path(), resolvedPath)
 	}
 	if err != nil {
 		return err
 	}
 	// Make it an absolute path.
-	absPath = filepath.Join(string(filepath.Separator), baseRel)
+	absPath = driver.Join(string(driver.Separator()), baseRel)
 
+	// @ TODO: gupta-ak: Technically, this works since it no-ops
+	// on Windows and the file system is local anyway on linux.
+	// But eventually, it should be made driver aware.
 	toVolume, err := checkIfPathIsInAVolume(container, absPath)
 	if err != nil {
 		return err
@@ -287,7 +366,7 @@
 		}
 	}
 
-	if err := chrootarchive.Untar(content, resolvedPath, options); err != nil {
+	if err := extractArchive(driver, content, resolvedPath, options); err != nil {
 		return err
 	}
 
@@ -297,6 +376,9 @@
 }
 
 func (daemon *Daemon) containerCopy(container *container.Container, resource string) (rc io.ReadCloser, err error) {
+	if resource[0] == '/' || resource[0] == '\\' {
+		resource = resource[1:]
+	}
 	container.Lock()
 
 	defer func() {
@@ -325,24 +407,28 @@
 		return nil, err
 	}
 
+	// Normalize path before sending to rootfs
+	resource = container.BaseFS.FromSlash(resource)
+	driver := container.BaseFS
+
 	basePath, err := container.GetResourcePath(resource)
 	if err != nil {
 		return nil, err
 	}
-	stat, err := os.Stat(basePath)
+	stat, err := driver.Stat(basePath)
 	if err != nil {
 		return nil, err
 	}
 	var filter []string
 	if !stat.IsDir() {
-		d, f := filepath.Split(basePath)
+		d, f := driver.Split(basePath)
 		basePath = d
 		filter = []string{f}
 	} else {
-		filter = []string{filepath.Base(basePath)}
-		basePath = filepath.Dir(basePath)
+		filter = []string{driver.Base(basePath)}
+		basePath = driver.Dir(basePath)
 	}
-	archive, err := archive.TarWithOptions(basePath, &archive.TarOptions{
+	archive, err := archivePath(driver, basePath, &archive.TarOptions{
 		Compression:  archive.Uncompressed,
 		IncludeFiles: filter,
 	})
diff --git a/daemon/archive_unix.go b/daemon/archive_unix.go
index d5dfad7..e2d4c30 100644
--- a/daemon/archive_unix.go
+++ b/daemon/archive_unix.go
@@ -4,6 +4,7 @@
 
 import (
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/volume"
 )
 
 // checkIfPathIsInAVolume checks if the path is in a volume. If it is, it
@@ -11,8 +12,9 @@
 // cannot be configured with a read-only rootfs.
 func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) {
 	var toVolume bool
+	parser := volume.NewParser(container.Platform)
 	for _, mnt := range container.MountPoints {
-		if toVolume = mnt.HasResource(absPath); toVolume {
+		if toVolume = parser.HasResource(mnt, absPath); toVolume {
 			if mnt.RW {
 				break
 			}
diff --git a/daemon/attach.go b/daemon/attach.go
index 3241039..651a964 100644
--- a/daemon/attach.go
+++ b/daemon/attach.go
@@ -5,14 +5,14 @@
 	"fmt"
 	"io"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container/stream"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/pkg/stdcopy"
 	"github.com/docker/docker/pkg/term"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerAttach attaches to logs according to the config passed in. See ContainerAttachConfig.
@@ -22,7 +22,7 @@
 	if c.DetachKeys != "" {
 		keys, err = term.ToBytes(c.DetachKeys)
 		if err != nil {
-			return fmt.Errorf("Invalid detach keys (%s) provided", c.DetachKeys)
+			return validationError{errors.Errorf("Invalid detach keys (%s) provided", c.DetachKeys)}
 		}
 	}
 
@@ -31,12 +31,12 @@
 		return err
 	}
 	if container.IsPaused() {
-		err := fmt.Errorf("Container %s is paused, unpause the container before attach.", prefixOrName)
-		return errors.NewRequestConflictError(err)
+		err := fmt.Errorf("container %s is paused, unpause the container before attach", prefixOrName)
+		return stateConflictError{err}
 	}
 	if container.IsRestarting() {
-		err := fmt.Errorf("Container %s is restarting, wait until the container is running.", prefixOrName)
-		return errors.NewRequestConflictError(err)
+		err := fmt.Errorf("container %s is restarting, wait until the container is running", prefixOrName)
+		return stateConflictError{err}
 	}
 
 	cfg := stream.AttachConfig{
@@ -119,7 +119,7 @@
 		}
 		cLog, ok := logDriver.(logger.LogReader)
 		if !ok {
-			return logger.ErrReadLogsNotSupported
+			return logger.ErrReadLogsNotSupported{}
 		}
 		logs := cLog.ReadLogs(logger.ReadConfig{Tail: -1})
 		defer logs.Close()
@@ -168,7 +168,7 @@
 		// Wait for the container to stop before returning.
 		waitChan := c.Wait(context.Background(), container.WaitConditionNotRunning)
 		defer func() {
-			_ = <-waitChan // Ignore returned exit code.
+			<-waitChan // Ignore returned exit code.
 		}()
 	}
 
diff --git a/daemon/build.go b/daemon/build.go
index 14767e5..be34406 100644
--- a/daemon/build.go
+++ b/daemon/build.go
@@ -4,17 +4,18 @@
 	"io"
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/registry"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -25,9 +26,9 @@
 	rwLayer    layer.RWLayer
 }
 
-func (rl *releaseableLayer) Mount() (string, error) {
+func (rl *releaseableLayer) Mount() (containerfs.ContainerFS, error) {
 	var err error
-	var mountPath string
+	var mountPath containerfs.ContainerFS
 	var chainID layer.ChainID
 	if rl.roLayer != nil {
 		chainID = rl.roLayer.ChainID()
@@ -36,7 +37,7 @@
 	mountID := stringid.GenerateRandomID()
 	rl.rwLayer, err = rl.layerStore.CreateRWLayer(mountID, chainID, nil)
 	if err != nil {
-		return "", errors.Wrap(err, "failed to create rwlayer")
+		return nil, errors.Wrap(err, "failed to create rwlayer")
 	}
 
 	mountPath, err = rl.rwLayer.Mount("")
@@ -48,7 +49,7 @@
 			logrus.Errorf("Failed to release RWLayer: %s", err)
 		}
 		rl.rwLayer = nil
-		return "", err
+		return nil, err
 	}
 
 	return mountPath, nil
diff --git a/daemon/cache.go b/daemon/cache.go
index 219b0b3..5ad68ec 100644
--- a/daemon/cache.go
+++ b/daemon/cache.go
@@ -1,9 +1,9 @@
 package daemon
 
 import (
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/builder"
 	"github.com/docker/docker/image/cache"
+	"github.com/sirupsen/logrus"
 )
 
 // MakeImageCache creates a stateful image cache.
diff --git a/daemon/checkpoint.go b/daemon/checkpoint.go
index d3028f1..7bdcae5 100644
--- a/daemon/checkpoint.go
+++ b/daemon/checkpoint.go
@@ -7,13 +7,13 @@
 	"os"
 	"path/filepath"
 
-	"github.com/docker/docker/api"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/daemon/names"
 )
 
 var (
-	validCheckpointNameChars   = api.RestrictedNameChars
-	validCheckpointNamePattern = api.RestrictedNamePattern
+	validCheckpointNameChars   = names.RestrictedNameChars
+	validCheckpointNamePattern = names.RestrictedNamePattern
 )
 
 // getCheckpointDir verifies checkpoint directory for create,remove, list options and checks if checkpoint already exists
diff --git a/daemon/cluster/cluster.go b/daemon/cluster/cluster.go
index 57fc4d2..6a7db15 100644
--- a/daemon/cluster/cluster.go
+++ b/daemon/cluster/cluster.go
@@ -46,7 +46,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/network"
 	types "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/daemon/cluster/controllers/plugin"
@@ -56,6 +55,7 @@
 	swarmapi "github.com/docker/swarmkit/api"
 	swarmnode "github.com/docker/swarmkit/node"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -72,21 +72,6 @@
 	contextPrefix         = "com.docker.swarm"
 )
 
-// errNoSwarm is returned on leaving a cluster that was never initialized
-var errNoSwarm = errors.New("This node is not part of a swarm")
-
-// errSwarmExists is returned on initialize or join request for a cluster that has already been activated
-var errSwarmExists = errors.New("This node is already part of a swarm. Use \"docker swarm leave\" to leave this swarm and join another one.")
-
-// errSwarmJoinTimeoutReached is returned when cluster join could not complete before timeout was reached.
-var errSwarmJoinTimeoutReached = errors.New("Timeout was reached before node was joined. The attempt to join the swarm will continue in the background. Use the \"docker info\" command to see the current swarm status of your node.")
-
-// errSwarmLocked is returned if the swarm is encrypted and needs a key to unlock it.
-var errSwarmLocked = errors.New("Swarm is encrypted and needs to be unlocked before it can be used. Please use \"docker swarm unlock\" to unlock it.")
-
-// errSwarmCertificatesExpired is returned if docker was not started for the whole validity period and they had no chance to renew automatically.
-var errSwarmCertificatesExpired = errors.New("Swarm certificates have expired. To replace them, leave the swarm and join again.")
-
 // NetworkSubnetsProvider exposes functions for retrieving the subnets
 // of networks managed by Docker, so they can be filtered.
 type NetworkSubnetsProvider interface {
@@ -343,12 +328,12 @@
 		if st.err == errSwarmCertificatesExpired {
 			return errSwarmCertificatesExpired
 		}
-		return errors.New("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
+		return errors.WithStack(notAvailableError("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again."))
 	}
 	if st.swarmNode.Manager() != nil {
-		return errors.New("This node is not a swarm manager. Manager is being prepared or has trouble connecting to the cluster.")
+		return errors.WithStack(notAvailableError("This node is not a swarm manager. Manager is being prepared or has trouble connecting to the cluster."))
 	}
-	return errors.New("This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.")
+	return errors.WithStack(notAvailableError("This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager."))
 }
 
 // Cleanup stops active swarm node. This is run before daemon shutdown.
diff --git a/daemon/cluster/controllers/plugin/controller.go b/daemon/cluster/controllers/plugin/controller.go
index e72edcd..b48c9fd 100644
--- a/daemon/cluster/controllers/plugin/controller.go
+++ b/daemon/cluster/controllers/plugin/controller.go
@@ -5,8 +5,8 @@
 	"io/ioutil"
 	"net/http"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
+	"github.com/docker/docker/api/errdefs"
 	enginetypes "github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/swarm/runtime"
 	"github.com/docker/docker/plugin"
@@ -14,6 +14,7 @@
 	"github.com/docker/swarmkit/api"
 	"github.com/gogo/protobuf/proto"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -198,8 +199,7 @@
 }
 
 func isNotFound(err error) bool {
-	_, ok := errors.Cause(err).(plugin.ErrNotFound)
-	return ok
+	return errdefs.IsNotFound(err)
 }
 
 // Shutdown is the shutdown phase from swarmkit
diff --git a/daemon/cluster/controllers/plugin/controller_test.go b/daemon/cluster/controllers/plugin/controller_test.go
index 17b77cc..70bb91b 100644
--- a/daemon/cluster/controllers/plugin/controller_test.go
+++ b/daemon/cluster/controllers/plugin/controller_test.go
@@ -9,13 +9,13 @@
 	"testing"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	enginetypes "github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/swarm/runtime"
 	"github.com/docker/docker/pkg/pubsub"
 	"github.com/docker/docker/plugin"
 	"github.com/docker/docker/plugin/v2"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/daemon/cluster/convert/container.go b/daemon/cluster/convert/container.go
index 6ac6f331..795e944 100644
--- a/daemon/cluster/convert/container.go
+++ b/daemon/cluster/convert/container.go
@@ -5,12 +5,12 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	container "github.com/docker/docker/api/types/container"
 	mounttypes "github.com/docker/docker/api/types/mount"
 	types "github.com/docker/docker/api/types/swarm"
 	swarmapi "github.com/docker/swarmkit/api"
 	gogotypes "github.com/gogo/protobuf/types"
+	"github.com/sirupsen/logrus"
 )
 
 func containerSpecFromGRPC(c *swarmapi.ContainerSpec) *types.ContainerSpec {
diff --git a/daemon/cluster/convert/swarm.go b/daemon/cluster/convert/swarm.go
index 2ea89b9..3ef3205 100644
--- a/daemon/cluster/convert/swarm.go
+++ b/daemon/cluster/convert/swarm.go
@@ -3,7 +3,6 @@
 import (
 	"fmt"
 	"strings"
-	"time"
 
 	types "github.com/docker/docker/api/types/swarm"
 	swarmapi "github.com/docker/swarmkit/api"
@@ -115,7 +114,7 @@
 		spec.Raft.ElectionTick = uint32(s.Raft.ElectionTick)
 	}
 	if s.Dispatcher.HeartbeatPeriod != 0 {
-		spec.Dispatcher.HeartbeatPeriod = gogotypes.DurationProto(time.Duration(s.Dispatcher.HeartbeatPeriod))
+		spec.Dispatcher.HeartbeatPeriod = gogotypes.DurationProto(s.Dispatcher.HeartbeatPeriod)
 	}
 	if s.CAConfig.NodeCertExpiry != 0 {
 		spec.CAConfig.NodeCertExpiry = gogotypes.DurationProto(s.CAConfig.NodeCertExpiry)
diff --git a/daemon/cluster/errors.go b/daemon/cluster/errors.go
new file mode 100644
index 0000000..0ffe78b
--- /dev/null
+++ b/daemon/cluster/errors.go
@@ -0,0 +1,117 @@
+package cluster
+
+const (
+	// errNoSwarm is returned on leaving a cluster that was never initialized
+	errNoSwarm notAvailableError = "This node is not part of a swarm"
+
+	// errSwarmExists is returned on initialize or join request for a cluster that has already been activated
+	errSwarmExists notAvailableError = "This node is already part of a swarm. Use \"docker swarm leave\" to leave this swarm and join another one."
+
+	// errSwarmJoinTimeoutReached is returned when cluster join could not complete before timeout was reached.
+	errSwarmJoinTimeoutReached notAvailableError = "Timeout was reached before node joined. The attempt to join the swarm will continue in the background. Use the \"docker info\" command to see the current swarm status of your node."
+
+	// errSwarmLocked is returned if the swarm is encrypted and needs a key to unlock it.
+	errSwarmLocked notAvailableError = "Swarm is encrypted and needs to be unlocked before it can be used. Please use \"docker swarm unlock\" to unlock it."
+
+	// errSwarmCertificatesExpired is returned if docker was not started for the whole validity period and they had no chance to renew automatically.
+	errSwarmCertificatesExpired notAvailableError = "Swarm certificates have expired. To replace them, leave the swarm and join again."
+
+	// errSwarmNotManager is returned if the node is not a swarm manager.
+	errSwarmNotManager notAvailableError = "This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager."
+)
+
+type notFoundError struct {
+	cause error
+}
+
+func (e notFoundError) Error() string {
+	return e.cause.Error()
+}
+
+func (e notFoundError) NotFound() {}
+
+func (e notFoundError) Cause() error {
+	return e.cause
+}
+
+type ambiguousResultsError struct {
+	cause error
+}
+
+func (e ambiguousResultsError) Error() string {
+	return e.cause.Error()
+}
+
+func (e ambiguousResultsError) InvalidParameter() {}
+
+func (e ambiguousResultsError) Cause() error {
+	return e.cause
+}
+
+type convertError struct {
+	cause error
+}
+
+func (e convertError) Error() string {
+	return e.cause.Error()
+}
+
+func (e convertError) InvalidParameter() {}
+
+func (e convertError) Cause() error {
+	return e.cause
+}
+
+type notAllowedError string
+
+func (e notAllowedError) Error() string {
+	return string(e)
+}
+
+func (e notAllowedError) Forbidden() {}
+
+type validationError struct {
+	cause error
+}
+
+func (e validationError) Error() string {
+	return e.cause.Error()
+}
+
+func (e validationError) InvalidParameter() {}
+
+func (e validationError) Cause() error {
+	return e.cause
+}
+
+type notAvailableError string
+
+func (e notAvailableError) Error() string {
+	return string(e)
+}
+
+func (e notAvailableError) Unavailable() {}
+
+type configError string
+
+func (e configError) Error() string {
+	return string(e)
+}
+
+func (e configError) InvalidParameter() {}
+
+type invalidUnlockKey struct{}
+
+func (invalidUnlockKey) Error() string {
+	return "swarm could not be unlocked: invalid key provided"
+}
+
+func (invalidUnlockKey) Unauthorized() {}
+
+type notLockedError struct{}
+
+func (notLockedError) Error() string {
+	return "swarm is not locked"
+}
+
+func (notLockedError) Conflict() {}
diff --git a/daemon/cluster/executor/backend.go b/daemon/cluster/executor/backend.go
index fbe9006..f6763d1 100644
--- a/daemon/cluster/executor/backend.go
+++ b/daemon/cluster/executor/backend.go
@@ -15,6 +15,7 @@
 	swarmtypes "github.com/docker/docker/api/types/swarm"
 	containerpkg "github.com/docker/docker/container"
 	clustertypes "github.com/docker/docker/daemon/cluster/provider"
+	networkSettings "github.com/docker/docker/daemon/network"
 	"github.com/docker/docker/plugin"
 	"github.com/docker/libnetwork"
 	"github.com/docker/libnetwork/cluster"
@@ -34,7 +35,7 @@
 	CreateManagedContainer(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error)
 	ContainerStart(name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error
 	ContainerStop(name string, seconds *int) error
-	ContainerLogs(context.Context, string, *types.ContainerLogsOptions) (<-chan *backend.LogMessage, error)
+	ContainerLogs(context.Context, string, *types.ContainerLogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error)
 	ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
 	ActivateContainerServiceBinding(containerName string) error
 	DeactivateContainerServiceBinding(containerName string) error
@@ -61,4 +62,5 @@
 	LookupImage(name string) (*types.ImageInspect, error)
 	PluginManager() *plugin.Manager
 	PluginGetter() *plugin.Store
+	GetAttachmentStore() *networkSettings.AttachmentStore
 }
diff --git a/daemon/cluster/executor/container/adapter.go b/daemon/cluster/executor/container/adapter.go
index 7444057..8077efd 100644
--- a/daemon/cluster/executor/container/adapter.go
+++ b/daemon/cluster/executor/container/adapter.go
@@ -12,7 +12,6 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
@@ -28,6 +27,7 @@
 	"github.com/docker/swarmkit/log"
 	gogotypes "github.com/gogo/protobuf/types"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/time/rate"
 )
@@ -41,8 +41,8 @@
 	dependencies exec.DependencyGetter
 }
 
-func newContainerAdapter(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*containerAdapter, error) {
-	ctnr, err := newContainerConfig(task)
+func newContainerAdapter(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*containerAdapter, error) {
+	ctnr, err := newContainerConfig(task, node)
 	if err != nil {
 		return nil, err
 	}
@@ -451,7 +451,7 @@
 			}
 		}
 	}
-	msgs, err := c.backend.ContainerLogs(ctx, c.container.name(), apiOptions)
+	msgs, _, err := c.backend.ContainerLogs(ctx, c.container.name(), apiOptions)
 	if err != nil {
 		return nil, err
 	}
diff --git a/daemon/cluster/executor/container/attachment.go b/daemon/cluster/executor/container/attachment.go
index 54f95a1..405aa2d 100644
--- a/daemon/cluster/executor/container/attachment.go
+++ b/daemon/cluster/executor/container/attachment.go
@@ -20,8 +20,8 @@
 	closed  chan struct{}
 }
 
-func newNetworkAttacherController(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*networkAttacherController, error) {
-	adapter, err := newContainerAdapter(b, task, dependencies)
+func newNetworkAttacherController(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*networkAttacherController, error) {
+	adapter, err := newContainerAdapter(b, task, node, dependencies)
 	if err != nil {
 		return nil, err
 	}
@@ -40,11 +40,7 @@
 
 func (nc *networkAttacherController) Prepare(ctx context.Context) error {
 	// Make sure all the networks that the task needs are created.
-	if err := nc.adapter.createNetworks(ctx); err != nil {
-		return err
-	}
-
-	return nil
+	return nc.adapter.createNetworks(ctx)
 }
 
 func (nc *networkAttacherController) Start(ctx context.Context) error {
@@ -69,11 +65,7 @@
 func (nc *networkAttacherController) Remove(ctx context.Context) error {
 	// Try removing the network referenced in this task in case this
 	// task is the last one referencing it
-	if err := nc.adapter.removeNetworks(ctx); err != nil {
-		return err
-	}
-
-	return nil
+	return nc.adapter.removeNetworks(ctx)
 }
 
 func (nc *networkAttacherController) Close() error {
diff --git a/daemon/cluster/executor/container/container.go b/daemon/cluster/executor/container/container.go
index 3ca7b5d..59ac9bf 100644
--- a/daemon/cluster/executor/container/container.go
+++ b/daemon/cluster/executor/container/container.go
@@ -8,7 +8,7 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
@@ -48,12 +48,12 @@
 
 // newContainerConfig returns a validated container config. No methods should
 // return an error if this function returns without error.
-func newContainerConfig(t *api.Task) (*containerConfig, error) {
+func newContainerConfig(t *api.Task, node *api.NodeDescription) (*containerConfig, error) {
 	var c containerConfig
-	return &c, c.setTask(t)
+	return &c, c.setTask(t, node)
 }
 
-func (c *containerConfig) setTask(t *api.Task) error {
+func (c *containerConfig) setTask(t *api.Task, node *api.NodeDescription) error {
 	if t.Spec.GetContainer() == nil && t.Spec.GetAttachment() == nil {
 		return exec.ErrRuntimeUnsupported
 	}
@@ -78,7 +78,7 @@
 	c.task = t
 
 	if t.Spec.GetContainer() != nil {
-		preparedSpec, err := template.ExpandContainerSpec(nil, t)
+		preparedSpec, err := template.ExpandContainerSpec(node, t)
 		if err != nil {
 			return err
 		}
diff --git a/daemon/cluster/executor/container/controller.go b/daemon/cluster/executor/container/controller.go
index 7fa4a86..dda1259 100644
--- a/daemon/cluster/executor/container/controller.go
+++ b/daemon/cluster/executor/container/controller.go
@@ -40,8 +40,8 @@
 var _ exec.Controller = &controller{}
 
 // NewController returns a docker exec runner for the provided task.
-func newController(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*controller, error) {
-	adapter, err := newContainerAdapter(b, task, dependencies)
+func newController(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*controller, error) {
+	adapter, err := newContainerAdapter(b, task, node, dependencies)
 	if err != nil {
 		return nil, err
 	}
@@ -659,7 +659,7 @@
 }
 
 func (e *exitError) ExitCode() int {
-	return int(e.code)
+	return e.code
 }
 
 func (e *exitError) Cause() error {
diff --git a/daemon/cluster/executor/container/executor.go b/daemon/cluster/executor/container/executor.go
index f6fb6e5..14e41fa 100644
--- a/daemon/cluster/executor/container/executor.go
+++ b/daemon/cluster/executor/container/executor.go
@@ -4,8 +4,8 @@
 	"fmt"
 	"sort"
 	"strings"
+	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/network"
@@ -19,6 +19,7 @@
 	"github.com/docker/swarmkit/agent/exec"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/naming"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -26,6 +27,8 @@
 	backend       executorpkg.Backend
 	pluginBackend plugin.Backend
 	dependencies  exec.DependencyManager
+	mutex         sync.Mutex // This mutex protects the following node field
+	node          *api.NodeDescription
 }
 
 // NewExecutor returns an executor from the docker client.
@@ -124,27 +127,41 @@
 		},
 	}
 
+	// Save the node information in the executor field
+	e.mutex.Lock()
+	e.node = description
+	e.mutex.Unlock()
+
 	return description, nil
 }
 
 func (e *executor) Configure(ctx context.Context, node *api.Node) error {
-	na := node.Attachment
-	if na == nil {
+	var ingressNA *api.NetworkAttachment
+	attachments := make(map[string]string)
+
+	for _, na := range node.Attachments {
+		if na.Network.Spec.Ingress {
+			ingressNA = na
+		}
+		attachments[na.Network.ID] = na.Addresses[0]
+	}
+
+	if ingressNA == nil {
 		e.backend.ReleaseIngress()
-		return nil
+		return e.backend.GetAttachmentStore().ResetAttachments(attachments)
 	}
 
 	options := types.NetworkCreate{
-		Driver: na.Network.DriverState.Name,
+		Driver: ingressNA.Network.DriverState.Name,
 		IPAM: &network.IPAM{
-			Driver: na.Network.IPAM.Driver.Name,
+			Driver: ingressNA.Network.IPAM.Driver.Name,
 		},
-		Options:        na.Network.DriverState.Options,
+		Options:        ingressNA.Network.DriverState.Options,
 		Ingress:        true,
 		CheckDuplicate: true,
 	}
 
-	for _, ic := range na.Network.IPAM.Configs {
+	for _, ic := range ingressNA.Network.IPAM.Configs {
 		c := network.IPAMConfig{
 			Subnet:  ic.Subnet,
 			IPRange: ic.Range,
@@ -154,22 +171,30 @@
 	}
 
 	_, err := e.backend.SetupIngress(clustertypes.NetworkCreateRequest{
-		ID: na.Network.ID,
+		ID: ingressNA.Network.ID,
 		NetworkCreateRequest: types.NetworkCreateRequest{
-			Name:          na.Network.Spec.Annotations.Name,
+			Name:          ingressNA.Network.Spec.Annotations.Name,
 			NetworkCreate: options,
 		},
-	}, na.Addresses[0])
+	}, ingressNA.Addresses[0])
+	if err != nil {
+		return err
+	}
 
-	return err
+	return e.backend.GetAttachmentStore().ResetAttachments(attachments)
 }
 
 // Controller returns a docker container runner.
 func (e *executor) Controller(t *api.Task) (exec.Controller, error) {
 	dependencyGetter := agent.Restrict(e.dependencies, t)
 
+	// Get the node description from the executor field
+	e.mutex.Lock()
+	nodeDescription := e.node
+	e.mutex.Unlock()
+
 	if t.Spec.GetAttachment() != nil {
-		return newNetworkAttacherController(e.backend, t, dependencyGetter)
+		return newNetworkAttacherController(e.backend, t, nodeDescription, dependencyGetter)
 	}
 
 	var ctlr exec.Controller
@@ -185,16 +210,20 @@
 		}
 		switch runtimeKind {
 		case string(swarmtypes.RuntimePlugin):
+			info, _ := e.backend.SystemInfo()
+			if !info.ExperimentalBuild {
+				return ctlr, fmt.Errorf("runtime type %q only supported in experimental", swarmtypes.RuntimePlugin)
+			}
 			c, err := plugin.NewController(e.pluginBackend, t)
 			if err != nil {
 				return ctlr, err
 			}
 			ctlr = c
 		default:
-			return ctlr, fmt.Errorf("unsupported runtime type: %q", r.Generic.Kind)
+			return ctlr, fmt.Errorf("unsupported runtime type: %q", runtimeKind)
 		}
 	case *api.TaskSpec_Container:
-		c, err := newController(e.backend, t, dependencyGetter)
+		c, err := newController(e.backend, t, nodeDescription, dependencyGetter)
 		if err != nil {
 			return ctlr, err
 		}
diff --git a/daemon/cluster/executor/container/health_test.go b/daemon/cluster/executor/container/health_test.go
index b6f1885..450865e 100644
--- a/daemon/cluster/executor/container/health_test.go
+++ b/daemon/cluster/executor/container/health_test.go
@@ -52,7 +52,7 @@
 		EventsService: e,
 	}
 
-	controller, err := newController(daemon, task, nil)
+	controller, err := newController(daemon, task, nil, nil)
 	if err != nil {
 		t.Fatalf("create controller fail %v", err)
 	}
diff --git a/daemon/cluster/executor/container/validate_test.go b/daemon/cluster/executor/container/validate_test.go
index 9d98e2c..43e224a 100644
--- a/daemon/cluster/executor/container/validate_test.go
+++ b/daemon/cluster/executor/container/validate_test.go
@@ -26,7 +26,8 @@
 				},
 			},
 		},
-	}, nil)
+	}, nil,
+		nil)
 }
 
 func TestControllerValidateMountBind(t *testing.T) {
diff --git a/daemon/cluster/helpers.go b/daemon/cluster/helpers.go
index a74118c..fd50eef 100644
--- a/daemon/cluster/helpers.go
+++ b/daemon/cluster/helpers.go
@@ -3,8 +3,8 @@
 import (
 	"fmt"
 
-	"github.com/docker/docker/api/errors"
 	swarmapi "github.com/docker/swarmkit/api"
+	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 )
 
@@ -15,7 +15,7 @@
 	}
 
 	if len(rl.Clusters) == 0 {
-		return nil, errors.NewRequestNotFoundError(errNoSwarm)
+		return nil, errors.WithStack(errNoSwarm)
 	}
 
 	// TODO: assume one cluster only
@@ -48,11 +48,11 @@
 
 	if len(rl.Nodes) == 0 {
 		err := fmt.Errorf("node %s not found", input)
-		return nil, errors.NewRequestNotFoundError(err)
+		return nil, notFoundError{err}
 	}
 
 	if l := len(rl.Nodes); l > 1 {
-		return nil, fmt.Errorf("node %s is ambiguous (%d matches found)", input, l)
+		return nil, ambiguousResultsError{fmt.Errorf("node %s is ambiguous (%d matches found)", input, l)}
 	}
 
 	return rl.Nodes[0], nil
@@ -84,11 +84,11 @@
 
 	if len(rl.Services) == 0 {
 		err := fmt.Errorf("service %s not found", input)
-		return nil, errors.NewRequestNotFoundError(err)
+		return nil, notFoundError{err}
 	}
 
 	if l := len(rl.Services); l > 1 {
-		return nil, fmt.Errorf("service %s is ambiguous (%d matches found)", input, l)
+		return nil, ambiguousResultsError{fmt.Errorf("service %s is ambiguous (%d matches found)", input, l)}
 	}
 
 	if !insertDefaults {
@@ -128,11 +128,11 @@
 
 	if len(rl.Tasks) == 0 {
 		err := fmt.Errorf("task %s not found", input)
-		return nil, errors.NewRequestNotFoundError(err)
+		return nil, notFoundError{err}
 	}
 
 	if l := len(rl.Tasks); l > 1 {
-		return nil, fmt.Errorf("task %s is ambiguous (%d matches found)", input, l)
+		return nil, ambiguousResultsError{fmt.Errorf("task %s is ambiguous (%d matches found)", input, l)}
 	}
 
 	return rl.Tasks[0], nil
@@ -164,11 +164,11 @@
 
 	if len(rl.Secrets) == 0 {
 		err := fmt.Errorf("secret %s not found", input)
-		return nil, errors.NewRequestNotFoundError(err)
+		return nil, notFoundError{err}
 	}
 
 	if l := len(rl.Secrets); l > 1 {
-		return nil, fmt.Errorf("secret %s is ambiguous (%d matches found)", input, l)
+		return nil, ambiguousResultsError{fmt.Errorf("secret %s is ambiguous (%d matches found)", input, l)}
 	}
 
 	return rl.Secrets[0], nil
@@ -200,11 +200,11 @@
 
 	if len(rl.Configs) == 0 {
 		err := fmt.Errorf("config %s not found", input)
-		return nil, errors.NewRequestNotFoundError(err)
+		return nil, notFoundError{err}
 	}
 
 	if l := len(rl.Configs); l > 1 {
-		return nil, fmt.Errorf("config %s is ambiguous (%d matches found)", input, l)
+		return nil, ambiguousResultsError{fmt.Errorf("config %s is ambiguous (%d matches found)", input, l)}
 	}
 
 	return rl.Configs[0], nil
@@ -238,7 +238,7 @@
 	}
 
 	if l := len(rl.Networks); l > 1 {
-		return nil, fmt.Errorf("network %s is ambiguous (%d matches found)", input, l)
+		return nil, ambiguousResultsError{fmt.Errorf("network %s is ambiguous (%d matches found)", input, l)}
 	}
 
 	return rl.Networks[0], nil
diff --git a/daemon/cluster/listen_addr.go b/daemon/cluster/listen_addr.go
index 993ccb6..0d65907 100644
--- a/daemon/cluster/listen_addr.go
+++ b/daemon/cluster/listen_addr.go
@@ -1,20 +1,19 @@
 package cluster
 
 import (
-	"errors"
 	"fmt"
 	"net"
 )
 
-var (
-	errNoSuchInterface         = errors.New("no such interface")
-	errNoIP                    = errors.New("could not find the system's IP address")
-	errMustSpecifyListenAddr   = errors.New("must specify a listening address because the address to advertise is not recognized as a system address, and a system's IP address to use could not be uniquely identified")
-	errBadNetworkIdentifier    = errors.New("must specify a valid IP address or interface name")
-	errBadListenAddr           = errors.New("listen address must be an IP address or network interface (with optional port number)")
-	errBadAdvertiseAddr        = errors.New("advertise address must be a non-zero IP address or network interface (with optional port number)")
-	errBadDataPathAddr         = errors.New("data path address must be a non-zero IP address or network interface (without a port number)")
-	errBadDefaultAdvertiseAddr = errors.New("default advertise address must be a non-zero IP address or network interface (without a port number)")
+const (
+	errNoSuchInterface         configError = "no such interface"
+	errNoIP                    configError = "could not find the system's IP address"
+	errMustSpecifyListenAddr   configError = "must specify a listening address because the address to advertise is not recognized as a system address, and a system's IP address to use could not be uniquely identified"
+	errBadNetworkIdentifier    configError = "must specify a valid IP address or interface name"
+	errBadListenAddr           configError = "listen address must be an IP address or network interface (with optional port number)"
+	errBadAdvertiseAddr        configError = "advertise address must be a non-zero IP address or network interface (with optional port number)"
+	errBadDataPathAddr         configError = "data path address must be a non-zero IP address or network interface (without a port number)"
+	errBadDefaultAdvertiseAddr configError = "default advertise address must be a non-zero IP address or network interface (without a port number)"
 )
 
 func resolveListenAddr(specifiedAddr string) (string, string, error) {
@@ -125,13 +124,13 @@
 			if ipAddr.IP.To4() != nil {
 				// IPv4
 				if interfaceAddr4 != nil {
-					return nil, fmt.Errorf("interface %s has more than one IPv4 address (%s and %s)", specifiedInterface, interfaceAddr4, ipAddr.IP)
+					return nil, configError(fmt.Sprintf("interface %s has more than one IPv4 address (%s and %s)", specifiedInterface, interfaceAddr4, ipAddr.IP))
 				}
 				interfaceAddr4 = ipAddr.IP
 			} else {
 				// IPv6
 				if interfaceAddr6 != nil {
-					return nil, fmt.Errorf("interface %s has more than one IPv6 address (%s and %s)", specifiedInterface, interfaceAddr6, ipAddr.IP)
+					return nil, configError(fmt.Sprintf("interface %s has more than one IPv6 address (%s and %s)", specifiedInterface, interfaceAddr6, ipAddr.IP))
 				}
 				interfaceAddr6 = ipAddr.IP
 			}
@@ -139,7 +138,7 @@
 	}
 
 	if interfaceAddr4 == nil && interfaceAddr6 == nil {
-		return nil, fmt.Errorf("interface %s has no usable IPv4 or IPv6 address", specifiedInterface)
+		return nil, configError(fmt.Sprintf("interface %s has no usable IPv4 or IPv6 address", specifiedInterface))
 	}
 
 	// In the case that there's exactly one IPv4 address
@@ -296,7 +295,7 @@
 
 func errMultipleIPs(interfaceA, interfaceB string, addrA, addrB net.IP) error {
 	if interfaceA == interfaceB {
-		return fmt.Errorf("could not choose an IP address to advertise since this system has multiple addresses on interface %s (%s and %s)", interfaceA, addrA, addrB)
+		return configError(fmt.Sprintf("could not choose an IP address to advertise since this system has multiple addresses on interface %s (%s and %s)", interfaceA, addrA, addrB))
 	}
-	return fmt.Errorf("could not choose an IP address to advertise since this system has multiple addresses on different interfaces (%s on %s and %s on %s)", addrA, interfaceA, addrB, interfaceB)
+	return configError(fmt.Sprintf("could not choose an IP address to advertise since this system has multiple addresses on different interfaces (%s on %s and %s on %s)", addrA, interfaceA, addrB, interfaceB))
 }
diff --git a/daemon/cluster/networks.go b/daemon/cluster/networks.go
index 1906c37..04582eb 100644
--- a/daemon/cluster/networks.go
+++ b/daemon/cluster/networks.go
@@ -3,8 +3,6 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
-	apierrors "github.com/docker/docker/api/errors"
 	apitypes "github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/network"
 	types "github.com/docker/docker/api/types/swarm"
@@ -12,6 +10,7 @@
 	"github.com/docker/docker/runconfig"
 	swarmapi "github.com/docker/swarmkit/api"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -250,8 +249,8 @@
 // CreateNetwork creates a new cluster managed network.
 func (c *Cluster) CreateNetwork(s apitypes.NetworkCreateRequest) (string, error) {
 	if runconfig.IsPreDefinedNetwork(s.Name) {
-		err := fmt.Errorf("%s is a pre-defined network and cannot be created", s.Name)
-		return "", apierrors.NewRequestForbiddenError(err)
+		err := notAllowedError(fmt.Sprintf("%s is a pre-defined network and cannot be created", s.Name))
+		return "", errors.WithStack(err)
 	}
 
 	var resp *swarmapi.CreateNetworkResponse
@@ -299,14 +298,13 @@
 				// and use its id for the request.
 				apiNetwork, err = getNetwork(ctx, client, ln.Name())
 				if err != nil {
-					err = fmt.Errorf("could not find the corresponding predefined swarm network: %v", err)
-					return apierrors.NewRequestNotFoundError(err)
+					return errors.Wrap(notFoundError{err}, "could not find the corresponding predefined swarm network")
 				}
 				goto setid
 			}
 			if ln != nil && !ln.Info().Dynamic() {
-				err = fmt.Errorf("The network %s cannot be used with services. Only networks scoped to the swarm can be used, such as those created with the overlay driver.", ln.Name())
-				return apierrors.NewRequestForbiddenError(err)
+				errMsg := fmt.Sprintf("The network %s cannot be used with services. Only networks scoped to the swarm can be used, such as those created with the overlay driver.", ln.Name())
+				return errors.WithStack(notAllowedError(errMsg))
 			}
 			return err
 		}
diff --git a/daemon/cluster/noderunner.go b/daemon/cluster/noderunner.go
index b970e7b..aa12737 100644
--- a/daemon/cluster/noderunner.go
+++ b/daemon/cluster/noderunner.go
@@ -8,13 +8,13 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	types "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/daemon/cluster/executor/container"
 	lncluster "github.com/docker/libnetwork/cluster"
 	swarmapi "github.com/docker/swarmkit/api"
 	swarmnode "github.com/docker/swarmkit/node"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 )
diff --git a/daemon/cluster/nodes.go b/daemon/cluster/nodes.go
index 839c8f7..582e7cd 100644
--- a/daemon/cluster/nodes.go
+++ b/daemon/cluster/nodes.go
@@ -1,7 +1,6 @@
 package cluster
 
 import (
-	apierrors "github.com/docker/docker/api/errors"
 	apitypes "github.com/docker/docker/api/types"
 	types "github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/daemon/cluster/convert"
@@ -65,7 +64,7 @@
 	return c.lockedManagerAction(func(ctx context.Context, state nodeState) error {
 		nodeSpec, err := convert.NodeSpecToGRPC(spec)
 		if err != nil {
-			return apierrors.NewBadRequestError(err)
+			return convertError{err}
 		}
 
 		ctx, cancel := c.getRequestContext()
diff --git a/daemon/cluster/services.go b/daemon/cluster/services.go
index 4f99802..f3fba8d 100644
--- a/daemon/cluster/services.go
+++ b/daemon/cluster/services.go
@@ -10,9 +10,7 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
-	apierrors "github.com/docker/docker/api/errors"
 	apitypes "github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	types "github.com/docker/docker/api/types/swarm"
@@ -22,6 +20,7 @@
 	swarmapi "github.com/docker/swarmkit/api"
 	gogotypes "github.com/gogo/protobuf/types"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -75,7 +74,7 @@
 	services := make([]types.Service, 0, len(r.Services))
 
 	for _, service := range r.Services {
-		if options.Filters.Include("mode") {
+		if options.Filters.Contains("mode") {
 			var mode string
 			switch service.Spec.GetMode().(type) {
 			case *swarmapi.ServiceSpec_Global:
@@ -129,7 +128,7 @@
 
 		serviceSpec, err := convert.ServiceSpecToGRPC(s)
 		if err != nil {
-			return apierrors.NewBadRequestError(err)
+			return convertError{err}
 		}
 
 		resp = &apitypes.ServiceCreateResponse{}
@@ -139,9 +138,16 @@
 		case *swarmapi.TaskSpec_Generic:
 			switch serviceSpec.Task.GetGeneric().Kind {
 			case string(types.RuntimePlugin):
+				info, _ := c.config.Backend.SystemInfo()
+				if !info.ExperimentalBuild {
+					return fmt.Errorf("runtime type %q only supported in experimental", types.RuntimePlugin)
+				}
 				if s.TaskTemplate.PluginSpec == nil {
 					return errors.New("plugin spec must be set")
 				}
+
+			default:
+				return fmt.Errorf("unsupported runtime type: %q", serviceSpec.Task.GetGeneric().Kind)
 			}
 
 			r, err := state.controlClient.CreateService(ctx, &swarmapi.CreateServiceRequest{Spec: &serviceSpec})
@@ -226,7 +232,7 @@
 
 		serviceSpec, err := convert.ServiceSpecToGRPC(spec)
 		if err != nil {
-			return apierrors.NewBadRequestError(err)
+			return convertError{err}
 		}
 
 		currentService, err := getService(ctx, state.controlClient, serviceIDOrName, false)
diff --git a/daemon/cluster/swarm.go b/daemon/cluster/swarm.go
index ef0596b..e3fffe9 100644
--- a/daemon/cluster/swarm.go
+++ b/daemon/cluster/swarm.go
@@ -6,8 +6,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
-	apierrors "github.com/docker/docker/api/errors"
 	apitypes "github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	types "github.com/docker/docker/api/types/swarm"
@@ -18,6 +16,7 @@
 	"github.com/docker/swarmkit/manager/encryption"
 	swarmnode "github.com/docker/swarmkit/node"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -27,9 +26,13 @@
 	defer c.controlMutex.Unlock()
 	if c.nr != nil {
 		if req.ForceNewCluster {
+
 			// Take c.mu temporarily to wait for presently running
 			// API handlers to finish before shutting down the node.
 			c.mu.Lock()
+			if !c.nr.nodeState.IsManager() {
+				return "", errSwarmNotManager
+			}
 			c.mu.Unlock()
 
 			if err := c.nr.Stop(); err != nil {
@@ -41,7 +44,7 @@
 	}
 
 	if err := validateAndSanitizeInitRequest(&req); err != nil {
-		return "", apierrors.NewBadRequestError(err)
+		return "", validationError{err}
 	}
 
 	listenHost, listenPort, err := resolveListenAddr(req.ListenAddr)
@@ -132,12 +135,12 @@
 	c.mu.Lock()
 	if c.nr != nil {
 		c.mu.Unlock()
-		return errSwarmExists
+		return errors.WithStack(errSwarmExists)
 	}
 	c.mu.Unlock()
 
 	if err := validateAndSanitizeJoinRequest(&req); err != nil {
-		return apierrors.NewBadRequestError(err)
+		return validationError{err}
 	}
 
 	listenHost, listenPort, err := resolveListenAddr(req.ListenAddr)
@@ -222,7 +225,7 @@
 		// will be used to swarmkit.
 		clusterSpec, err := convert.SwarmSpecToGRPC(spec)
 		if err != nil {
-			return apierrors.NewBadRequestError(err)
+			return convertError{err}
 		}
 
 		_, err = state.controlClient.UpdateCluster(
@@ -284,7 +287,7 @@
 	} else {
 		// when manager is active, return an error of "not locked"
 		c.mu.RUnlock()
-		return errors.New("swarm is not locked")
+		return notLockedError{}
 	}
 
 	// only when swarm is locked, code running reaches here
@@ -293,7 +296,7 @@
 
 	key, err := encryption.ParseHumanReadableKey(req.UnlockKey)
 	if err != nil {
-		return err
+		return validationError{err}
 	}
 
 	config := nr.config
@@ -312,9 +315,9 @@
 
 	if err := <-nr.Ready(); err != nil {
 		if errors.Cause(err) == errSwarmLocked {
-			return errors.New("swarm could not be unlocked: invalid key provided")
+			return invalidUnlockKey{}
 		}
-		return fmt.Errorf("swarm component could not be started: %v", err)
+		return errors.Errorf("swarm component could not be started: %v", err)
 	}
 	return nil
 }
@@ -328,7 +331,7 @@
 	nr := c.nr
 	if nr == nil {
 		c.mu.Unlock()
-		return errNoSwarm
+		return errors.WithStack(errNoSwarm)
 	}
 
 	state := c.currentNodeState()
@@ -337,7 +340,7 @@
 
 	if errors.Cause(state.err) == errSwarmLocked && !force {
 		// leave a locked swarm without --force is not allowed
-		return errors.New("Swarm is encrypted and locked. Please unlock it first or use `--force` to ignore this message.")
+		return errors.WithStack(notAvailableError("Swarm is encrypted and locked. Please unlock it first or use `--force` to ignore this message."))
 	}
 
 	if state.IsManager() && !force {
@@ -348,7 +351,7 @@
 				if active && removingManagerCausesLossOfQuorum(reachable, unreachable) {
 					if isLastManager(reachable, unreachable) {
 						msg += "Removing the last manager erases all current state of the swarm. Use `--force` to ignore this message. "
-						return errors.New(msg)
+						return errors.WithStack(notAvailableError(msg))
 					}
 					msg += fmt.Sprintf("Removing this node leaves %v managers out of %v. Without a Raft quorum your swarm will be inaccessible. ", reachable-1, reachable+unreachable)
 				}
@@ -358,7 +361,7 @@
 		}
 
 		msg += "The only way to restore a swarm that has lost consensus is to reinitialize it with `--force-new-cluster`. Use `--force` to suppress this message."
-		return errors.New(msg)
+		return errors.WithStack(notAvailableError(msg))
 	}
 	// release readers in here
 	if err := nr.Stop(); err != nil {
diff --git a/daemon/cluster/tasks.go b/daemon/cluster/tasks.go
index 26706a2..f52301f 100644
--- a/daemon/cluster/tasks.go
+++ b/daemon/cluster/tasks.go
@@ -15,7 +15,7 @@
 
 	if err := c.lockedManagerAction(func(ctx context.Context, state nodeState) error {
 		filterTransform := func(filter filters.Args) error {
-			if filter.Include("service") {
+			if filter.Contains("service") {
 				serviceFilters := filter.Get("service")
 				for _, serviceFilter := range serviceFilters {
 					service, err := getService(ctx, state.controlClient, serviceFilter, false)
@@ -26,7 +26,7 @@
 					filter.Add("service", service.ID)
 				}
 			}
-			if filter.Include("node") {
+			if filter.Contains("node") {
 				nodeFilters := filter.Get("node")
 				for _, nodeFilter := range nodeFilters {
 					node, err := getNode(ctx, state.controlClient, nodeFilter)
@@ -37,7 +37,7 @@
 					filter.Add("node", node.ID)
 				}
 			}
-			if !filter.Include("runtime") {
+			if !filter.Contains("runtime") {
 				// default to only showing container tasks
 				filter.Add("runtime", "container")
 				filter.Add("runtime", "")
diff --git a/daemon/commit.go b/daemon/commit.go
index 084f488..2684f61 100644
--- a/daemon/commit.go
+++ b/daemon/commit.go
@@ -2,6 +2,7 @@
 
 import (
 	"encoding/json"
+	"fmt"
 	"io"
 	"runtime"
 	"strings"
@@ -133,6 +134,16 @@
 		return "", errors.Errorf("%+v does not support commit of a running container", runtime.GOOS)
 	}
 
+	if container.IsDead() {
+		err := fmt.Errorf("You cannot commit container %s which is Dead", container.ID)
+		return "", stateConflictError{err}
+	}
+
+	if container.IsRemovalInProgress() {
+		err := fmt.Errorf("You cannot commit container %s which is being removed", container.ID)
+		return "", stateConflictError{err}
+	}
+
 	if c.Pause && !container.IsPaused() {
 		daemon.containerPause(container)
 		defer daemon.containerUnpause(container)
@@ -234,19 +245,36 @@
 	return id.String(), nil
 }
 
-func (daemon *Daemon) exportContainerRw(container *container.Container) (io.ReadCloser, error) {
-	if err := daemon.Mount(container); err != nil {
+func (daemon *Daemon) exportContainerRw(container *container.Container) (arch io.ReadCloser, err error) {
+	rwlayer, err := daemon.stores[container.Platform].layerStore.GetRWLayer(container.ID)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err != nil {
+			daemon.stores[container.Platform].layerStore.ReleaseRWLayer(rwlayer)
+		}
+	}()
+
+	// TODO: this mount call is not necessary as we assume that TarStream() should
+	// mount the layer if needed. But the Diff() function for windows requests that
+	// the layer should be mounted when calling it. So we reserve this mount call
+	// until windows driver can implement Diff() interface correctly.
+	_, err = rwlayer.Mount(container.GetMountLabel())
+	if err != nil {
 		return nil, err
 	}
 
-	archive, err := container.RWLayer.TarStream()
+	archive, err := rwlayer.TarStream()
 	if err != nil {
-		daemon.Unmount(container) // logging is already handled in the `Unmount` function
+		rwlayer.Unmount()
 		return nil, err
 	}
 	return ioutils.NewReadCloserWrapper(archive, func() error {
 			archive.Close()
-			return container.RWLayer.Unmount()
+			err = rwlayer.Unmount()
+			daemon.stores[container.Platform].layerStore.ReleaseRWLayer(rwlayer)
+			return err
 		}),
 		nil
 }
diff --git a/daemon/config/config.go b/daemon/config/config.go
index 5adb7e6..501c07a 100644
--- a/daemon/config/config.go
+++ b/daemon/config/config.go
@@ -12,13 +12,13 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	daemondiscovery "github.com/docker/docker/daemon/discovery"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/authorization"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/registry"
 	"github.com/imdario/mergo"
+	"github.com/sirupsen/logrus"
 	"github.com/spf13/pflag"
 )
 
@@ -103,7 +103,6 @@
 	Root                 string                    `json:"data-root,omitempty"`
 	SocketGroup          string                    `json:"group,omitempty"`
 	CorsHeaders          string                    `json:"api-cors-header,omitempty"`
-	EnableCors           bool                      `json:"api-enable-cors,omitempty"`
 
 	// TrustKeyPath is used to generate the daemon ID and for signing schema 1 manifests
 	// when pushing to a registry which does not support schema 2. This field is marked as
@@ -502,7 +501,7 @@
 		}
 	}
 
-	if _, err := opts.ParseGenericResources(config.NodeGenericResources); err != nil {
+	if _, err := ParseGenericResources(config.NodeGenericResources); err != nil {
 		return err
 	}
 
@@ -513,6 +512,11 @@
 		}
 	}
 
+	// validate platform-specific settings
+	if err := config.ValidatePlatformConfig(); err != nil {
+		return err
+	}
+
 	return nil
 }
 
diff --git a/daemon/config/config_solaris.go b/daemon/config/config_solaris.go
index f4f0802..6b1e061 100644
--- a/daemon/config/config_solaris.go
+++ b/daemon/config/config_solaris.go
@@ -1,9 +1,5 @@
 package config
 
-import (
-	"github.com/spf13/pflag"
-)
-
 // Config defines the configuration of a docker daemon.
 // These are the configuration settings that you pass
 // to the docker daemon when you launch it with say: `docker -d -e lxc`
@@ -27,3 +23,8 @@
 func (conf *Config) IsSwarmCompatible() error {
 	return nil
 }
+
+// ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
+func (conf *Config) ValidatePlatformConfig() error {
+	return nil
+}
diff --git a/daemon/config/config_test.go b/daemon/config/config_test.go
index cc5f010..43246d9 100644
--- a/daemon/config/config_test.go
+++ b/daemon/config/config_test.go
@@ -8,8 +8,8 @@
 	"testing"
 
 	"github.com/docker/docker/daemon/discovery"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/docker/docker/opts"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/spf13/pflag"
 	"github.com/stretchr/testify/assert"
 )
diff --git a/daemon/config/config_unix.go b/daemon/config/config_unix.go
index 8f1da59..3a9e1cf 100644
--- a/daemon/config/config_unix.go
+++ b/daemon/config/config_unix.go
@@ -5,10 +5,16 @@
 import (
 	"fmt"
 
+	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/opts"
 	units "github.com/docker/go-units"
 )
 
+const (
+	// DefaultIpcMode is default for container's IpcMode, if not set otherwise
+	DefaultIpcMode = "shareable" // TODO: change to private
+)
+
 // Config defines the configuration of a docker daemon.
 // It includes json tags to deserialize configuration from a file
 // using the same names that the flags in the command line uses.
@@ -31,6 +37,7 @@
 	SeccompProfile       string                   `json:"seccomp-profile,omitempty"`
 	ShmSize              opts.MemBytes            `json:"default-shm-size,omitempty"`
 	NoNewPrivileges      bool                     `json:"no-new-privileges,omitempty"`
+	IpcMode              string                   `json:"default-ipc-mode,omitempty"`
 }
 
 // BridgeConfig stores all the bridge driver specific
@@ -61,3 +68,21 @@
 	}
 	return nil
 }
+
+func verifyDefaultIpcMode(mode string) error {
+	const hint = "Use \"shareable\" or \"private\"."
+
+	dm := containertypes.IpcMode(mode)
+	if !dm.Valid() {
+		return fmt.Errorf("Default IPC mode setting (%v) is invalid. "+hint, dm)
+	}
+	if dm != "" && !dm.IsPrivate() && !dm.IsShareable() {
+		return fmt.Errorf("IPC mode \"%v\" is not supported as default value. "+hint, dm)
+	}
+	return nil
+}
+
+// ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
+func (conf *Config) ValidatePlatformConfig() error {
+	return verifyDefaultIpcMode(conf.IpcMode)
+}
diff --git a/daemon/config/config_unix_test.go b/daemon/config/config_unix_test.go
index 9e52cb7..fedf757 100644
--- a/daemon/config/config_unix_test.go
+++ b/daemon/config/config_unix_test.go
@@ -6,15 +6,15 @@
 	"testing"
 
 	"github.com/docker/docker/opts"
-	"github.com/docker/docker/pkg/testutil/tempfile"
-	"github.com/docker/go-units"
+	units "github.com/docker/go-units"
+	"github.com/gotestyourself/gotestyourself/fs"
 	"github.com/spf13/pflag"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestGetConflictFreeConfiguration(t *testing.T) {
-	configFileData := string([]byte(`
+	configFileData := `
 		{
 			"debug": true,
 			"default-ulimits": {
@@ -27,9 +27,9 @@
 			"log-opts": {
 				"tag": "test_tag"
 			}
-		}`))
+		}`
 
-	file := tempfile.NewTempFile(t, "docker-config", configFileData)
+	file := fs.NewFile(t, "docker-config", fs.WithContent(configFileData))
 	defer file.Remove()
 
 	flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
@@ -38,7 +38,7 @@
 	flags.Var(opts.NewNamedUlimitOpt("default-ulimits", nil), "default-ulimit", "")
 	flags.Var(opts.NewNamedMapOpts("log-opts", nil, nil), "log-opt", "")
 
-	cc, err := getConflictFreeConfiguration(file.Name(), flags)
+	cc, err := getConflictFreeConfiguration(file.Path(), flags)
 	require.NoError(t, err)
 
 	assert.True(t, cc.Debug)
@@ -55,7 +55,7 @@
 }
 
 func TestDaemonConfigurationMerge(t *testing.T) {
-	configFileData := string([]byte(`
+	configFileData := `
 		{
 			"debug": true,
 			"default-ulimits": {
@@ -68,9 +68,9 @@
 			"log-opts": {
 				"tag": "test_tag"
 			}
-		}`))
+		}`
 
-	file := tempfile.NewTempFile(t, "docker-config", configFileData)
+	file := fs.NewFile(t, "docker-config", fs.WithContent(configFileData))
 	defer file.Remove()
 
 	c := &Config{
@@ -90,7 +90,7 @@
 	flags.Var(opts.NewNamedUlimitOpt("default-ulimits", nil), "default-ulimit", "")
 	flags.Var(opts.NewNamedMapOpts("log-opts", nil, nil), "log-opt", "")
 
-	cc, err := MergeDaemonConfigurations(c, flags, file.Name())
+	cc, err := MergeDaemonConfigurations(c, flags, file.Path())
 	require.NoError(t, err)
 
 	assert.True(t, cc.Debug)
@@ -115,12 +115,9 @@
 }
 
 func TestDaemonConfigurationMergeShmSize(t *testing.T) {
-	data := string([]byte(`
-		{
-			"default-shm-size": "1g"
-		}`))
+	data := `{"default-shm-size": "1g"}`
 
-	file := tempfile.NewTempFile(t, "docker-config", data)
+	file := fs.NewFile(t, "docker-config", fs.WithContent(data))
 	defer file.Remove()
 
 	c := &Config{}
@@ -129,11 +126,9 @@
 	shmSize := opts.MemBytes(DefaultShmSize)
 	flags.Var(&shmSize, "default-shm-size", "")
 
-	cc, err := MergeDaemonConfigurations(c, flags, file.Name())
+	cc, err := MergeDaemonConfigurations(c, flags, file.Path())
 	require.NoError(t, err)
 
 	expectedValue := 1 * 1024 * 1024 * 1024
-	if cc.ShmSize.Value() != int64(expectedValue) {
-		t.Fatalf("expected default shm size %d, got %d", expectedValue, cc.ShmSize.Value())
-	}
+	assert.Equal(t, int64(expectedValue), cc.ShmSize.Value())
 }
diff --git a/daemon/config/config_windows.go b/daemon/config/config_windows.go
index 849acc1..6f994e3 100644
--- a/daemon/config/config_windows.go
+++ b/daemon/config/config_windows.go
@@ -50,3 +50,8 @@
 func (conf *Config) IsSwarmCompatible() error {
 	return nil
 }
+
+// ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
+func (conf *Config) ValidatePlatformConfig() error {
+	return nil
+}
diff --git a/daemon/config/opts.go b/daemon/config/opts.go
new file mode 100644
index 0000000..00f32e4
--- /dev/null
+++ b/daemon/config/opts.go
@@ -0,0 +1,22 @@
+package config
+
+import (
+	"github.com/docker/docker/api/types/swarm"
+	"github.com/docker/docker/daemon/cluster/convert"
+	"github.com/docker/swarmkit/api/genericresource"
+)
+
+// ParseGenericResources parses and validates the specified string as a list of GenericResource
+func ParseGenericResources(value string) ([]swarm.GenericResource, error) {
+	if value == "" {
+		return nil, nil
+	}
+
+	resources, err := genericresource.Parse(value)
+	if err != nil {
+		return nil, err
+	}
+
+	obj := convert.GenericResourcesFromGRPC(resources)
+	return obj, nil
+}
diff --git a/daemon/configs.go b/daemon/configs.go
index 31da56b..9d9137c 100644
--- a/daemon/configs.go
+++ b/daemon/configs.go
@@ -1,8 +1,8 @@
 package daemon
 
 import (
-	"github.com/Sirupsen/logrus"
 	swarmtypes "github.com/docker/docker/api/types/swarm"
+	"github.com/sirupsen/logrus"
 )
 
 // SetContainerConfigReferences sets the container config references needed
diff --git a/daemon/container.go b/daemon/container.go
index 4c015b7..79b9d41 100644
--- a/daemon/container.go
+++ b/daemon/container.go
@@ -3,10 +3,12 @@
 import (
 	"fmt"
 	"os"
+	"path"
 	"path/filepath"
+	"runtime"
+	"strings"
 	"time"
 
-	"github.com/docker/docker/api/errors"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/strslice"
 	"github.com/docker/docker/container"
@@ -19,6 +21,7 @@
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/go-connections/nat"
 	"github.com/opencontainers/selinux/go-selinux/label"
+	"github.com/pkg/errors"
 )
 
 // GetContainer looks for a container using the provided information, which could be
@@ -30,7 +33,7 @@
 //  If none of these searches succeed, an error is returned
 func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
 	if len(prefixOrName) == 0 {
-		return nil, errors.NewBadRequestError(fmt.Errorf("No container name or ID supplied"))
+		return nil, errors.WithStack(invalidIdentifier(prefixOrName))
 	}
 
 	if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
@@ -48,10 +51,9 @@
 	if indexError != nil {
 		// When truncindex defines an error type, use that instead
 		if indexError == truncindex.ErrNotExist {
-			err := fmt.Errorf("No such container: %s", prefixOrName)
-			return nil, errors.NewRequestNotFoundError(err)
+			return nil, containerNotFound(prefixOrName)
 		}
-		return nil, indexError
+		return nil, systemError{indexError}
 	}
 	return daemon.containers.Get(containerID), nil
 }
@@ -136,7 +138,7 @@
 		if config.Hostname == "" {
 			config.Hostname, err = os.Hostname()
 			if err != nil {
-				return nil, err
+				return nil, systemError{err}
 			}
 		}
 	} else {
@@ -227,13 +229,24 @@
 
 // verifyContainerSettings performs validation of the hostconfig and config
 // structures.
-func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
-
+func (daemon *Daemon) verifyContainerSettings(platform string, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
 	// First perform verification of settings common across all platforms.
 	if config != nil {
 		if config.WorkingDir != "" {
-			config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
-			if !system.IsAbs(config.WorkingDir) {
+			wdInvalid := false
+			if runtime.GOOS == platform {
+				config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
+				if !system.IsAbs(config.WorkingDir) {
+					wdInvalid = true
+				}
+			} else {
+				// LCOW. Force Unix semantics
+				config.WorkingDir = strings.Replace(config.WorkingDir, string(os.PathSeparator), "/", -1)
+				if !path.IsAbs(config.WorkingDir) {
+					wdInvalid = true
+				}
+			}
+			if wdInvalid {
 				return nil, fmt.Errorf("the working directory '%s' is invalid, it needs to be an absolute path", config.WorkingDir)
 			}
 		}
@@ -255,19 +268,19 @@
 		// Validate the healthcheck params of Config
 		if config.Healthcheck != nil {
 			if config.Healthcheck.Interval != 0 && config.Healthcheck.Interval < containertypes.MinimumDuration {
-				return nil, fmt.Errorf("Interval in Healthcheck cannot be less than %s", containertypes.MinimumDuration)
+				return nil, errors.Errorf("Interval in Healthcheck cannot be less than %s", containertypes.MinimumDuration)
 			}
 
 			if config.Healthcheck.Timeout != 0 && config.Healthcheck.Timeout < containertypes.MinimumDuration {
-				return nil, fmt.Errorf("Timeout in Healthcheck cannot be less than %s", containertypes.MinimumDuration)
+				return nil, errors.Errorf("Timeout in Healthcheck cannot be less than %s", containertypes.MinimumDuration)
 			}
 
 			if config.Healthcheck.Retries < 0 {
-				return nil, fmt.Errorf("Retries in Healthcheck cannot be negative")
+				return nil, errors.Errorf("Retries in Healthcheck cannot be negative")
 			}
 
 			if config.Healthcheck.StartPeriod != 0 && config.Healthcheck.StartPeriod < containertypes.MinimumDuration {
-				return nil, fmt.Errorf("StartPeriod in Healthcheck cannot be less than %s", containertypes.MinimumDuration)
+				return nil, errors.Errorf("StartPeriod in Healthcheck cannot be less than %s", containertypes.MinimumDuration)
 			}
 		}
 	}
@@ -277,7 +290,7 @@
 	}
 
 	if hostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
-		return nil, fmt.Errorf("can't create 'AutoRemove' container with restart policy")
+		return nil, errors.Errorf("can't create 'AutoRemove' container with restart policy")
 	}
 
 	for _, extraHost := range hostConfig.ExtraHosts {
@@ -289,12 +302,12 @@
 	for port := range hostConfig.PortBindings {
 		_, portStr := nat.SplitProtoPort(string(port))
 		if _, err := nat.ParsePort(portStr); err != nil {
-			return nil, fmt.Errorf("invalid port specification: %q", portStr)
+			return nil, errors.Errorf("invalid port specification: %q", portStr)
 		}
 		for _, pb := range hostConfig.PortBindings[port] {
 			_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
 			if err != nil {
-				return nil, fmt.Errorf("invalid port specification: %q", pb.HostPort)
+				return nil, errors.Errorf("invalid port specification: %q", pb.HostPort)
 			}
 		}
 	}
@@ -304,16 +317,16 @@
 	switch p.Name {
 	case "always", "unless-stopped", "no":
 		if p.MaximumRetryCount != 0 {
-			return nil, fmt.Errorf("maximum retry count cannot be used with restart policy '%s'", p.Name)
+			return nil, errors.Errorf("maximum retry count cannot be used with restart policy '%s'", p.Name)
 		}
 	case "on-failure":
 		if p.MaximumRetryCount < 0 {
-			return nil, fmt.Errorf("maximum retry count cannot be negative")
+			return nil, errors.Errorf("maximum retry count cannot be negative")
 		}
 	case "":
 		// do nothing
 	default:
-		return nil, fmt.Errorf("invalid restart policy '%s'", p.Name)
+		return nil, errors.Errorf("invalid restart policy '%s'", p.Name)
 	}
 
 	// Now do platform-specific verification
diff --git a/daemon/container_linux.go b/daemon/container_linux.go
index 2c87715..d05992d 100644
--- a/daemon/container_linux.go
+++ b/daemon/container_linux.go
@@ -14,7 +14,7 @@
 	}
 
 	if err := parseSecurityOpt(container, container.HostConfig); err != nil {
-		return err
+		return validationError{err}
 	}
 
 	if !container.HostConfig.Privileged {
diff --git a/daemon/container_operations.go b/daemon/container_operations.go
index 7c7dcc7..fc08f82 100644
--- a/daemon/container_operations.go
+++ b/daemon/container_operations.go
@@ -10,8 +10,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
-	derr "github.com/docker/docker/api/errors"
 	containertypes "github.com/docker/docker/api/types/container"
 	networktypes "github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/container"
@@ -24,6 +22,7 @@
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -923,7 +922,7 @@
 	}
 	if !nc.IsRunning() {
 		err := fmt.Errorf("cannot join network of a non running container: %s", connectedContainerID)
-		return nil, derr.NewRequestConflictError(err)
+		return nil, stateConflictError{err}
 	}
 	if nc.IsRestarting() {
 		return nil, errContainerIsRestarting(connectedContainerID)
diff --git a/daemon/container_operations_unix.go b/daemon/container_operations_unix.go
index 8c1b44b..954c194 100644
--- a/daemon/container_operations_unix.go
+++ b/daemon/container_operations_unix.go
@@ -11,7 +11,6 @@
 	"strconv"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/links"
 	"github.com/docker/docker/pkg/idtools"
@@ -21,6 +20,7 @@
 	"github.com/docker/libnetwork"
 	"github.com/opencontainers/selinux/go-selinux/label"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
@@ -57,13 +57,27 @@
 	return env, nil
 }
 
-func (daemon *Daemon) getIpcContainer(container *container.Container) (*container.Container, error) {
-	containerID := container.HostConfig.IpcMode.Container()
-	container, err := daemon.GetContainer(containerID)
+func (daemon *Daemon) getIpcContainer(id string) (*container.Container, error) {
+	errMsg := "can't join IPC of container " + id
+	// Check the container exists
+	container, err := daemon.GetContainer(id)
 	if err != nil {
-		return nil, errors.Wrapf(err, "cannot join IPC of a non running container: %s", container.ID)
+		return nil, errors.Wrap(err, errMsg)
 	}
-	return container, daemon.checkContainer(container, containerIsRunning, containerIsNotRestarting)
+	// Check the container is running and not restarting
+	if err := daemon.checkContainer(container, containerIsRunning, containerIsNotRestarting); err != nil {
+		return nil, errors.Wrap(err, errMsg)
+	}
+	// Check the container ipc is shareable
+	if st, err := os.Stat(container.ShmPath); err != nil || !st.IsDir() {
+		if err == nil || os.IsNotExist(err) {
+			return nil, errors.New(errMsg + ": non-shareable IPC")
+		}
+		// stat() failed?
+		return nil, errors.Wrap(err, errMsg+": unexpected error from stat "+container.ShmPath)
+	}
+
+	return container, nil
 }
 
 func (daemon *Daemon) getPidContainer(container *container.Container) (*container.Container, error) {
@@ -77,7 +91,7 @@
 
 func containerIsRunning(c *container.Container) error {
 	if !c.IsRunning() {
-		return errors.Errorf("container %s is not running", c.ID)
+		return stateConflictError{errors.Errorf("container %s is not running", c.ID)}
 	}
 	return nil
 }
@@ -90,25 +104,33 @@
 }
 
 func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
-	var err error
+	ipcMode := c.HostConfig.IpcMode
 
-	c.ShmPath, err = c.ShmResourcePath()
-	if err != nil {
-		return err
-	}
-
-	if c.HostConfig.IpcMode.IsContainer() {
-		ic, err := daemon.getIpcContainer(c)
+	switch {
+	case ipcMode.IsContainer():
+		ic, err := daemon.getIpcContainer(ipcMode.Container())
 		if err != nil {
 			return err
 		}
 		c.ShmPath = ic.ShmPath
-	} else if c.HostConfig.IpcMode.IsHost() {
+
+	case ipcMode.IsHost():
 		if _, err := os.Stat("/dev/shm"); err != nil {
 			return fmt.Errorf("/dev/shm is not mounted, but must be for --ipc=host")
 		}
 		c.ShmPath = "/dev/shm"
-	} else {
+
+	case ipcMode.IsPrivate(), ipcMode.IsNone():
+		// c.ShmPath will/should not be used, so make it empty.
+		// Container's /dev/shm mount comes from OCI spec.
+		c.ShmPath = ""
+
+	case ipcMode.IsEmpty():
+		// A container was created by an older version of the daemon.
+		// The default behavior used to be what is now called "shareable".
+		fallthrough
+
+	case ipcMode.IsShareable():
 		rootIDs := daemon.idMappings.RootPair()
 		if !c.HasMountFor("/dev/shm") {
 			shmPath, err := c.ShmResourcePath()
@@ -120,19 +142,18 @@
 				return err
 			}
 
-			shmSize := int64(daemon.configStore.ShmSize)
-			if c.HostConfig.ShmSize != 0 {
-				shmSize = c.HostConfig.ShmSize
-			}
-			shmproperty := "mode=1777,size=" + strconv.FormatInt(shmSize, 10)
+			shmproperty := "mode=1777,size=" + strconv.FormatInt(c.HostConfig.ShmSize, 10)
 			if err := unix.Mount("shm", shmPath, "tmpfs", uintptr(unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV), label.FormatMountLabel(shmproperty, c.GetMountLabel())); err != nil {
 				return fmt.Errorf("mounting shm tmpfs: %s", err)
 			}
 			if err := os.Chown(shmPath, rootIDs.UID, rootIDs.GID); err != nil {
 				return err
 			}
+			c.ShmPath = shmPath
 		}
 
+	default:
+		return fmt.Errorf("invalid IPC mode: %v", ipcMode)
 	}
 
 	return nil
@@ -286,6 +307,8 @@
 		if err := os.Chown(fPath, rootIDs.UID+uid, rootIDs.GID+gid); err != nil {
 			return errors.Wrap(err, "error setting ownership for config")
 		}
+
+		label.Relabel(fPath, c.MountLabel, false)
 	}
 
 	return nil
diff --git a/daemon/container_operations_windows.go b/daemon/container_operations_windows.go
index 2788f1a..51762a2 100644
--- a/daemon/container_operations_windows.go
+++ b/daemon/container_operations_windows.go
@@ -5,11 +5,11 @@
 	"io/ioutil"
 	"os"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/libnetwork"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]string, error) {
diff --git a/daemon/create.go b/daemon/create.go
index 78070fd..c722405 100644
--- a/daemon/create.go
+++ b/daemon/create.go
@@ -9,8 +9,6 @@
 
 	"github.com/pkg/errors"
 
-	"github.com/Sirupsen/logrus"
-	apierrors "github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	networktypes "github.com/docker/docker/api/types/network"
@@ -22,6 +20,7 @@
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/runconfig"
 	"github.com/opencontainers/selinux/go-selinux/label"
+	"github.com/sirupsen/logrus"
 )
 
 // CreateManagedContainer creates a container that is managed by a Service
@@ -37,17 +36,27 @@
 func (daemon *Daemon) containerCreate(params types.ContainerCreateConfig, managed bool) (containertypes.ContainerCreateCreatedBody, error) {
 	start := time.Now()
 	if params.Config == nil {
-		return containertypes.ContainerCreateCreatedBody{}, fmt.Errorf("Config cannot be empty in order to create a container")
+		return containertypes.ContainerCreateCreatedBody{}, validationError{errors.New("Config cannot be empty in order to create a container")}
 	}
 
-	warnings, err := daemon.verifyContainerSettings(params.HostConfig, params.Config, false)
-	if err != nil {
-		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, err
+	// TODO: @jhowardmsft LCOW support - at a later point, can remove the hard-coding
+	// to force the platform to be linux.
+	// Default the platform if not supplied
+	if params.Platform == "" {
+		params.Platform = runtime.GOOS
+	}
+	if system.LCOWSupported() {
+		params.Platform = "linux"
 	}
 
-	err = daemon.verifyNetworkingConfig(params.NetworkingConfig)
+	warnings, err := daemon.verifyContainerSettings(params.Platform, params.HostConfig, params.Config, false)
 	if err != nil {
-		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, err
+		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, validationError{err}
+	}
+
+	err = verifyNetworkingConfig(params.NetworkingConfig)
+	if err != nil {
+		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, validationError{err}
 	}
 
 	if params.HostConfig == nil {
@@ -55,12 +64,12 @@
 	}
 	err = daemon.adaptContainerSettings(params.HostConfig, params.AdjustCPUShares)
 	if err != nil {
-		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, err
+		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, validationError{err}
 	}
 
 	container, err := daemon.create(params, managed)
 	if err != nil {
-		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, daemon.imageNotExistToErrcode(err)
+		return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, err
 	}
 	containerActions.WithValues("create").UpdateSince(start)
 
@@ -76,16 +85,6 @@
 		err       error
 	)
 
-	// TODO: @jhowardmsft LCOW support - at a later point, can remove the hard-coding
-	// to force the platform to be linux.
-	// Default the platform if not supplied
-	if params.Platform == "" {
-		params.Platform = runtime.GOOS
-	}
-	if system.LCOWSupported() {
-		params.Platform = "linux"
-	}
-
 	if params.Config.Image != "" {
 		img, err = daemon.GetImage(params.Config.Image)
 		if err != nil {
@@ -113,11 +112,11 @@
 	}
 
 	if err := daemon.mergeAndVerifyConfig(params.Config, img); err != nil {
-		return nil, err
+		return nil, validationError{err}
 	}
 
 	if err := daemon.mergeAndVerifyLogConfig(&params.HostConfig.LogConfig); err != nil {
-		return nil, err
+		return nil, validationError{err}
 	}
 
 	if container, err = daemon.newContainer(params.Name, params.Platform, params.Config, params.HostConfig, imgID, managed); err != nil {
@@ -137,9 +136,26 @@
 
 	container.HostConfig.StorageOpt = params.HostConfig.StorageOpt
 
+	// Fixes: https://github.com/moby/moby/issues/34074 and
+	// https://github.com/docker/for-win/issues/999.
+	// Merge the daemon's storage options if they aren't already present. We only
+	// do this on Windows as there's no effective sandbox size limit other than
+	// physical on Linux.
+	if runtime.GOOS == "windows" {
+		if container.HostConfig.StorageOpt == nil {
+			container.HostConfig.StorageOpt = make(map[string]string)
+		}
+		for _, v := range daemon.configStore.GraphOptions {
+			opt := strings.SplitN(v, "=", 2)
+			if _, ok := container.HostConfig.StorageOpt[opt[0]]; !ok {
+				container.HostConfig.StorageOpt[opt[0]] = opt[1]
+			}
+		}
+	}
+
 	// Set RWLayer for container after mount labels have been set
 	if err := daemon.setRWLayer(container); err != nil {
-		return nil, err
+		return nil, systemError{err}
 	}
 
 	rootIDs := daemon.idMappings.RootPair()
@@ -295,7 +311,7 @@
 
 // Checks if the client set configurations for more than one network while creating a container
 // Also checks if the IPAMConfig is valid
-func (daemon *Daemon) verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
+func verifyNetworkingConfig(nwConfig *networktypes.NetworkingConfig) error {
 	if nwConfig == nil || len(nwConfig.EndpointsConfig) == 0 {
 		return nil
 	}
@@ -303,14 +319,14 @@
 		for _, v := range nwConfig.EndpointsConfig {
 			if v != nil && v.IPAMConfig != nil {
 				if v.IPAMConfig.IPv4Address != "" && net.ParseIP(v.IPAMConfig.IPv4Address).To4() == nil {
-					return apierrors.NewBadRequestError(fmt.Errorf("invalid IPv4 address: %s", v.IPAMConfig.IPv4Address))
+					return errors.Errorf("invalid IPv4 address: %s", v.IPAMConfig.IPv4Address)
 				}
 				if v.IPAMConfig.IPv6Address != "" {
 					n := net.ParseIP(v.IPAMConfig.IPv6Address)
 					// if the address is an invalid network address (ParseIP == nil) or if it is
 					// an IPv4 address (To4() != nil), then it is an invalid IPv6 address
 					if n == nil || n.To4() != nil {
-						return apierrors.NewBadRequestError(fmt.Errorf("invalid IPv6 address: %s", v.IPAMConfig.IPv6Address))
+						return errors.Errorf("invalid IPv6 address: %s", v.IPAMConfig.IPv6Address)
 					}
 				}
 			}
@@ -321,6 +337,5 @@
 	for k := range nwConfig.EndpointsConfig {
 		l = append(l, k)
 	}
-	err := fmt.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
-	return apierrors.NewBadRequestError(err)
+	return errors.Errorf("Container cannot be connected to network endpoints: %s", strings.Join(l, ", "))
 }
diff --git a/daemon/create_unix.go b/daemon/create_unix.go
index 2501a33..1940e9c 100644
--- a/daemon/create_unix.go
+++ b/daemon/create_unix.go
@@ -7,12 +7,12 @@
 	"os"
 	"path/filepath"
 
-	"github.com/Sirupsen/logrus"
 	containertypes "github.com/docker/docker/api/types/container"
 	mounttypes "github.com/docker/docker/api/types/mount"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/opencontainers/selinux/go-selinux/label"
+	"github.com/sirupsen/logrus"
 )
 
 // createContainerPlatformSpecificSettings performs platform specific container create functionality
diff --git a/daemon/create_windows.go b/daemon/create_windows.go
index bbf0dbe..059980b 100644
--- a/daemon/create_windows.go
+++ b/daemon/create_windows.go
@@ -2,6 +2,7 @@
 
 import (
 	"fmt"
+	"runtime"
 
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
@@ -11,14 +12,24 @@
 
 // createContainerPlatformSpecificSettings performs platform specific container create functionality
 func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error {
-	// Make sure the host config has the default daemon isolation if not specified by caller.
-	if containertypes.Isolation.IsDefault(containertypes.Isolation(hostConfig.Isolation)) {
-		hostConfig.Isolation = daemon.defaultIsolation
-	}
 
+	if container.Platform == runtime.GOOS {
+		// Make sure the host config has the default daemon isolation if not specified by caller.
+		if containertypes.Isolation.IsDefault(containertypes.Isolation(hostConfig.Isolation)) {
+			hostConfig.Isolation = daemon.defaultIsolation
+		}
+	} else {
+		// LCOW must be a Hyper-V container as you can't run a shared kernel when one
+		// is a Windows kernel, the other is a Linux kernel.
+		if containertypes.Isolation.IsProcess(containertypes.Isolation(hostConfig.Isolation)) {
+			return fmt.Errorf("process isolation is invalid for Linux containers on Windows")
+		}
+		hostConfig.Isolation = "hyperv"
+	}
+	parser := volume.NewParser(container.Platform)
 	for spec := range config.Volumes {
 
-		mp, err := volume.ParseMountRaw(spec, hostConfig.VolumeDriver)
+		mp, err := parser.ParseMountRaw(spec, hostConfig.VolumeDriver)
 		if err != nil {
 			return fmt.Errorf("Unrecognised volume spec: %v", err)
 		}
diff --git a/daemon/daemon.go b/daemon/daemon.go
index 4d4b98c..23c7b20 100644
--- a/daemon/daemon.go
+++ b/daemon/daemon.go
@@ -18,9 +18,7 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	containerd "github.com/containerd/containerd/api/grpc/types"
-	"github.com/docker/docker/api"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/swarm"
@@ -30,7 +28,8 @@
 	"github.com/docker/docker/daemon/events"
 	"github.com/docker/docker/daemon/exec"
 	"github.com/docker/docker/daemon/logger"
-	"github.com/docker/docker/opts"
+	"github.com/docker/docker/daemon/network"
+	"github.com/sirupsen/logrus"
 	// register graph drivers
 	_ "github.com/docker/docker/daemon/graphdriver/register"
 	"github.com/docker/docker/daemon/initlayer"
@@ -42,12 +41,14 @@
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/migrate/v1"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/pkg/truncindex"
 	"github.com/docker/docker/plugin"
+	pluginexec "github.com/docker/docker/plugin/executor/containerd"
 	refstore "github.com/docker/docker/reference"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/runconfig"
@@ -66,7 +67,7 @@
 	// containerd if none is specified
 	DefaultRuntimeBinary = "docker-runc"
 
-	errSystemNotSupported = errors.New("The Docker daemon is not supported on this platform.")
+	errSystemNotSupported = errors.New("the Docker daemon is not supported on this platform")
 )
 
 type daemonStore struct {
@@ -75,7 +76,6 @@
 	imageStore                image.Store
 	layerStore                layer.Store
 	distributionMetadataStore dmetadata.Store
-	referenceStore            refstore.Store
 }
 
 // Daemon holds information about the Docker daemon.
@@ -103,7 +103,8 @@
 	shutdown              bool
 	idMappings            *idtools.IDMappings
 	stores                map[string]daemonStore // By container target platform
-	PluginStore           *plugin.Store          // todo: remove
+	referenceStore        refstore.Store
+	PluginStore           *plugin.Store // todo: remove
 	pluginManager         *plugin.Manager
 	linkIndex             *linkIndex
 	containerd            libcontainerd.Client
@@ -123,6 +124,8 @@
 	pruneRunning     int32
 	hosts            map[string]bool // hosts stores the addresses the daemon is listening on
 	startupDone      chan struct{}
+
+	attachmentStore network.AttachmentStore
 }
 
 // StoreHosts stores the addresses the daemon is listening on
@@ -137,10 +140,7 @@
 
 // HasExperimental returns whether the experimental features of the daemon are enabled or not
 func (daemon *Daemon) HasExperimental() bool {
-	if daemon.configStore != nil && daemon.configStore.Experimental {
-		return true
-	}
-	return false
+	return daemon.configStore != nil && daemon.configStore.Experimental
 }
 
 func (daemon *Daemon) restore() error {
@@ -490,6 +490,8 @@
 	} else {
 		logrus.Warnf("failed to initiate ingress network removal: %v", err)
 	}
+
+	daemon.attachmentStore.ClearAttachments()
 }
 
 // setClusterProvider sets a component for querying the current cluster state.
@@ -642,12 +644,16 @@
 	}
 	registerMetricsPluginCallback(d.PluginStore, metricsSockPath)
 
+	createPluginExec := func(m *plugin.Manager) (plugin.Executor, error) {
+		return pluginexec.New(containerdRemote, m)
+	}
+
 	// Plugin system initialization should happen before restore. Do not change order.
 	d.pluginManager, err = plugin.NewManager(plugin.ManagerConfig{
 		Root:               filepath.Join(config.Root, "plugins"),
 		ExecRoot:           getPluginExecRoot(config.Root),
 		Store:              d.PluginStore,
-		Executor:           containerdRemote,
+		CreateExecutor:     createPluginExec,
 		RegistryService:    registryService,
 		LiveRestoreEnabled: config.LiveRestoreEnabled,
 		LogPluginEvent:     d.LogPluginEvent, // todo: make private
@@ -691,7 +697,6 @@
 	d.downloadManager = xfer.NewLayerDownloadManager(lsMap, *config.MaxConcurrentDownloads)
 	logrus.Debugf("Max Concurrent Uploads: %d", *config.MaxConcurrentUploads)
 	d.uploadManager = xfer.NewLayerUploadManager(*config.MaxConcurrentUploads)
-
 	for platform, ds := range d.stores {
 		imageRoot := filepath.Join(config.Root, "image", ds.graphDriver)
 		ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))
@@ -715,7 +720,7 @@
 		return nil, err
 	}
 
-	trustKey, err := api.LoadOrCreateTrustKey(config.TrustKeyPath)
+	trustKey, err := loadOrCreateTrustKey(config.TrustKeyPath)
 	if err != nil {
 		return nil, err
 	}
@@ -728,18 +733,30 @@
 
 	eventsService := events.New()
 
+	// We have a single tag/reference store for the daemon globally. However, it's
+	// stored under the graphdriver. On host platforms which only support a single
+	// container OS, but multiple selectable graphdrivers, this means depending on which
+	// graphdriver is chosen, the global reference store is under there. For
+	// platforms which support multiple container operating systems, this is slightly
+	// more problematic as where does the global ref store get located? Fortunately,
+	// for Windows, which is currently the only daemon supporting multiple container
+	// operating systems, the list of graphdrivers available isn't user configurable.
+	// For backwards compatibility, we just put it under the windowsfilter
+	// directory regardless.
+	refStoreLocation := filepath.Join(d.stores[runtime.GOOS].imageRoot, `repositories.json`)
+	rs, err := refstore.NewReferenceStore(refStoreLocation)
+	if err != nil {
+		return nil, fmt.Errorf("Couldn't create reference store repository: %s", err)
+	}
+	d.referenceStore = rs
+
 	for platform, ds := range d.stores {
 		dms, err := dmetadata.NewFSMetadataStore(filepath.Join(ds.imageRoot, "distribution"), platform)
 		if err != nil {
 			return nil, err
 		}
 
-		rs, err := refstore.NewReferenceStore(filepath.Join(ds.imageRoot, "repositories.json"), platform)
-		if err != nil {
-			return nil, fmt.Errorf("Couldn't create Tag store repositories: %s", err)
-		}
 		ds.distributionMetadataStore = dms
-		ds.referenceStore = rs
 		d.stores[platform] = ds
 
 		// No content-addressability migration on Windows as it never supported pre-CA
@@ -850,7 +867,7 @@
 
 	// Wait without timeout for the container to exit.
 	// Ignore the result.
-	_ = <-c.Wait(context.Background(), container.WaitConditionNotRunning)
+	<-c.Wait(context.Background(), container.WaitConditionNotRunning)
 	return nil
 }
 
@@ -957,11 +974,11 @@
 	}
 	logrus.Debugf("container mounted via layerStore: %v", dir)
 
-	if container.BaseFS != dir {
+	if container.BaseFS != nil && container.BaseFS.Path() != dir.Path() {
 		// The mount path reported by the graph driver should always be trusted on Windows, since the
 		// volume path for a given mounted layer may change over time.  This should only be an error
 		// on non-Windows operating systems.
-		if container.BaseFS != "" && runtime.GOOS != "windows" {
+		if runtime.GOOS != "windows" {
 			daemon.Unmount(container)
 			return fmt.Errorf("Error: driver %s is returning inconsistent paths for container %s ('%s' then '%s')",
 				daemon.GraphDriverName(container.Platform), container.ID, container.BaseFS, dir)
@@ -1024,7 +1041,7 @@
 					logrus.Warnf("failed to delete old tmp directory: %s", newName)
 				}
 			}()
-		} else {
+		} else if !os.IsNotExist(err) {
 			logrus.Warnf("failed to rename %s for background deletion: %s. Deleting synchronously", tmpDir, err)
 			if err := os.RemoveAll(tmpDir); err != nil {
 				logrus.Warnf("failed to delete old tmp directory: %s", tmpDir)
@@ -1036,13 +1053,13 @@
 	return tmpDir, idtools.MkdirAllAndChown(tmpDir, 0700, rootIDs)
 }
 
-func (daemon *Daemon) setupInitLayer(initPath string) error {
+func (daemon *Daemon) setupInitLayer(initPath containerfs.ContainerFS) error {
 	rootIDs := daemon.idMappings.RootPair()
 	return initlayer.Setup(initPath, rootIDs)
 }
 
 func (daemon *Daemon) setGenericResources(conf *config.Config) error {
-	genericResources, err := opts.ParseGenericResources(conf.NodeGenericResources)
+	genericResources, err := config.ParseGenericResources(conf.NodeGenericResources)
 	if err != nil {
 		return err
 	}
@@ -1233,3 +1250,8 @@
 		resources.MemorySwappiness = nil
 	}
 }
+
+// GetAttachmentStore returns current attachment store associated with the daemon
+func (daemon *Daemon) GetAttachmentStore() *network.AttachmentStore {
+	return &daemon.attachmentStore
+}
diff --git a/daemon/daemon_linux.go b/daemon/daemon_linux.go
index 000a048..56ed4ce 100644
--- a/daemon/daemon_linux.go
+++ b/daemon/daemon_linux.go
@@ -8,9 +8,9 @@
 	"regexp"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/mount"
+	"github.com/sirupsen/logrus"
 )
 
 // On Linux, plugins use a static path for storing execution state,
diff --git a/daemon/daemon_solaris.go b/daemon/daemon_solaris.go
index f464ee3..9c7d67f 100644
--- a/daemon/daemon_solaris.go
+++ b/daemon/daemon_solaris.go
@@ -7,40 +7,41 @@
 	"net"
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/image"
-	"github.com/docker/docker/layer"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/sysinfo"
-	refstore "github.com/docker/docker/reference"
 	"github.com/docker/libnetwork"
 	nwconfig "github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/drivers/solaris/bridge"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netutils"
 	lntypes "github.com/docker/libnetwork/types"
-	"github.com/opencontainers/runtime-spec/specs-go"
+	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/opencontainers/selinux/go-selinux/label"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 //#include <zone.h>
 import "C"
 
 const (
-	defaultVirtualSwitch = "Virtual Switch"
-	platformSupported    = true
-	solarisMinCPUShares  = 1
-	solarisMaxCPUShares  = 65535
+	platformSupported   = true
+	solarisMinCPUShares = 1
+	solarisMaxCPUShares = 65535
 )
 
 func getMemoryResources(config containertypes.Resources) specs.CappedMemory {
-	memory := specs.CappedMemory{}
+	memory := specs.CappedMemory{
+		DisableOOMKiller: config.OomKillDisable,
+	}
 
 	if config.Memory > 0 {
 		memory.Physical = strconv.FormatInt(config.Memory, 10)
@@ -72,7 +73,7 @@
 }
 
 func parseSecurityOpt(container *container.Container, config *containertypes.HostConfig) error {
-	//Since config.SecurityOpt is specifically defined as a "List of string values to
+	//Since hostConfig.SecurityOpt is specifically defined as a "List of string values to
 	//customize labels for MLs systems, such as SELinux"
 	//until we figure out how to map to Trusted Extensions
 	//this is being disabled for now on Solaris
@@ -89,15 +90,15 @@
 	return err
 }
 
-func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) {
-	return nil, nil, nil
+func setupRemappedRoot(config *config.Config) (*idtools.IDMappings, error) {
+	return nil, nil
 }
 
-func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
+func setupDaemonRoot(config *config.Config, rootDir string, rootIDs idtools.IDPair) error {
 	return nil
 }
 
-func (daemon *Daemon) getLayerInit() func(string) error {
+func (daemon *Daemon) getLayerInit() func(containerfs.ContainerFS) error {
 	return nil
 }
 
@@ -136,7 +137,7 @@
 }
 
 // UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
-func UsingSystemd(config *Config) bool {
+func UsingSystemd(config *config.Config) bool {
 	return false
 }
 
@@ -309,25 +310,26 @@
 
 // reloadPlatform updates configuration with platform specific options
 // and updates the passed attributes
-func (daemon *Daemon) reloadPlatform(config *Config, attributes map[string]string) {
-}
-
-// verifyDaemonSettings performs validation of daemon config struct
-func verifyDaemonSettings(config *Config) error {
-
-	if config.DefaultRuntime == "" {
-		config.DefaultRuntime = stockRuntimeName
-	}
-	if config.Runtimes == nil {
-		config.Runtimes = make(map[string]types.Runtime)
-	}
-	stockRuntimeOpts := []string{}
-	config.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary, Args: stockRuntimeOpts}
-
-	// checkSystem validates platform-specific requirements
+func (daemon *Daemon) reloadPlatform(conf *config.Config, attributes map[string]string) error {
 	return nil
 }
 
+// verifyDaemonSettings performs validation of daemon config struct
+func verifyDaemonSettings(conf *config.Config) error {
+
+	if conf.DefaultRuntime == "" {
+		conf.DefaultRuntime = stockRuntimeName
+	}
+	if conf.Runtimes == nil {
+		conf.Runtimes = make(map[string]types.Runtime)
+	}
+	stockRuntimeOpts := []string{}
+	conf.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary, Args: stockRuntimeOpts}
+
+	return nil
+}
+
+// checkSystem validates platform-specific requirements
 func checkSystem() error {
 	// check OS version for compatibility, ensure running in global zone
 	var err error
@@ -349,16 +351,16 @@
 
 // configureMaxThreads sets the Go runtime max threads threshold
 // which is 90% of the kernel setting from /proc/sys/kernel/threads-max
-func configureMaxThreads(config *Config) error {
+func configureMaxThreads(config *config.Config) error {
 	return nil
 }
 
-// configureKernelSecuritySupport configures and validate security support for the kernel
+// configureKernelSecuritySupport configures and validates security support for the kernel
 func configureKernelSecuritySupport(config *config.Config, driverNames []string) error {
 	return nil
 }
 
-func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
+func (daemon *Daemon) initNetworkController(config *config.Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
 	netOptions, err := daemon.networkOptions(config, daemon.PluginStore, activeSandboxes)
 	if err != nil {
 		return nil, err
@@ -384,7 +386,7 @@
 	return controller, nil
 }
 
-func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error {
+func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error {
 	if n, err := controller.NetworkByName("bridge"); err == nil {
 		if err = n.Delete(); err != nil {
 			return fmt.Errorf("could not delete the default bridge network: %v", err)
@@ -497,12 +499,7 @@
 	return daemon.Unmount(container)
 }
 
-func restoreCustomImage(is image.Store, ls layer.Store, rs refstore.Store) error {
-	// Solaris has no custom images to register
-	return nil
-}
-
-func driverOptions(config *Config) []nwconfig.Option {
+func driverOptions(config *config.Config) []nwconfig.Option {
 	return []nwconfig.Option{}
 }
 
@@ -520,7 +517,7 @@
 	return types.RootFS{}
 }
 
-func setupDaemonProcess(config *Config) error {
+func setupDaemonProcess(config *config.Config) error {
 	return nil
 }
 
diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go
index 562b749..31f8bc0 100644
--- a/daemon/daemon_unix.go
+++ b/daemon/daemon_unix.go
@@ -16,7 +16,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/blkiodev"
 	pblkiodev "github.com/docker/docker/api/types/blkiodev"
@@ -25,6 +24,7 @@
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/opts"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/parsers/kernel"
@@ -44,6 +44,7 @@
 	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/opencontainers/selinux/go-selinux/label"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 	"golang.org/x/sys/unix"
 )
@@ -64,22 +65,23 @@
 	cgroupSystemdDriver = "systemd"
 )
 
+type containerGetter interface {
+	GetContainer(string) (*container.Container, error)
+}
+
 func getMemoryResources(config containertypes.Resources) *specs.LinuxMemory {
 	memory := specs.LinuxMemory{}
 
 	if config.Memory > 0 {
-		limit := uint64(config.Memory)
-		memory.Limit = &limit
+		memory.Limit = &config.Memory
 	}
 
 	if config.MemoryReservation > 0 {
-		reservation := uint64(config.MemoryReservation)
-		memory.Reservation = &reservation
+		memory.Reservation = &config.MemoryReservation
 	}
 
 	if config.MemorySwap > 0 {
-		swap := uint64(config.MemorySwap)
-		memory.Swap = &swap
+		memory.Swap = &config.MemorySwap
 	}
 
 	if config.MemorySwappiness != nil {
@@ -88,8 +90,7 @@
 	}
 
 	if config.KernelMemory != 0 {
-		kernelMemory := uint64(config.KernelMemory)
-		memory.Kernel = &kernelMemory
+		memory.Kernel = &config.KernelMemory
 	}
 
 	return &memory
@@ -276,6 +277,17 @@
 			hostConfig.ShmSize = int64(daemon.configStore.ShmSize)
 		}
 	}
+	// Set default IPC mode, if unset for container
+	if hostConfig.IpcMode.IsEmpty() {
+		m := config.DefaultIpcMode
+		if daemon.configStore != nil {
+			m = daemon.configStore.IpcMode
+		}
+		hostConfig.IpcMode = containertypes.IpcMode(m)
+	}
+
+	adaptSharedNamespaceContainer(daemon, hostConfig)
+
 	var err error
 	opts, err := daemon.generateSecurityOpt(hostConfig)
 	if err != nil {
@@ -290,6 +302,36 @@
 	return nil
 }
 
+// adaptSharedNamespaceContainer replaces container name with its ID in hostConfig.
+// To be more precisely, it modifies `container:name` to `container:ID` of PidMode, IpcMode
+// and NetworkMode.
+//
+// When a container shares its namespace with another container, use ID can keep the namespace
+// sharing connection between the two containers even the another container is renamed.
+func adaptSharedNamespaceContainer(daemon containerGetter, hostConfig *containertypes.HostConfig) {
+	containerPrefix := "container:"
+	if hostConfig.PidMode.IsContainer() {
+		pidContainer := hostConfig.PidMode.Container()
+		// if there is any error returned here, we just ignore it and leave it to be
+		// handled in the following logic
+		if c, err := daemon.GetContainer(pidContainer); err == nil {
+			hostConfig.PidMode = containertypes.PidMode(containerPrefix + c.ID)
+		}
+	}
+	if hostConfig.IpcMode.IsContainer() {
+		ipcContainer := hostConfig.IpcMode.Container()
+		if c, err := daemon.GetContainer(ipcContainer); err == nil {
+			hostConfig.IpcMode = containertypes.IpcMode(containerPrefix + c.ID)
+		}
+	}
+	if hostConfig.NetworkMode.IsContainer() {
+		netContainer := hostConfig.NetworkMode.ConnectedContainer()
+		if c, err := daemon.GetContainer(netContainer); err == nil {
+			hostConfig.NetworkMode = containertypes.NetworkMode(containerPrefix + c.ID)
+		}
+	}
+}
+
 func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysinfo.SysInfo, update bool) ([]string, error) {
 	warnings := []string{}
 	fixMemorySwappiness(resources)
@@ -461,6 +503,7 @@
 		warnings = append(warnings, "Your kernel does not support BPS Block I/O write limit or the cgroup is not mounted. Block I/O BPS write limit discarded.")
 		logrus.Warn("Your kernel does not support BPS Block I/O write limit or the cgroup is not mounted. Block I/O BPS write limit discarded.")
 		resources.BlkioDeviceWriteBps = []*pblkiodev.ThrottleDevice{}
+
 	}
 	if len(resources.BlkioDeviceReadIOps) > 0 && !sysInfo.BlkioReadIOpsDevice {
 		warnings = append(warnings, "Your kernel does not support IOPS Block read limit or the cgroup is not mounted. Block I/O IOPS read limit discarded.")
@@ -547,13 +590,13 @@
 	// check for various conflicting options with user namespaces
 	if daemon.configStore.RemappedRoot != "" && hostConfig.UsernsMode.IsPrivate() {
 		if hostConfig.Privileged {
-			return warnings, fmt.Errorf("Privileged mode is incompatible with user namespaces")
+			return warnings, fmt.Errorf("privileged mode is incompatible with user namespaces.  You must run the container in the host namespace when running privileged mode")
 		}
 		if hostConfig.NetworkMode.IsHost() && !hostConfig.UsernsMode.IsHost() {
-			return warnings, fmt.Errorf("Cannot share the host's network namespace when user namespaces are enabled")
+			return warnings, fmt.Errorf("cannot share the host's network namespace when user namespaces are enabled")
 		}
 		if hostConfig.PidMode.IsHost() && !hostConfig.UsernsMode.IsHost() {
-			return warnings, fmt.Errorf("Cannot share the host PID namespace when user namespaces are enabled")
+			return warnings, fmt.Errorf("cannot share the host PID namespace when user namespaces are enabled")
 		}
 	}
 	if hostConfig.CgroupParent != "" && UsingSystemd(daemon.configStore) {
@@ -570,8 +613,9 @@
 		return warnings, fmt.Errorf("Unknown runtime specified %s", hostConfig.Runtime)
 	}
 
+	parser := volume.NewParser(runtime.GOOS)
 	for dest := range hostConfig.Tmpfs {
-		if err := volume.ValidateTmpfsMountDestination(dest); err != nil {
+		if err := parser.ValidateTmpfsMountDestination(dest); err != nil {
 			return warnings, err
 		}
 	}
@@ -581,7 +625,11 @@
 
 // reloadPlatform updates configuration with platform specific options
 // and updates the passed attributes
-func (daemon *Daemon) reloadPlatform(conf *config.Config, attributes map[string]string) {
+func (daemon *Daemon) reloadPlatform(conf *config.Config, attributes map[string]string) error {
+	if err := conf.ValidatePlatformConfig(); err != nil {
+		return err
+	}
+
 	if conf.IsValueSet("runtimes") {
 		daemon.configStore.Runtimes = conf.Runtimes
 		// Always set the default one
@@ -596,6 +644,10 @@
 		daemon.configStore.ShmSize = conf.ShmSize
 	}
 
+	if conf.IpcMode != "" {
+		daemon.configStore.IpcMode = conf.IpcMode
+	}
+
 	// Update attributes
 	var runtimeList bytes.Buffer
 	for name, rt := range daemon.configStore.Runtimes {
@@ -608,6 +660,9 @@
 	attributes["runtimes"] = runtimeList.String()
 	attributes["default-runtime"] = daemon.configStore.DefaultRuntime
 	attributes["default-shm-size"] = fmt.Sprintf("%d", daemon.configStore.ShmSize)
+	attributes["default-ipc-mode"] = daemon.configStore.IpcMode
+
+	return nil
 }
 
 // verifyDaemonSettings performs validation of daemon config struct
@@ -934,7 +989,7 @@
 	}
 }
 
-func (daemon *Daemon) getLayerInit() func(string) error {
+func (daemon *Daemon) getLayerInit() func(containerfs.ContainerFS) error {
 	return daemon.setupInitLayer
 }
 
@@ -1104,7 +1159,7 @@
 				break
 			}
 			if !idtools.CanAccess(dirPath, rootIDs) {
-				return fmt.Errorf("A subdirectory in your graphroot path (%s) restricts access to the remapped root uid/gid; please fix by allowing 'o+x' permissions on existing directories.", config.Root)
+				return fmt.Errorf("a subdirectory in your graphroot path (%s) restricts access to the remapped root uid/gid; please fix by allowing 'o+x' permissions on existing directories", config.Root)
 			}
 		}
 	}
@@ -1124,13 +1179,13 @@
 		}
 		child, err := daemon.GetContainer(name)
 		if err != nil {
-			return fmt.Errorf("Could not get container for %s", name)
+			return errors.Wrapf(err, "could not get container for %s", name)
 		}
 		for child.HostConfig.NetworkMode.IsContainer() {
 			parts := strings.SplitN(string(child.HostConfig.NetworkMode), ":", 2)
 			child, err = daemon.GetContainer(parts[1])
 			if err != nil {
-				return fmt.Errorf("Could not get container for %s", parts[1])
+				return errors.Wrapf(err, "Could not get container for %s", parts[1])
 			}
 		}
 		if child.HostConfig.NetworkMode.IsHost() {
@@ -1161,12 +1216,12 @@
 
 func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
 	if !c.IsRunning() {
-		return nil, errNotRunning{c.ID}
+		return nil, errNotRunning(c.ID)
 	}
 	stats, err := daemon.containerd.Stats(c.ID)
 	if err != nil {
 		if strings.Contains(err.Error(), "container not found") {
-			return nil, errNotFound{c.ID}
+			return nil, containerNotFound(c.ID)
 		}
 		return nil, err
 	}
@@ -1242,7 +1297,39 @@
 // setupDaemonProcess sets various settings for the daemon's process
 func setupDaemonProcess(config *config.Config) error {
 	// setup the daemons oom_score_adj
-	return setupOOMScoreAdj(config.OOMScoreAdjust)
+	if err := setupOOMScoreAdj(config.OOMScoreAdjust); err != nil {
+		return err
+	}
+	return setMayDetachMounts()
+}
+
+// This is used to allow removal of mountpoints that may be mounted in other
+// namespaces on RHEL based kernels starting from RHEL 7.4.
+// Without this setting, removals on these RHEL based kernels may fail with
+// "device or resource busy".
+// This setting is not available in upstream kernels as it is not configurable,
+// but has been in the upstream kernels since 3.15.
+func setMayDetachMounts() error {
+	f, err := os.OpenFile("/proc/sys/fs/may_detach_mounts", os.O_WRONLY, 0)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return nil
+		}
+		return errors.Wrap(err, "error opening may_detach_mounts kernel config file")
+	}
+	defer f.Close()
+
+	_, err = f.WriteString("1")
+	if os.IsPermission(err) {
+		// Setting may_detach_mounts does not work in an
+		// unprivileged container. Ignore the error, but log
+		// it if we appear not to be in that situation.
+		if !rsystem.RunningInUserNS() {
+			logrus.Debugf("Permission denied writing %q to /proc/sys/fs/may_detach_mounts", "1")
+		}
+		return nil
+	}
+	return err
 }
 
 func setupOOMScoreAdj(score int) error {
diff --git a/daemon/daemon_unix_test.go b/daemon/daemon_unix_test.go
index c3aa443..2bdbd23 100644
--- a/daemon/daemon_unix_test.go
+++ b/daemon/daemon_unix_test.go
@@ -3,6 +3,7 @@
 package daemon
 
 import (
+	"errors"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -16,8 +17,47 @@
 	"github.com/docker/docker/volume/drivers"
 	"github.com/docker/docker/volume/local"
 	"github.com/docker/docker/volume/store"
+	"github.com/stretchr/testify/require"
 )
 
+type fakeContainerGetter struct {
+	containers map[string]*container.Container
+}
+
+func (f *fakeContainerGetter) GetContainer(cid string) (*container.Container, error) {
+	container, ok := f.containers[cid]
+	if !ok {
+		return nil, errors.New("container not found")
+	}
+	return container, nil
+}
+
+// Unix test as uses settings which are not available on Windows
+func TestAdjustSharedNamespaceContainerName(t *testing.T) {
+	fakeID := "abcdef1234567890"
+	hostConfig := &containertypes.HostConfig{
+		IpcMode:     containertypes.IpcMode("container:base"),
+		PidMode:     containertypes.PidMode("container:base"),
+		NetworkMode: containertypes.NetworkMode("container:base"),
+	}
+	containerStore := &fakeContainerGetter{}
+	containerStore.containers = make(map[string]*container.Container)
+	containerStore.containers["base"] = &container.Container{
+		ID: fakeID,
+	}
+
+	adaptSharedNamespaceContainer(containerStore, hostConfig)
+	if hostConfig.IpcMode != containertypes.IpcMode("container:"+fakeID) {
+		t.Errorf("Expected IpcMode to be container:%s", fakeID)
+	}
+	if hostConfig.PidMode != containertypes.PidMode("container:"+fakeID) {
+		t.Errorf("Expected PidMode to be container:%s", fakeID)
+	}
+	if hostConfig.NetworkMode != containertypes.NetworkMode("container:"+fakeID) {
+		t.Errorf("Expected NetworkMode to be container:%s", fakeID)
+	}
+}
+
 // Unix test as uses settings which are not available on Windows
 func TestAdjustCPUShares(t *testing.T) {
 	tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-")
@@ -250,13 +290,12 @@
 	containerRoot := filepath.Join(rootDir, "containers")
 	cid := "1234"
 	err = os.MkdirAll(filepath.Join(containerRoot, cid), 0755)
+	require.NoError(t, err)
 
 	vid := "5678"
 	vfsPath := filepath.Join(rootDir, "vfs", "dir", vid)
 	err = os.MkdirAll(vfsPath, 0755)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	config := []byte(`
 		{
diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go
index 798ba39..8dcea03 100644
--- a/daemon/daemon_windows.go
+++ b/daemon/daemon_windows.go
@@ -5,15 +5,14 @@
 	"os"
 	"path/filepath"
 	"strings"
-	"syscall"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/image"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/parsers"
@@ -28,7 +27,10 @@
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/options"
 	blkiodev "github.com/opencontainers/runc/libcontainer/configs"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/windows"
+	"golang.org/x/sys/windows/svc/mgr"
 )
 
 const (
@@ -38,9 +40,6 @@
 	windowsMaxCPUShares  = 10000
 	windowsMinCPUPercent = 1
 	windowsMaxCPUPercent = 100
-	windowsMinCPUCount   = 1
-
-	errInvalidState = syscall.Errno(0x139F)
 )
 
 // Windows has no concept of an execution state directory. So use config.Root here.
@@ -60,23 +59,7 @@
 	return nil
 }
 
-func getBlkioReadIOpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) {
-	return nil, nil
-}
-
-func getBlkioWriteIOpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) {
-	return nil, nil
-}
-
-func getBlkioReadBpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) {
-	return nil, nil
-}
-
-func getBlkioWriteBpsDevices(config *containertypes.HostConfig) ([]blkiodev.ThrottleDevice, error) {
-	return nil, nil
-}
-
-func (daemon *Daemon) getLayerInit() func(string) error {
+func (daemon *Daemon) getLayerInit() func(containerfs.ContainerFS) error {
 	return nil
 }
 
@@ -231,7 +214,8 @@
 
 // reloadPlatform updates configuration with platform specific options
 // and updates the passed attributes
-func (daemon *Daemon) reloadPlatform(config *config.Config, attributes map[string]string) {
+func (daemon *Daemon) reloadPlatform(config *config.Config, attributes map[string]string) error {
+	return nil
 }
 
 // verifyDaemonSettings performs validation of daemon config struct
@@ -253,9 +237,32 @@
 
 	vmcompute := windows.NewLazySystemDLL("vmcompute.dll")
 	if vmcompute.Load() != nil {
-		return fmt.Errorf("Failed to load vmcompute.dll. Ensure that the Containers role is installed.")
+		return fmt.Errorf("failed to load vmcompute.dll, ensure that the Containers feature is installed")
 	}
 
+	// Ensure that the required Host Network Service and vmcompute services
+	// are running. Docker will fail in unexpected ways if this is not present.
+	var requiredServices = []string{"hns", "vmcompute"}
+	if err := ensureServicesInstalled(requiredServices); err != nil {
+		return errors.Wrap(err, "a required service is not installed, ensure the Containers feature is installed")
+	}
+
+	return nil
+}
+
+func ensureServicesInstalled(services []string) error {
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	for _, service := range services {
+		s, err := m.OpenService(service)
+		if err != nil {
+			return errors.Wrapf(err, "failed to open service %s", service)
+		}
+		s.Close()
+	}
 	return nil
 }
 
@@ -519,14 +526,14 @@
 
 func (daemon *Daemon) stats(c *container.Container) (*types.StatsJSON, error) {
 	if !c.IsRunning() {
-		return nil, errNotRunning{c.ID}
+		return nil, errNotRunning(c.ID)
 	}
 
 	// Obtain the stats from HCS via libcontainerd
 	stats, err := daemon.containerd.Stats(c.ID)
 	if err != nil {
 		if strings.Contains(err.Error(), "container not found") {
-			return nil, errNotFound{c.ID}
+			return nil, containerNotFound(c.ID)
 		}
 		return nil, err
 	}
diff --git a/daemon/daemon_windows_test.go b/daemon/daemon_windows_test.go
new file mode 100644
index 0000000..8b350cf
--- /dev/null
+++ b/daemon/daemon_windows_test.go
@@ -0,0 +1,72 @@
+// +build windows
+
+package daemon
+
+import (
+	"strings"
+	"testing"
+
+	"golang.org/x/sys/windows/svc/mgr"
+)
+
+const existingService = "Power"
+
+func TestEnsureServicesExist(t *testing.T) {
+	m, err := mgr.Connect()
+	if err != nil {
+		t.Fatal("failed to connect to service manager, this test needs admin")
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(existingService)
+	if err != nil {
+		t.Fatalf("expected to find known inbox service %q, this test needs a known inbox service to run correctly", existingService)
+	}
+	defer s.Close()
+
+	input := []string{existingService}
+	err = ensureServicesInstalled(input)
+	if err != nil {
+		t.Fatalf("unexpected error for input %q: %q", input, err)
+	}
+}
+
+func TestEnsureServicesExistErrors(t *testing.T) {
+	m, err := mgr.Connect()
+	if err != nil {
+		t.Fatal("failed to connect to service manager, this test needs admin")
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(existingService)
+	if err != nil {
+		t.Fatalf("expected to find known inbox service %q, this test needs a known inbox service to run correctly", existingService)
+	}
+	defer s.Close()
+
+	for _, testcase := range []struct {
+		input         []string
+		expectedError string
+	}{
+		{
+			input:         []string{"daemon_windows_test_fakeservice"},
+			expectedError: "failed to open service daemon_windows_test_fakeservice",
+		},
+		{
+			input:         []string{"daemon_windows_test_fakeservice1", "daemon_windows_test_fakeservice2"},
+			expectedError: "failed to open service daemon_windows_test_fakeservice1",
+		},
+		{
+			input:         []string{existingService, "daemon_windows_test_fakeservice"},
+			expectedError: "failed to open service daemon_windows_test_fakeservice",
+		},
+	} {
+		t.Run(strings.Join(testcase.input, ";"), func(t *testing.T) {
+			err := ensureServicesInstalled(testcase.input)
+			if err == nil {
+				t.Fatalf("expected error for input %v", testcase.input)
+			}
+			if !strings.Contains(err.Error(), testcase.expectedError) {
+				t.Fatalf("expected error %q to contain %q", err.Error(), testcase.expectedError)
+			}
+		})
+	}
+}
diff --git a/daemon/debugtrap_unix.go b/daemon/debugtrap_unix.go
index 39298df..8ea696d 100644
--- a/daemon/debugtrap_unix.go
+++ b/daemon/debugtrap_unix.go
@@ -6,8 +6,8 @@
 	"os"
 	"os/signal"
 
-	"github.com/Sirupsen/logrus"
 	stackdump "github.com/docker/docker/pkg/signal"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/debugtrap_windows.go b/daemon/debugtrap_windows.go
index dfaf953..f7d95c0 100644
--- a/daemon/debugtrap_windows.go
+++ b/daemon/debugtrap_windows.go
@@ -6,9 +6,8 @@
 	"unsafe"
 
 	winio "github.com/Microsoft/go-winio"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/signal"
-	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/windows"
 )
 
@@ -16,7 +15,7 @@
 	// Windows does not support signals like *nix systems. So instead of
 	// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
 	// signaled. ACL'd to builtin administrators and local system
-	ev := "Global\\docker-daemon-" + fmt.Sprint(os.Getpid())
+	ev, _ := windows.UTF16PtrFromString("Global\\docker-daemon-" + fmt.Sprint(os.Getpid()))
 	sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
 	if err != nil {
 		logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", ev, err.Error())
@@ -26,7 +25,7 @@
 	sa.Length = uint32(unsafe.Sizeof(sa))
 	sa.InheritHandle = 1
 	sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
-	h, err := system.CreateEvent(&sa, false, false, ev)
+	h, err := windows.CreateEvent(&sa, 0, 0, ev)
 	if h == 0 || err != nil {
 		logrus.Errorf("failed to create debug stackdump event %s: %s", ev, err.Error())
 		return
diff --git a/daemon/delete.go b/daemon/delete.go
index 61ee6eb..99b515d 100644
--- a/daemon/delete.go
+++ b/daemon/delete.go
@@ -7,14 +7,13 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
-	apierrors "github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/system"
 	volumestore "github.com/docker/docker/volume/store"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerRm removes the container id from the filesystem. An error
@@ -31,7 +30,7 @@
 	// Container state RemovalInProgress should be used to avoid races.
 	if inProgress := container.SetRemovalInProgress(); inProgress {
 		err := fmt.Errorf("removal of container %s is already in progress", name)
-		return apierrors.NewBadRequestError(err)
+		return stateConflictError{err}
 	}
 	defer container.ResetRemovalInProgress()
 
@@ -87,7 +86,7 @@
 				procedure = "Unpause and then " + strings.ToLower(procedure)
 			}
 			err := fmt.Errorf("You cannot remove a %s container %s. %s", state, container.ID, procedure)
-			return apierrors.NewRequestConflictError(err)
+			return stateConflictError{err}
 		}
 		if err := daemon.Kill(container); err != nil {
 			return fmt.Errorf("Could not kill running container %s, cannot remove - %v", container.ID, err)
@@ -128,7 +127,7 @@
 		return errors.Wrapf(err, "unable to remove filesystem for %s", container.ID)
 	}
 
-	daemon.linkIndex.delete(container)
+	linkNames := daemon.linkIndex.delete(container)
 	selinuxFreeLxcContexts(container.ProcessLabel)
 	daemon.idIndex.Delete(container.ID)
 	daemon.containers.Delete(container.ID)
@@ -136,6 +135,9 @@
 	if e := daemon.removeMountPoints(container, removeVolume); e != nil {
 		logrus.Error(e)
 	}
+	for _, name := range linkNames {
+		daemon.releaseName(name)
+	}
 	container.SetRemoved()
 	stateCtr.del(container.ID)
 	daemon.LogContainerEvent(container, "destroy")
@@ -148,7 +150,7 @@
 func (daemon *Daemon) VolumeRm(name string, force bool) error {
 	err := daemon.volumeRm(name)
 	if err != nil && volumestore.IsInUse(err) {
-		return apierrors.NewRequestConflictError(err)
+		return stateConflictError{err}
 	}
 	if err == nil || force {
 		daemon.volumes.Purge(name)
diff --git a/daemon/delete_test.go b/daemon/delete_test.go
index f1a9790..887fa53 100644
--- a/daemon/delete_test.go
+++ b/daemon/delete_test.go
@@ -9,7 +9,7 @@
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
-	"github.com/docker/docker/pkg/testutil"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/daemon/discovery/discovery.go b/daemon/discovery/discovery.go
index 509155c..4b1b15f 100644
--- a/daemon/discovery/discovery.go
+++ b/daemon/discovery/discovery.go
@@ -6,8 +6,8 @@
 	"strconv"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
+	"github.com/sirupsen/logrus"
 
 	// Register the libkv backends for discovery.
 	_ "github.com/docker/docker/pkg/discovery/kv"
diff --git a/daemon/discovery/discovery_test.go b/daemon/discovery/discovery_test.go
index f084a64..d5c9966 100644
--- a/daemon/discovery/discovery_test.go
+++ b/daemon/discovery/discovery_test.go
@@ -4,92 +4,77 @@
 	"fmt"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
+func TestDiscoveryOptsErrors(t *testing.T) {
+	var testcases = []struct {
+		doc  string
+		opts map[string]string
+	}{
+		{
+			doc:  "discovery.ttl < discovery.heartbeat",
+			opts: map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "5"},
+		},
+		{
+			doc:  "discovery.ttl == discovery.heartbeat",
+			opts: map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "10"},
+		},
+		{
+			doc:  "negative discovery.heartbeat",
+			opts: map[string]string{"discovery.heartbeat": "-10", "discovery.ttl": "10"},
+		},
+		{
+			doc:  "negative discovery.ttl",
+			opts: map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "-10"},
+		},
+		{
+			doc:  "invalid discovery.heartbeat",
+			opts: map[string]string{"discovery.heartbeat": "invalid"},
+		},
+		{
+			doc:  "invalid discovery.ttl",
+			opts: map[string]string{"discovery.ttl": "invalid"},
+		},
+	}
+
+	for _, testcase := range testcases {
+		_, _, err := discoveryOpts(testcase.opts)
+		assert.Error(t, err, testcase.doc)
+	}
+}
+
 func TestDiscoveryOpts(t *testing.T) {
-	clusterOpts := map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "5"}
+	clusterOpts := map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "20"}
 	heartbeat, ttl, err := discoveryOpts(clusterOpts)
-	if err == nil {
-		t.Fatal("discovery.ttl < discovery.heartbeat must fail")
-	}
-
-	clusterOpts = map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "10"}
-	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err == nil {
-		t.Fatal("discovery.ttl == discovery.heartbeat must fail")
-	}
-
-	clusterOpts = map[string]string{"discovery.heartbeat": "-10", "discovery.ttl": "10"}
-	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err == nil {
-		t.Fatal("negative discovery.heartbeat must fail")
-	}
-
-	clusterOpts = map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "-10"}
-	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err == nil {
-		t.Fatal("negative discovery.ttl must fail")
-	}
-
-	clusterOpts = map[string]string{"discovery.heartbeat": "invalid"}
-	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err == nil {
-		t.Fatal("invalid discovery.heartbeat must fail")
-	}
-
-	clusterOpts = map[string]string{"discovery.ttl": "invalid"}
-	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err == nil {
-		t.Fatal("invalid discovery.ttl must fail")
-	}
-
-	clusterOpts = map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "20"}
-	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if heartbeat != 10*time.Second {
-		t.Fatalf("Heartbeat - Expected : %v, Actual : %v", 10*time.Second, heartbeat)
-	}
-
-	if ttl != 20*time.Second {
-		t.Fatalf("TTL - Expected : %v, Actual : %v", 20*time.Second, ttl)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, 10*time.Second, heartbeat)
+	assert.Equal(t, 20*time.Second, ttl)
 
 	clusterOpts = map[string]string{"discovery.heartbeat": "10"}
 	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if heartbeat != 10*time.Second {
-		t.Fatalf("Heartbeat - Expected : %v, Actual : %v", 10*time.Second, heartbeat)
-	}
-
-	expected := 10 * defaultDiscoveryTTLFactor * time.Second
-	if ttl != expected {
-		t.Fatalf("TTL - Expected : %v, Actual : %v", expected, ttl)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, 10*time.Second, heartbeat)
+	assert.Equal(t, 10*defaultDiscoveryTTLFactor*time.Second, ttl)
 
 	clusterOpts = map[string]string{"discovery.ttl": "30"}
 	heartbeat, ttl, err = discoveryOpts(clusterOpts)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	if ttl != 30*time.Second {
 		t.Fatalf("TTL - Expected : %v, Actual : %v", 30*time.Second, ttl)
 	}
 
-	expected = 30 * time.Second / defaultDiscoveryTTLFactor
+	expected := 30 * time.Second / defaultDiscoveryTTLFactor
 	if heartbeat != expected {
 		t.Fatalf("Heartbeat - Expected : %v, Actual : %v", expected, heartbeat)
 	}
 
 	discoveryTTL := fmt.Sprintf("%d", defaultDiscoveryTTLFactor-1)
 	clusterOpts = map[string]string{"discovery.ttl": discoveryTTL}
-	heartbeat, ttl, err = discoveryOpts(clusterOpts)
+	heartbeat, _, err = discoveryOpts(clusterOpts)
 	if err == nil && heartbeat == 0 {
 		t.Fatal("discovery.heartbeat must be positive")
 	}
diff --git a/daemon/disk_usage.go b/daemon/disk_usage.go
index c64a243..7142ef0 100644
--- a/daemon/disk_usage.go
+++ b/daemon/disk_usage.go
@@ -6,13 +6,13 @@
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/directory"
 	"github.com/docker/docker/volume"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 )
 
 func (daemon *Daemon) getLayerRefs(platform string) map[layer.ChainID]int {
@@ -20,7 +20,7 @@
 	layerRefs := map[layer.ChainID]int{}
 	for id, img := range tmpImages {
 		dgst := digest.Digest(id)
-		if len(daemon.stores[platform].referenceStore.References(dgst)) == 0 && len(daemon.stores[platform].imageStore.Children(id)) != 0 {
+		if len(daemon.referenceStore.References(dgst)) == 0 && len(daemon.stores[platform].imageStore.Children(id)) != 0 {
 			continue
 		}
 
@@ -99,7 +99,6 @@
 	for platform := range daemon.stores {
 		layerRefs := daemon.getLayerRefs(platform)
 		allLayers := daemon.stores[platform].layerStore.Map()
-		var allLayersSize int64
 		for _, l := range allLayers {
 			select {
 			case <-ctx.Done():
diff --git a/daemon/errors.go b/daemon/errors.go
index 5050f87..cd8de4d 100644
--- a/daemon/errors.go
+++ b/daemon/errors.go
@@ -2,52 +2,215 @@
 
 import (
 	"fmt"
+	"strings"
+	"syscall"
 
-	"github.com/docker/docker/api/errors"
+	"github.com/pkg/errors"
+	"google.golang.org/grpc"
 )
 
-func (d *Daemon) imageNotExistToErrcode(err error) error {
-	if dne, isDNE := err.(ErrImageDoesNotExist); isDNE {
-		return errors.NewRequestNotFoundError(dne)
-	}
-	return err
+func errNotRunning(id string) error {
+	return stateConflictError{errors.Errorf("Container %s is not running", id)}
 }
 
-type errNotRunning struct {
-	containerID string
+func containerNotFound(id string) error {
+	return objNotFoundError{"container", id}
 }
 
-func (e errNotRunning) Error() string {
-	return fmt.Sprintf("Container %s is not running", e.containerID)
+func volumeNotFound(id string) error {
+	return objNotFoundError{"volume", id}
 }
 
-func (e errNotRunning) ContainerIsRunning() bool {
-	return false
+func networkNotFound(id string) error {
+	return objNotFoundError{"network", id}
 }
 
+type objNotFoundError struct {
+	object string
+	id     string
+}
+
+func (e objNotFoundError) Error() string {
+	return "No such " + e.object + ": " + e.id
+}
+
+func (e objNotFoundError) NotFound() {}
+
+type stateConflictError struct {
+	cause error
+}
+
+func (e stateConflictError) Error() string {
+	return e.cause.Error()
+}
+
+func (e stateConflictError) Cause() error {
+	return e.cause
+}
+
+func (e stateConflictError) Conflict() {}
+
 func errContainerIsRestarting(containerID string) error {
-	err := fmt.Errorf("Container %s is restarting, wait until the container is running", containerID)
-	return errors.NewRequestConflictError(err)
+	cause := errors.Errorf("Container %s is restarting, wait until the container is running", containerID)
+	return stateConflictError{cause}
 }
 
 func errExecNotFound(id string) error {
-	err := fmt.Errorf("No such exec instance '%s' found in daemon", id)
-	return errors.NewRequestNotFoundError(err)
+	return objNotFoundError{"exec instance", id}
 }
 
 func errExecPaused(id string) error {
-	err := fmt.Errorf("Container %s is paused, unpause the container before exec", id)
-	return errors.NewRequestConflictError(err)
+	cause := errors.Errorf("Container %s is paused, unpause the container before exec", id)
+	return stateConflictError{cause}
 }
 
-type errNotFound struct {
-	containerID string
+type validationError struct {
+	cause error
 }
 
-func (e errNotFound) Error() string {
-	return fmt.Sprintf("Container %s is not found", e.containerID)
+func (e validationError) Error() string {
+	return e.cause.Error()
 }
 
-func (e errNotFound) ContainerNotFound() bool {
-	return true
+func (e validationError) InvalidParameter() {}
+
+func (e validationError) Cause() error {
+	return e.cause
+}
+
+type notAllowedError struct {
+	cause error
+}
+
+func (e notAllowedError) Error() string {
+	return e.cause.Error()
+}
+
+func (e notAllowedError) Forbidden() {}
+
+func (e notAllowedError) Cause() error {
+	return e.cause
+}
+
+type containerNotModifiedError struct {
+	running bool
+}
+
+func (e containerNotModifiedError) Error() string {
+	if e.running {
+		return "Container is already started"
+	}
+	return "Container is already stopped"
+}
+
+func (e containerNotModifiedError) NotModified() {}
+
+type systemError struct {
+	cause error
+}
+
+func (e systemError) Error() string {
+	return e.cause.Error()
+}
+
+func (e systemError) SystemError() {}
+
+func (e systemError) Cause() error {
+	return e.cause
+}
+
+type invalidIdentifier string
+
+func (e invalidIdentifier) Error() string {
+	return fmt.Sprintf("invalid name or ID supplied: %q", string(e))
+}
+
+func (invalidIdentifier) InvalidParameter() {}
+
+type duplicateMountPointError string
+
+func (e duplicateMountPointError) Error() string {
+	return "Duplicate mount point: " + string(e)
+}
+func (duplicateMountPointError) InvalidParameter() {}
+
+type containerFileNotFound struct {
+	file      string
+	container string
+}
+
+func (e containerFileNotFound) Error() string {
+	return "Could not find the file " + e.file + " in container " + e.container
+}
+
+func (containerFileNotFound) NotFound() {}
+
+type invalidFilter struct {
+	filter string
+	value  interface{}
+}
+
+func (e invalidFilter) Error() string {
+	msg := "Invalid filter '" + e.filter
+	if e.value != nil {
+		msg += fmt.Sprintf("=%s", e.value)
+	}
+	return msg + "'"
+}
+
+func (e invalidFilter) InvalidParameter() {}
+
+type unknownError struct {
+	cause error
+}
+
+func (e unknownError) Error() string {
+	return e.cause.Error()
+}
+
+func (unknownError) Unknown() {}
+
+func (e unknownError) Cause() error {
+	return e.cause
+}
+
+type startInvalidConfigError string
+
+func (e startInvalidConfigError) Error() string {
+	return string(e)
+}
+
+func (e startInvalidConfigError) InvalidParameter() {} // Is this right???
+
+func translateContainerdStartErr(cmd string, setExitCode func(int), err error) error {
+	errDesc := grpc.ErrorDesc(err)
+	contains := func(s1, s2 string) bool {
+		return strings.Contains(strings.ToLower(s1), s2)
+	}
+	var retErr error = unknownError{errors.New(errDesc)}
+	// if we receive an internal error from the initial start of a container then lets
+	// return it instead of entering the restart loop
+	// set to 127 for container cmd not found/does not exist)
+	if contains(errDesc, cmd) &&
+		(contains(errDesc, "executable file not found") ||
+			contains(errDesc, "no such file or directory") ||
+			contains(errDesc, "system cannot find the file specified")) {
+		setExitCode(127)
+		retErr = startInvalidConfigError(errDesc)
+	}
+	// set to 126 for container cmd can't be invoked errors
+	if contains(errDesc, syscall.EACCES.Error()) {
+		setExitCode(126)
+		retErr = startInvalidConfigError(errDesc)
+	}
+
+	// attempted to mount a file onto a directory, or a directory onto a file, maybe from user specified bind mounts
+	if contains(errDesc, syscall.ENOTDIR.Error()) {
+		errDesc += ": Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type"
+		setExitCode(127)
+		retErr = startInvalidConfigError(errDesc)
+	}
+
+	// TODO: it would be nice to get some better errors from containerd so we can return better errors here
+	return retErr
 }
diff --git a/daemon/events.go b/daemon/events.go
index 7ae8518..e302a4f 100644
--- a/daemon/events.go
+++ b/daemon/events.go
@@ -6,7 +6,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/events"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/container"
@@ -14,6 +13,7 @@
 	"github.com/docker/libnetwork"
 	swarmapi "github.com/docker/swarmkit/api"
 	gogotypes "github.com/gogo/protobuf/types"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/daemon/events/filter.go b/daemon/events/filter.go
index 645f1ca..61e3459 100644
--- a/daemon/events/filter.go
+++ b/daemon/events/filter.go
@@ -27,6 +27,10 @@
 		ef.matchVolume(ev) &&
 		ef.matchNetwork(ev) &&
 		ef.matchImage(ev) &&
+		ef.matchNode(ev) &&
+		ef.matchService(ev) &&
+		ef.matchSecret(ev) &&
+		ef.matchConfig(ev) &&
 		ef.matchLabels(ev.Actor.Attributes)
 }
 
@@ -49,14 +53,14 @@
 }
 
 func (ef *Filter) matchScope(scope string) bool {
-	if !ef.filter.Include("scope") {
+	if !ef.filter.Contains("scope") {
 		return true
 	}
 	return ef.filter.ExactMatch("scope", scope)
 }
 
 func (ef *Filter) matchLabels(attributes map[string]string) bool {
-	if !ef.filter.Include("label") {
+	if !ef.filter.Contains("label") {
 		return true
 	}
 	return ef.filter.MatchKVList("label", attributes)
diff --git a/daemon/exec.go b/daemon/exec.go
index 72d01c8..9b3e583 100644
--- a/daemon/exec.go
+++ b/daemon/exec.go
@@ -8,8 +8,6 @@
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/strslice"
 	"github.com/docker/docker/container"
@@ -19,6 +17,8 @@
 	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/signal"
 	"github.com/docker/docker/pkg/term"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // Seconds to wait after sending TERM before trying KILL
@@ -81,7 +81,7 @@
 	}
 
 	if !container.IsRunning() {
-		return nil, errNotRunning{container.ID}
+		return nil, errNotRunning(container.ID)
 	}
 	if container.IsPaused() {
 		return nil, errExecPaused(name)
@@ -142,7 +142,7 @@
 // ContainerExecStart starts a previously set up exec instance. The
 // std streams are set up.
 // If ctx is cancelled, the process is terminated.
-func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) (err error) {
+func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (err error) {
 	var (
 		cStdin           io.ReadCloser
 		cStdout, cStderr io.Writer
@@ -157,12 +157,12 @@
 	if ec.ExitCode != nil {
 		ec.Unlock()
 		err := fmt.Errorf("Error: Exec command %s has already run", ec.ID)
-		return errors.NewRequestConflictError(err)
+		return stateConflictError{err}
 	}
 
 	if ec.Running {
 		ec.Unlock()
-		return fmt.Errorf("Error: Exec command %s is already running", ec.ID)
+		return stateConflictError{fmt.Errorf("Error: Exec command %s is already running", ec.ID)}
 	}
 	ec.Running = true
 	ec.Unlock()
@@ -233,7 +233,7 @@
 
 	systemPid, err := d.containerd.AddProcess(ctx, c.ID, name, p, ec.InitializeStdio)
 	if err != nil {
-		return err
+		return translateContainerdStartErr(ec.Entrypoint, ec.SetExitCode, err)
 	}
 	ec.Lock()
 	ec.Pid = systemPid
@@ -254,7 +254,7 @@
 	case err := <-attachErr:
 		if err != nil {
 			if _, ok := err.(term.EscapeError); !ok {
-				return fmt.Errorf("exec attach failed with error: %v", err)
+				return errors.Wrap(systemError{err}, "exec attach failed")
 			}
 			d.LogContainerEvent(c, "exec_detach")
 		}
diff --git a/daemon/exec/exec.go b/daemon/exec/exec.go
index 933136f..f4efb4d 100644
--- a/daemon/exec/exec.go
+++ b/daemon/exec/exec.go
@@ -4,10 +4,10 @@
 	"runtime"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container/stream"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/sirupsen/logrus"
 )
 
 // Config holds the configurations for execs. The Daemon keeps
@@ -62,6 +62,11 @@
 	return c.StreamConfig.CloseStreams()
 }
 
+// SetExitCode sets the exec config's exit code
+func (c *Config) SetExitCode(code int) {
+	c.ExitCode = &code
+}
+
 // Store keeps track of the exec configurations.
 type Store struct {
 	commands map[string]*Config
@@ -70,7 +75,7 @@
 
 // NewStore initializes a new exec store.
 func NewStore() *Store {
-	return &Store{commands: make(map[string]*Config, 0)}
+	return &Store{commands: make(map[string]*Config)}
 }
 
 // Commands returns the exec configurations in the store.
diff --git a/daemon/export.go b/daemon/export.go
index 402e675..465ccac 100644
--- a/daemon/export.go
+++ b/daemon/export.go
@@ -13,15 +13,25 @@
 // ContainerExport writes the contents of the container to the given
 // writer. An error is returned if the container cannot be found.
 func (daemon *Daemon) ContainerExport(name string, out io.Writer) error {
-	if runtime.GOOS == "windows" {
-		return fmt.Errorf("the daemon on this platform does not support export of a container")
-	}
-
 	container, err := daemon.GetContainer(name)
 	if err != nil {
 		return err
 	}
 
+	if runtime.GOOS == "windows" && container.Platform == "windows" {
+		return fmt.Errorf("the daemon on this platform does not support exporting Windows containers")
+	}
+
+	if container.IsDead() {
+		err := fmt.Errorf("You cannot export container %s which is Dead", container.ID)
+		return stateConflictError{err}
+	}
+
+	if container.IsRemovalInProgress() {
+		err := fmt.Errorf("You cannot export container %s which is being removed", container.ID)
+		return stateConflictError{err}
+	}
+
 	data, err := daemon.containerExport(container)
 	if err != nil {
 		return fmt.Errorf("Error exporting container %s: %v", name, err)
@@ -35,23 +45,35 @@
 	return nil
 }
 
-func (daemon *Daemon) containerExport(container *container.Container) (io.ReadCloser, error) {
-	if err := daemon.Mount(container); err != nil {
+func (daemon *Daemon) containerExport(container *container.Container) (arch io.ReadCloser, err error) {
+	rwlayer, err := daemon.stores[container.Platform].layerStore.GetRWLayer(container.ID)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err != nil {
+			daemon.stores[container.Platform].layerStore.ReleaseRWLayer(rwlayer)
+		}
+	}()
+
+	_, err = rwlayer.Mount(container.GetMountLabel())
+	if err != nil {
 		return nil, err
 	}
 
-	archive, err := archive.TarWithOptions(container.BaseFS, &archive.TarOptions{
+	archive, err := archivePath(container.BaseFS, container.BaseFS.Path(), &archive.TarOptions{
 		Compression: archive.Uncompressed,
 		UIDMaps:     daemon.idMappings.UIDs(),
 		GIDMaps:     daemon.idMappings.GIDs(),
 	})
 	if err != nil {
-		daemon.Unmount(container)
+		rwlayer.Unmount()
 		return nil, err
 	}
-	arch := ioutils.NewReadCloserWrapper(archive, func() error {
+	arch = ioutils.NewReadCloserWrapper(archive, func() error {
 		err := archive.Close()
-		daemon.Unmount(container)
+		rwlayer.Unmount()
+		daemon.stores[container.Platform].layerStore.ReleaseRWLayer(rwlayer)
 		return err
 	})
 	daemon.LogContainerEvent(container, "export")
diff --git a/daemon/getsize_unix.go b/daemon/getsize_unix.go
index 434fa43..e47e646 100644
--- a/daemon/getsize_unix.go
+++ b/daemon/getsize_unix.go
@@ -5,7 +5,7 @@
 import (
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // getSize returns the real size & virtual size of the container.
diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go
index c099b88..8313263 100644
--- a/daemon/graphdriver/aufs/aufs.go
+++ b/daemon/graphdriver/aufs/aufs.go
@@ -35,10 +35,10 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/chrootarchive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/directory"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/locker"
@@ -47,6 +47,7 @@
 	rsystem "github.com/opencontainers/runc/libcontainer/system"
 	"github.com/opencontainers/selinux/go-selinux/label"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"github.com/vbatts/tar-split/tar/storage"
 	"golang.org/x/sys/unix"
 )
@@ -141,6 +142,30 @@
 			return nil, err
 		}
 	}
+	logger := logrus.WithFields(logrus.Fields{
+		"module": "graphdriver",
+		"driver": "aufs",
+	})
+
+	for _, path := range []string{"mnt", "diff"} {
+		p := filepath.Join(root, path)
+		entries, err := ioutil.ReadDir(p)
+		if err != nil {
+			logger.WithError(err).WithField("dir", p).Error("error reading dir entries")
+			continue
+		}
+		for _, entry := range entries {
+			if !entry.IsDir() {
+				continue
+			}
+			if strings.HasSuffix(entry.Name(), "-removing") {
+				logger.WithField("dir", entry.Name()).Debug("Cleaning up stale layer dir")
+				if err := system.EnsureRemoveAll(filepath.Join(p, entry.Name())); err != nil {
+					logger.WithField("dir", entry.Name()).WithError(err).Error("Error removing stale layer dir")
+				}
+			}
+		}
+	}
 
 	a.naiveDiff = graphdriver.NewNaiveDiffDriver(a, uidMaps, gidMaps)
 	return a, nil
@@ -317,26 +342,6 @@
 		retries++
 		logger.Warnf("unmount failed due to EBUSY: retry count: %d", retries)
 		time.Sleep(100 * time.Millisecond)
-		continue
-	}
-
-	// Atomically remove each directory in turn by first moving it out of the
-	// way (so that docker doesn't find it anymore) before doing removal of
-	// the whole tree.
-	tmpMntPath := path.Join(a.mntPath(), fmt.Sprintf("%s-removing", id))
-	if err := os.Rename(mountpoint, tmpMntPath); err != nil && !os.IsNotExist(err) {
-		if err == unix.EBUSY {
-			logger.WithField("dir", mountpoint).WithError(err).Warn("os.Rename err due to EBUSY")
-		}
-		return errors.Wrapf(err, "error preparing atomic delete of aufs mountpoint for id: %s", id)
-	}
-	if err := system.EnsureRemoveAll(tmpMntPath); err != nil {
-		return errors.Wrapf(err, "error removing aufs layer %s", id)
-	}
-
-	tmpDiffpath := path.Join(a.diffPath(), fmt.Sprintf("%s-removing", id))
-	if err := os.Rename(a.getDiffPath(id), tmpDiffpath); err != nil && !os.IsNotExist(err) {
-		return errors.Wrapf(err, "error preparing atomic delete of aufs diff dir for id: %s", id)
 	}
 
 	// Remove the layers file for the id
@@ -344,20 +349,52 @@
 		return errors.Wrapf(err, "error removing layers dir for %s", id)
 	}
 
+	if err := atomicRemove(a.getDiffPath(id)); err != nil {
+		return errors.Wrapf(err, "could not remove diff path for id %s", id)
+	}
+
+	// Atomically remove each directory in turn by first moving it out of the
+	// way (so that docker doesn't find it anymore) before doing removal of
+	// the whole tree.
+	if err := atomicRemove(mountpoint); err != nil {
+		if errors.Cause(err) == unix.EBUSY {
+			logger.WithField("dir", mountpoint).WithError(err).Warn("error performing atomic remove due to EBUSY")
+		}
+		return errors.Wrapf(err, "could not remove mountpoint for id %s", id)
+	}
+
 	a.pathCacheLock.Lock()
 	delete(a.pathCache, id)
 	a.pathCacheLock.Unlock()
 	return nil
 }
 
+func atomicRemove(source string) error {
+	target := source + "-removing"
+
+	err := os.Rename(source, target)
+	switch {
+	case err == nil, os.IsNotExist(err):
+	case os.IsExist(err):
+		// Got error saying the target dir already exists, maybe the source doesn't exist due to a previous (failed) remove
+		if _, e := os.Stat(source); !os.IsNotExist(e) {
+			return errors.Wrapf(err, "target rename dir '%s' exists but should not, this needs to be manually cleaned up")
+		}
+	default:
+		return errors.Wrapf(err, "error preparing atomic delete")
+	}
+
+	return system.EnsureRemoveAll(target)
+}
+
 // Get returns the rootfs path for the id.
 // This will mount the dir at its given path
-func (a *Driver) Get(id, mountLabel string) (string, error) {
+func (a *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	a.locker.Lock(id)
 	defer a.locker.Unlock(id)
 	parents, err := a.getParentLayerPaths(id)
 	if err != nil && !os.IsNotExist(err) {
-		return "", err
+		return nil, err
 	}
 
 	a.pathCacheLock.Lock()
@@ -371,21 +408,21 @@
 		}
 	}
 	if count := a.ctr.Increment(m); count > 1 {
-		return m, nil
+		return containerfs.NewLocalContainerFS(m), nil
 	}
 
 	// If a dir does not have a parent ( no layers )do not try to mount
 	// just return the diff path to the data
 	if len(parents) > 0 {
 		if err := a.mount(id, m, mountLabel, parents); err != nil {
-			return "", err
+			return nil, err
 		}
 	}
 
 	a.pathCacheLock.Lock()
 	a.pathCache[id] = m
 	a.pathCacheLock.Unlock()
-	return m, nil
+	return containerfs.NewLocalContainerFS(m), nil
 }
 
 // Put unmounts and updates list of active mounts.
diff --git a/daemon/graphdriver/aufs/aufs_test.go b/daemon/graphdriver/aufs/aufs_test.go
index baf0fd8..a58f18a 100644
--- a/daemon/graphdriver/aufs/aufs_test.go
+++ b/daemon/graphdriver/aufs/aufs_test.go
@@ -9,6 +9,7 @@
 	"io/ioutil"
 	"os"
 	"path"
+	"path/filepath"
 	"sync"
 	"testing"
 
@@ -16,6 +17,8 @@
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 var (
@@ -39,6 +42,14 @@
 	return d
 }
 
+func driverGet(d *Driver, id string, mntLabel string) (string, error) {
+	mnt, err := d.Get(id, mntLabel)
+	if err != nil {
+		return "", err
+	}
+	return mnt.Path(), nil
+}
+
 func newDriver(t testing.TB) *Driver {
 	if err := os.MkdirAll(tmp, 0755); err != nil {
 		t.Fatal(err)
@@ -147,7 +158,10 @@
 
 	for _, p := range paths {
 		if _, err := os.Stat(path.Join(tmp, p, "1")); err == nil {
-			t.Fatalf("Error should not be nil because dirs with id 1 should be delted: %s", p)
+			t.Fatalf("Error should not be nil because dirs with id 1 should be deleted: %s", p)
+		}
+		if _, err := os.Stat(path.Join(tmp, p, "1-removing")); err == nil {
+			t.Fatalf("Error should not be nil because dirs with id 1-removing should be deleted: %s", p)
 		}
 	}
 }
@@ -165,7 +179,7 @@
 		t.Fatal(err)
 	}
 	expected := path.Join(tmp, "diff", "1")
-	if diffPath != expected {
+	if diffPath.Path() != expected {
 		t.Fatalf("Expected path %s got %s", expected, diffPath)
 	}
 }
@@ -174,9 +188,8 @@
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Cleanup(); err != nil {
-		t.Fatal(err)
-	}
+	err := d.Cleanup()
+	assert.NoError(t, err)
 }
 
 func TestCleanupWithDir(t *testing.T) {
@@ -196,18 +209,12 @@
 	d := newDriver(t)
 	defer os.RemoveAll(tmp)
 
-	if err := d.Create("1", "", nil); err != nil {
-		t.Fatal(err)
-	}
+	err := d.Create("1", "", nil)
+	require.NoError(t, err)
 
 	response, err := d.mounted(d.getDiffPath("1"))
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if response != false {
-		t.Fatal("Response if dir id 1 is mounted should be false")
-	}
+	require.NoError(t, err)
+	assert.False(t, response)
 }
 
 func TestMountedTrueResponse(t *testing.T) {
@@ -215,26 +222,17 @@
 	defer os.RemoveAll(tmp)
 	defer d.Cleanup()
 
-	if err := d.Create("1", "", nil); err != nil {
-		t.Fatal(err)
-	}
-	if err := d.Create("2", "1", nil); err != nil {
-		t.Fatal(err)
-	}
+	err := d.Create("1", "", nil)
+	require.NoError(t, err)
+	err = d.Create("2", "1", nil)
+	require.NoError(t, err)
 
-	_, err := d.Get("2", "")
-	if err != nil {
-		t.Fatal(err)
-	}
+	_, err = d.Get("2", "")
+	require.NoError(t, err)
 
 	response, err := d.mounted(d.pathCache["2"])
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if response != true {
-		t.Fatal("Response if dir id 2 is mounted should be true")
-	}
+	require.NoError(t, err)
+	assert.True(t, response)
 }
 
 func TestMountWithParent(t *testing.T) {
@@ -258,13 +256,13 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if mntPath == "" {
-		t.Fatal("mntPath should not be empty string")
+	if mntPath == nil {
+		t.Fatal("mntPath should not be nil")
 	}
 
 	expected := path.Join(tmp, "mnt", "2")
-	if mntPath != expected {
-		t.Fatalf("Expected %s got %s", expected, mntPath)
+	if mntPath.Path() != expected {
+		t.Fatalf("Expected %s got %s", expected, mntPath.Path())
 	}
 }
 
@@ -289,8 +287,8 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if mntPath == "" {
-		t.Fatal("mntPath should not be empty string")
+	if mntPath == nil {
+		t.Fatal("mntPath should not be nil")
 	}
 
 	mounted, err := d.mounted(d.pathCache["2"])
@@ -324,7 +322,7 @@
 		t.Fatal(err)
 	}
 
-	diffPath, err := d.Get("1", "")
+	diffPath, err := driverGet(d, "1", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -368,7 +366,7 @@
 		}
 	}()
 
-	mntPoint, err := d.Get("2", "")
+	mntPoint, err := driverGet(d, "2", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -407,7 +405,7 @@
 	if err := d.CreateReadWrite("3", "2", nil); err != nil {
 		t.Fatal(err)
 	}
-	mntPoint, err = d.Get("3", "")
+	mntPoint, err = driverGet(d, "3", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -453,7 +451,7 @@
 		t.Fatal(err)
 	}
 
-	diffPath, err := d.Get("1", "")
+	diffPath, err := driverGet(d, "1", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -495,7 +493,7 @@
 		t.Fatal(err)
 	}
 
-	diffPath, err := d.Get("1", "")
+	diffPath, err := driverGet(d, "1", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -569,9 +567,8 @@
 	}
 
 	status := d.Status()
-	if status == nil || len(status) == 0 {
-		t.Fatal("Status should not be nil or empty")
-	}
+	assert.Len(t, status, 4)
+
 	rootDir := status[0]
 	dirs := status[2]
 	if rootDir[0] != "Root Dir" {
@@ -597,7 +594,7 @@
 		t.Fatal(err)
 	}
 
-	diffPath, err := d.Get("1", "")
+	diffPath, err := driverGet(d, "1", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -632,7 +629,7 @@
 
 	// Ensure that the file is in the mount point for id 3
 
-	mountPoint, err := d.Get("3", "")
+	mountPoint, err := driverGet(d, "3", "")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -672,48 +669,34 @@
 		}
 		current = hash(current)
 
-		if err := d.CreateReadWrite(current, parent, nil); err != nil {
-			t.Logf("Current layer %d", i)
-			t.Error(err)
-		}
-		point, err := d.Get(current, "")
-		if err != nil {
-			t.Logf("Current layer %d", i)
-			t.Error(err)
-		}
+		err := d.CreateReadWrite(current, parent, nil)
+		require.NoError(t, err, "current layer %d", i)
+
+		point, err := driverGet(d, current, "")
+		require.NoError(t, err, "current layer %d", i)
+
 		f, err := os.Create(path.Join(point, current))
-		if err != nil {
-			t.Logf("Current layer %d", i)
-			t.Error(err)
-		}
+		require.NoError(t, err, "current layer %d", i)
 		f.Close()
 
 		if i%10 == 0 {
-			if err := os.Remove(path.Join(point, parent)); err != nil {
-				t.Logf("Current layer %d", i)
-				t.Error(err)
-			}
+			err := os.Remove(path.Join(point, parent))
+			require.NoError(t, err, "current layer %d", i)
 			expected--
 		}
 		last = current
 	}
 
 	// Perform the actual mount for the top most image
-	point, err := d.Get(last, "")
-	if err != nil {
-		t.Error(err)
-	}
+	point, err := driverGet(d, last, "")
+	require.NoError(t, err)
 	files, err := ioutil.ReadDir(point)
-	if err != nil {
-		t.Error(err)
-	}
-	if len(files) != expected {
-		t.Errorf("Expected %d got %d", expected, len(files))
-	}
+	require.NoError(t, err)
+	assert.Len(t, files, expected)
 }
 
 func TestMountMoreThan42Layers(t *testing.T) {
-	os.RemoveAll(tmpOuter)
+	defer os.RemoveAll(tmpOuter)
 	testMountMoreThan42Layers(t, tmp)
 }
 
@@ -800,3 +783,23 @@
 		}
 	}
 }
+
+func TestInitStaleCleanup(t *testing.T) {
+	if err := os.MkdirAll(tmp, 0755); err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmp)
+
+	for _, d := range []string{"diff", "mnt"} {
+		if err := os.MkdirAll(filepath.Join(tmp, d, "123-removing"), 0755); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	testInit(tmp, t)
+	for _, d := range []string{"diff", "mnt"} {
+		if _, err := os.Stat(filepath.Join(tmp, d, "123-removing")); err == nil {
+			t.Fatal("cleanup failed")
+		}
+	}
+}
diff --git a/daemon/graphdriver/aufs/mount.go b/daemon/graphdriver/aufs/mount.go
index 890213b..100e753 100644
--- a/daemon/graphdriver/aufs/mount.go
+++ b/daemon/graphdriver/aufs/mount.go
@@ -5,7 +5,7 @@
 import (
 	"os/exec"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/graphdriver/btrfs/btrfs.go b/daemon/graphdriver/btrfs/btrfs.go
index 2599842..5a61217 100644
--- a/daemon/graphdriver/btrfs/btrfs.go
+++ b/daemon/graphdriver/btrfs/btrfs.go
@@ -26,14 +26,15 @@
 	"sync"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/go-units"
 	"github.com/opencontainers/selinux/go-selinux/label"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
@@ -631,29 +632,29 @@
 }
 
 // Get the requested filesystem id.
-func (d *Driver) Get(id, mountLabel string) (string, error) {
+func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	dir := d.subvolumesDirID(id)
 	st, err := os.Stat(dir)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 
 	if !st.IsDir() {
-		return "", fmt.Errorf("%s: not a directory", dir)
+		return nil, fmt.Errorf("%s: not a directory", dir)
 	}
 
 	if quota, err := ioutil.ReadFile(d.quotasDirID(id)); err == nil {
 		if size, err := strconv.ParseUint(string(quota), 10, 64); err == nil && size >= d.options.minSpace {
 			if err := d.subvolEnableQuota(); err != nil {
-				return "", err
+				return nil, err
 			}
 			if err := subvolLimitQgroup(dir, size); err != nil {
-				return "", err
+				return nil, err
 			}
 		}
 	}
 
-	return dir, nil
+	return containerfs.NewLocalContainerFS(dir), nil
 }
 
 // Put is not implemented for BTRFS as there is no cleanup required for the id.
diff --git a/daemon/graphdriver/btrfs/btrfs_test.go b/daemon/graphdriver/btrfs/btrfs_test.go
index 0038dbc..056b99b 100644
--- a/daemon/graphdriver/btrfs/btrfs_test.go
+++ b/daemon/graphdriver/btrfs/btrfs_test.go
@@ -35,12 +35,14 @@
 	}
 	defer graphtest.PutDriver(t)
 
-	dir, err := d.Get("test", "")
+	dirFS, err := d.Get("test", "")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer d.Put("test")
 
+	dir := dirFS.Path()
+
 	if err := subvolCreate(dir, "subvoltest"); err != nil {
 		t.Fatal(err)
 	}
diff --git a/daemon/graphdriver/devmapper/device_setup.go b/daemon/graphdriver/devmapper/device_setup.go
index ef6cffb..30463f2 100644
--- a/daemon/graphdriver/devmapper/device_setup.go
+++ b/daemon/graphdriver/devmapper/device_setup.go
@@ -12,8 +12,8 @@
 	"reflect"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 type directLVMConfig struct {
@@ -172,29 +172,18 @@
 }
 
 func setupDirectLVM(cfg directLVMConfig) error {
-	pvCreate, err := exec.LookPath("pvcreate")
-	if err != nil {
-		return errors.Wrap(err, "error looking up command `pvcreate` while setting up direct lvm")
+	lvmProfileDir := "/etc/lvm/profile"
+	binaries := []string{"pvcreate", "vgcreate", "lvcreate", "lvconvert", "lvchange", "thin_check"}
+
+	for _, bin := range binaries {
+		if _, err := exec.LookPath(bin); err != nil {
+			return errors.Wrap(err, "error looking up command `"+bin+"` while setting up direct lvm")
+		}
 	}
 
-	vgCreate, err := exec.LookPath("vgcreate")
+	err := os.MkdirAll(lvmProfileDir, 0755)
 	if err != nil {
-		return errors.Wrap(err, "error looking up command `vgcreate` while setting up direct lvm")
-	}
-
-	lvCreate, err := exec.LookPath("lvcreate")
-	if err != nil {
-		return errors.Wrap(err, "error looking up command `lvcreate` while setting up direct lvm")
-	}
-
-	lvConvert, err := exec.LookPath("lvconvert")
-	if err != nil {
-		return errors.Wrap(err, "error looking up command `lvconvert` while setting up direct lvm")
-	}
-
-	lvChange, err := exec.LookPath("lvchange")
-	if err != nil {
-		return errors.Wrap(err, "error looking up command `lvchange` while setting up direct lvm")
+		return errors.Wrap(err, "error creating lvm profile directory")
 	}
 
 	if cfg.AutoExtendPercent == 0 {
@@ -212,36 +201,36 @@
 		cfg.ThinpMetaPercent = 1
 	}
 
-	out, err := exec.Command(pvCreate, "-f", cfg.Device).CombinedOutput()
+	out, err := exec.Command("pvcreate", "-f", cfg.Device).CombinedOutput()
 	if err != nil {
 		return errors.Wrap(err, string(out))
 	}
 
-	out, err = exec.Command(vgCreate, "docker", cfg.Device).CombinedOutput()
+	out, err = exec.Command("vgcreate", "docker", cfg.Device).CombinedOutput()
 	if err != nil {
 		return errors.Wrap(err, string(out))
 	}
 
-	out, err = exec.Command(lvCreate, "--wipesignatures", "y", "-n", "thinpool", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpPercent)).CombinedOutput()
+	out, err = exec.Command("lvcreate", "--wipesignatures", "y", "-n", "thinpool", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpPercent)).CombinedOutput()
 	if err != nil {
 		return errors.Wrap(err, string(out))
 	}
-	out, err = exec.Command(lvCreate, "--wipesignatures", "y", "-n", "thinpoolmeta", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpMetaPercent)).CombinedOutput()
+	out, err = exec.Command("lvcreate", "--wipesignatures", "y", "-n", "thinpoolmeta", "docker", "--extents", fmt.Sprintf("%d%%VG", cfg.ThinpMetaPercent)).CombinedOutput()
 	if err != nil {
 		return errors.Wrap(err, string(out))
 	}
 
-	out, err = exec.Command(lvConvert, "-y", "--zero", "n", "-c", "512K", "--thinpool", "docker/thinpool", "--poolmetadata", "docker/thinpoolmeta").CombinedOutput()
+	out, err = exec.Command("lvconvert", "-y", "--zero", "n", "-c", "512K", "--thinpool", "docker/thinpool", "--poolmetadata", "docker/thinpoolmeta").CombinedOutput()
 	if err != nil {
 		return errors.Wrap(err, string(out))
 	}
 
 	profile := fmt.Sprintf("activation{\nthin_pool_autoextend_threshold=%d\nthin_pool_autoextend_percent=%d\n}", cfg.AutoExtendThreshold, cfg.AutoExtendPercent)
-	err = ioutil.WriteFile("/etc/lvm/profile/docker-thinpool.profile", []byte(profile), 0600)
+	err = ioutil.WriteFile(lvmProfileDir+"/docker-thinpool.profile", []byte(profile), 0600)
 	if err != nil {
 		return errors.Wrap(err, "error writing docker thinp autoextend profile")
 	}
 
-	out, err = exec.Command(lvChange, "--metadataprofile", "docker-thinpool", "docker/thinpool").CombinedOutput()
+	out, err = exec.Command("lvchange", "--metadataprofile", "docker-thinpool", "docker/thinpool").CombinedOutput()
 	return errors.Wrap(err, string(out))
 }
diff --git a/daemon/graphdriver/devmapper/deviceset.go b/daemon/graphdriver/devmapper/deviceset.go
index 906daf6..deb8c87 100644
--- a/daemon/graphdriver/devmapper/deviceset.go
+++ b/daemon/graphdriver/devmapper/deviceset.go
@@ -18,17 +18,19 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/pkg/devicemapper"
+	"github.com/docker/docker/pkg/dmesg"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/loopback"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/parsers"
+	"github.com/docker/docker/pkg/parsers/kernel"
 	units "github.com/docker/go-units"
 	"github.com/opencontainers/selinux/go-selinux/label"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
@@ -533,11 +535,11 @@
 	return devicemapper.ActivateDevice(devices.getPoolDevName(), info.Name(), info.DeviceID, info.Size)
 }
 
-// Return true only if kernel supports xfs and mkfs.xfs is available
-func xfsSupported() bool {
+// xfsSupported checks if xfs is supported, returns nil if it is, otherwise an error
+func xfsSupported() error {
 	// Make sure mkfs.xfs is available
 	if _, err := exec.LookPath("mkfs.xfs"); err != nil {
-		return false
+		return err // error text is descriptive enough
 	}
 
 	// Check if kernel supports xfs filesystem or not.
@@ -545,41 +547,48 @@
 
 	f, err := os.Open("/proc/filesystems")
 	if err != nil {
-		logrus.Warnf("devmapper: Could not check if xfs is supported: %v", err)
-		return false
+		return errors.Wrapf(err, "error checking for xfs support")
 	}
 	defer f.Close()
 
 	s := bufio.NewScanner(f)
 	for s.Scan() {
 		if strings.HasSuffix(s.Text(), "\txfs") {
-			return true
+			return nil
 		}
 	}
 
 	if err := s.Err(); err != nil {
-		logrus.Warnf("devmapper: Could not check if xfs is supported: %v", err)
+		return errors.Wrapf(err, "error checking for xfs support")
 	}
-	return false
+
+	return errors.New(`kernel does not support xfs, or "modprobe xfs" failed`)
 }
 
 func determineDefaultFS() string {
-	if xfsSupported() {
+	err := xfsSupported()
+	if err == nil {
 		return "xfs"
 	}
 
-	logrus.Warn("devmapper: XFS is not supported in your system. Either the kernel doesn't support it or mkfs.xfs is not in your PATH. Defaulting to ext4 filesystem")
+	logrus.Warnf("devmapper: XFS is not supported in your system (%v). Defaulting to ext4 filesystem", err)
 	return "ext4"
 }
 
+// mkfsOptions tries to figure out whether some additional mkfs options are required
+func mkfsOptions(fs string) []string {
+	if fs == "xfs" && !kernel.CheckKernelVersion(3, 16, 0) {
+		// For kernels earlier than 3.16 (and newer xfsutils),
+		// some xfs features need to be explicitly disabled.
+		return []string{"-m", "crc=0,finobt=0"}
+	}
+
+	return []string{}
+}
+
 func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) {
 	devname := info.DevName()
 
-	args := []string{}
-	args = append(args, devices.mkfsArgs...)
-
-	args = append(args, devname)
-
 	if devices.filesystem == "" {
 		devices.filesystem = determineDefaultFS()
 	}
@@ -587,7 +596,11 @@
 		return err
 	}
 
-	logrus.Infof("devmapper: Creating filesystem %s on device %s", devices.filesystem, info.Name())
+	args := mkfsOptions(devices.filesystem)
+	args = append(args, devices.mkfsArgs...)
+	args = append(args, devname)
+
+	logrus.Infof("devmapper: Creating filesystem %s on device %s, mkfs args: %v", devices.filesystem, info.Name(), args)
 	defer func() {
 		if err != nil {
 			logrus.Infof("devmapper: Error while creating filesystem %s on device %s: %v", devices.filesystem, info.Name(), err)
@@ -1188,7 +1201,7 @@
 	options = joinMountOptions(options, devices.mountOptions)
 
 	if err := mount.Mount(info.DevName(), fsMountPoint, devices.BaseDeviceFilesystem, options); err != nil {
-		return fmt.Errorf("Error mounting '%s' on '%s': %s", info.DevName(), fsMountPoint, err)
+		return fmt.Errorf("Error mounting '%s' on '%s': %s\n%v", info.DevName(), fsMountPoint, err, string(dmesg.Dmesg(256)))
 	}
 
 	defer unix.Unmount(fsMountPoint, unix.MNT_DETACH)
@@ -1254,14 +1267,13 @@
 }
 
 func setCloseOnExec(name string) {
-	if fileInfos, _ := ioutil.ReadDir("/proc/self/fd"); fileInfos != nil {
-		for _, i := range fileInfos {
-			link, _ := os.Readlink(filepath.Join("/proc/self/fd", i.Name()))
-			if link == name {
-				fd, err := strconv.Atoi(i.Name())
-				if err == nil {
-					unix.CloseOnExec(fd)
-				}
+	fileInfos, _ := ioutil.ReadDir("/proc/self/fd")
+	for _, i := range fileInfos {
+		link, _ := os.Readlink(filepath.Join("/proc/self/fd", i.Name()))
+		if link == name {
+			fd, err := strconv.Atoi(i.Name())
+			if err == nil {
+				unix.CloseOnExec(fd)
 			}
 		}
 	}
@@ -1479,12 +1491,9 @@
 }
 
 func determineDriverCapabilities(version string) error {
-	/*
-	 * Driver version 4.27.0 and greater support deferred activation
-	 * feature.
-	 */
+	// Kernel driver version >= 4.27.0 support deferred removal
 
-	logrus.Debugf("devicemapper: driver version is %s", version)
+	logrus.Debugf("devicemapper: kernel dm driver version is %s", version)
 
 	versionSplit := strings.Split(version, ".")
 	major, err := strconv.Atoi(versionSplit[0])
@@ -1863,7 +1872,7 @@
 
 	if devices.thinPoolDevice == "" {
 		if devices.metadataLoopFile != "" || devices.dataLoopFile != "" {
-			logrus.Warn("devmapper: Usage of loopback devices is strongly discouraged for production use. Please use `--storage-opt dm.thinpooldev` or use `man docker` to refer to dm.thinpooldev section.")
+			logrus.Warn("devmapper: Usage of loopback devices is strongly discouraged for production use. Please use `--storage-opt dm.thinpooldev` or use `man dockerd` to refer to dm.thinpooldev section.")
 		}
 	}
 
@@ -2383,7 +2392,7 @@
 	options = joinMountOptions(options, label.FormatMountLabel("", mountLabel))
 
 	if err := mount.Mount(info.DevName(), path, fstype, options); err != nil {
-		return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s", info.DevName(), path, err)
+		return fmt.Errorf("devmapper: Error mounting '%s' on '%s': %s\n%v", info.DevName(), path, err, string(dmesg.Dmesg(256)))
 	}
 
 	if fstype == "xfs" && devices.xfsNospaceRetries != "" {
@@ -2667,7 +2676,7 @@
 			devices.metaDataLoopbackSize = size
 		case "dm.fs":
 			if val != "ext4" && val != "xfs" {
-				return nil, fmt.Errorf("devmapper: Unsupported filesystem %s\n", val)
+				return nil, fmt.Errorf("devmapper: Unsupported filesystem %s", val)
 			}
 			devices.filesystem = val
 		case "dm.mkfsarg":
@@ -2789,7 +2798,7 @@
 				Level: int(level),
 			})
 		default:
-			return nil, fmt.Errorf("devmapper: Unknown option %s\n", key)
+			return nil, fmt.Errorf("devmapper: Unknown option %s", key)
 		}
 	}
 
diff --git a/daemon/graphdriver/devmapper/driver.go b/daemon/graphdriver/devmapper/driver.go
index 243d88a..f41afa2 100644
--- a/daemon/graphdriver/devmapper/driver.go
+++ b/daemon/graphdriver/devmapper/driver.go
@@ -9,9 +9,10 @@
 	"path"
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 
 	"github.com/docker/docker/daemon/graphdriver"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/devicemapper"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/locker"
@@ -69,18 +70,18 @@
 
 	status := [][2]string{
 		{"Pool Name", s.PoolName},
-		{"Pool Blocksize", fmt.Sprintf("%s", units.HumanSize(float64(s.SectorSize)))},
-		{"Base Device Size", fmt.Sprintf("%s", units.HumanSize(float64(s.BaseDeviceSize)))},
+		{"Pool Blocksize", units.HumanSize(float64(s.SectorSize))},
+		{"Base Device Size", units.HumanSize(float64(s.BaseDeviceSize))},
 		{"Backing Filesystem", s.BaseDeviceFS},
 		{"Data file", s.DataFile},
 		{"Metadata file", s.MetadataFile},
-		{"Data Space Used", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Used)))},
-		{"Data Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Total)))},
-		{"Data Space Available", fmt.Sprintf("%s", units.HumanSize(float64(s.Data.Available)))},
-		{"Metadata Space Used", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Used)))},
-		{"Metadata Space Total", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Total)))},
-		{"Metadata Space Available", fmt.Sprintf("%s", units.HumanSize(float64(s.Metadata.Available)))},
-		{"Thin Pool Minimum Free Space", fmt.Sprintf("%s", units.HumanSize(float64(s.MinFreeSpace)))},
+		{"Data Space Used", units.HumanSize(float64(s.Data.Used))},
+		{"Data Space Total", units.HumanSize(float64(s.Data.Total))},
+		{"Data Space Available", units.HumanSize(float64(s.Data.Available))},
+		{"Metadata Space Used", units.HumanSize(float64(s.Metadata.Used))},
+		{"Metadata Space Total", units.HumanSize(float64(s.Metadata.Total))},
+		{"Metadata Space Available", units.HumanSize(float64(s.Metadata.Available))},
+		{"Thin Pool Minimum Free Space", units.HumanSize(float64(s.MinFreeSpace))},
 		{"Udev Sync Supported", fmt.Sprintf("%v", s.UdevSyncSupported)},
 		{"Deferred Removal Enabled", fmt.Sprintf("%v", s.DeferredRemoveEnabled)},
 		{"Deferred Deletion Enabled", fmt.Sprintf("%v", s.DeferredDeleteEnabled)},
@@ -159,51 +160,45 @@
 	if err := d.DeviceSet.DeleteDevice(id, false); err != nil {
 		return fmt.Errorf("failed to remove device %s: %v", id, err)
 	}
-
-	mp := path.Join(d.home, "mnt", id)
-	if err := system.EnsureRemoveAll(mp); err != nil {
-		return err
-	}
-
-	return nil
+	return system.EnsureRemoveAll(path.Join(d.home, "mnt", id))
 }
 
 // Get mounts a device with given id into the root filesystem
-func (d *Driver) Get(id, mountLabel string) (string, error) {
+func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	d.locker.Lock(id)
 	defer d.locker.Unlock(id)
 	mp := path.Join(d.home, "mnt", id)
 	rootFs := path.Join(mp, "rootfs")
 	if count := d.ctr.Increment(mp); count > 1 {
-		return rootFs, nil
+		return containerfs.NewLocalContainerFS(rootFs), nil
 	}
 
 	uid, gid, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
 	if err != nil {
 		d.ctr.Decrement(mp)
-		return "", err
+		return nil, err
 	}
 
 	// Create the target directories if they don't exist
 	if err := idtools.MkdirAllAs(path.Join(d.home, "mnt"), 0755, uid, gid); err != nil && !os.IsExist(err) {
 		d.ctr.Decrement(mp)
-		return "", err
+		return nil, err
 	}
 	if err := idtools.MkdirAs(mp, 0755, uid, gid); err != nil && !os.IsExist(err) {
 		d.ctr.Decrement(mp)
-		return "", err
+		return nil, err
 	}
 
 	// Mount the device
 	if err := d.DeviceSet.MountDevice(id, mp, mountLabel); err != nil {
 		d.ctr.Decrement(mp)
-		return "", err
+		return nil, err
 	}
 
 	if err := idtools.MkdirAllAs(rootFs, 0755, uid, gid); err != nil && !os.IsExist(err) {
 		d.ctr.Decrement(mp)
 		d.DeviceSet.UnmountDevice(id, mp)
-		return "", err
+		return nil, err
 	}
 
 	idFile := path.Join(mp, "id")
@@ -213,11 +208,11 @@
 		if err := ioutil.WriteFile(idFile, []byte(id), 0600); err != nil {
 			d.ctr.Decrement(mp)
 			d.DeviceSet.UnmountDevice(id, mp)
-			return "", err
+			return nil, err
 		}
 	}
 
-	return rootFs, nil
+	return containerfs.NewLocalContainerFS(rootFs), nil
 }
 
 // Put unmounts a device and removes it.
diff --git a/daemon/graphdriver/driver.go b/daemon/graphdriver/driver.go
index 88f190d..68f9022 100644
--- a/daemon/graphdriver/driver.go
+++ b/daemon/graphdriver/driver.go
@@ -8,10 +8,11 @@
 	"path/filepath"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"github.com/vbatts/tar-split/tar/storage"
 
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/plugingetter"
 )
@@ -68,7 +69,7 @@
 	// Get returns the mountpoint for the layered filesystem referred
 	// to by this id. You can optionally specify a mountLabel or "".
 	// Returns the absolute path to the mounted layered filesystem.
-	Get(id, mountLabel string) (dir string, err error)
+	Get(id, mountLabel string) (fs containerfs.ContainerFS, err error)
 	// Put releases the system resources for the specified id,
 	// e.g, unmounting layered filesystem.
 	Put(id string) error
diff --git a/daemon/graphdriver/driver_freebsd.go b/daemon/graphdriver/driver_freebsd.go
index fb13ac3..53394b7 100644
--- a/daemon/graphdriver/driver_freebsd.go
+++ b/daemon/graphdriver/driver_freebsd.go
@@ -1,6 +1,10 @@
 package graphdriver
 
-import "golang.org/x/sys/unix"
+import (
+	"syscall"
+
+	"golang.org/x/sys/unix"
+)
 
 var (
 	// Slice of drivers that should be used in an order
diff --git a/daemon/graphdriver/driver_linux.go b/daemon/graphdriver/driver_linux.go
index a92993d..a2be46b 100644
--- a/daemon/graphdriver/driver_linux.go
+++ b/daemon/graphdriver/driver_linux.go
@@ -53,10 +53,10 @@
 var (
 	// Slice of drivers that should be used in an order
 	priority = []string{
-		"aufs",
 		"btrfs",
 		"zfs",
 		"overlay2",
+		"aufs",
 		"overlay",
 		"devicemapper",
 		"vfs",
@@ -67,6 +67,7 @@
 		FsMagicAufs:        "aufs",
 		FsMagicBtrfs:       "btrfs",
 		FsMagicCramfs:      "cramfs",
+		FsMagicEcryptfs:    "ecryptfs",
 		FsMagicExtfs:       "extfs",
 		FsMagicF2fs:        "f2fs",
 		FsMagicGPFS:        "gpfs",
diff --git a/daemon/graphdriver/driver_solaris.go b/daemon/graphdriver/driver_solaris.go
index 06dc360..d31aaef 100644
--- a/daemon/graphdriver/driver_solaris.go
+++ b/daemon/graphdriver/driver_solaris.go
@@ -19,8 +19,8 @@
 	"path/filepath"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/mount"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -81,17 +81,16 @@
 func Mounted(fsType FsMagic, mountPath string) (bool, error) {
 
 	cs := C.CString(filepath.Dir(mountPath))
+	defer C.free(unsafe.Pointer(cs))
 	buf := C.getstatfs(cs)
+	defer C.free(unsafe.Pointer(buf))
 
 	// on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
 	if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
 		(buf.f_basetype[3] != 0) {
 		logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", mountPath)
-		C.free(unsafe.Pointer(buf))
 		return false, ErrPrerequisites
 	}
 
-	C.free(unsafe.Pointer(buf))
-	C.free(unsafe.Pointer(cs))
 	return true, nil
 }
diff --git a/daemon/graphdriver/fsdiff.go b/daemon/graphdriver/fsdiff.go
index 20826cd..533c5a7 100644
--- a/daemon/graphdriver/fsdiff.go
+++ b/daemon/graphdriver/fsdiff.go
@@ -4,11 +4,11 @@
 	"io"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/chrootarchive"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/ioutils"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -18,9 +18,9 @@
 )
 
 // NaiveDiffDriver takes a ProtoDriver and adds the
-// capability of the Diffing methods which it may or may not
-// support on its own. See the comment on the exported
-// NewNaiveDiffDriver function below.
+// capability of the Diffing methods on the local file system,
+// which it may or may not support on its own. See the comment
+// on the exported NewNaiveDiffDriver function below.
 // Notably, the AUFS driver doesn't need to be wrapped like this.
 type NaiveDiffDriver struct {
 	ProtoDriver
@@ -47,10 +47,11 @@
 	startTime := time.Now()
 	driver := gdw.ProtoDriver
 
-	layerFs, err := driver.Get(id, "")
+	layerRootFs, err := driver.Get(id, "")
 	if err != nil {
 		return nil, err
 	}
+	layerFs := layerRootFs.Path()
 
 	defer func() {
 		if err != nil {
@@ -70,12 +71,14 @@
 		}), nil
 	}
 
-	parentFs, err := driver.Get(parent, "")
+	parentRootFs, err := driver.Get(parent, "")
 	if err != nil {
 		return nil, err
 	}
 	defer driver.Put(parent)
 
+	parentFs := parentRootFs.Path()
+
 	changes, err := archive.ChangesDirs(layerFs, parentFs)
 	if err != nil {
 		return nil, err
@@ -94,7 +97,7 @@
 		// are extracted from tar's with full second precision on modified time.
 		// We need this hack here to make sure calls within same second receive
 		// correct result.
-		time.Sleep(startTime.Truncate(time.Second).Add(time.Second).Sub(time.Now()))
+		time.Sleep(time.Until(startTime.Truncate(time.Second).Add(time.Second)))
 		return err
 	}), nil
 }
@@ -104,20 +107,22 @@
 func (gdw *NaiveDiffDriver) Changes(id, parent string) ([]archive.Change, error) {
 	driver := gdw.ProtoDriver
 
-	layerFs, err := driver.Get(id, "")
+	layerRootFs, err := driver.Get(id, "")
 	if err != nil {
 		return nil, err
 	}
 	defer driver.Put(id)
 
+	layerFs := layerRootFs.Path()
 	parentFs := ""
 
 	if parent != "" {
-		parentFs, err = driver.Get(parent, "")
+		parentRootFs, err := driver.Get(parent, "")
 		if err != nil {
 			return nil, err
 		}
 		defer driver.Put(parent)
+		parentFs = parentRootFs.Path()
 	}
 
 	return archive.ChangesDirs(layerFs, parentFs)
@@ -130,12 +135,13 @@
 	driver := gdw.ProtoDriver
 
 	// Mount the root filesystem so we can apply the diff/layer.
-	layerFs, err := driver.Get(id, "")
+	layerRootFs, err := driver.Get(id, "")
 	if err != nil {
 		return
 	}
 	defer driver.Put(id)
 
+	layerFs := layerRootFs.Path()
 	options := &archive.TarOptions{UIDMaps: gdw.uidMaps,
 		GIDMaps: gdw.gidMaps}
 	start := time.Now().UTC()
@@ -165,5 +171,5 @@
 	}
 	defer driver.Put(id)
 
-	return archive.ChangesSize(layerFs, changes), nil
+	return archive.ChangesSize(layerFs.Path(), changes), nil
 }
diff --git a/daemon/graphdriver/graphtest/graphbench_unix.go b/daemon/graphdriver/graphtest/graphbench_unix.go
index def822b..c04394d 100644
--- a/daemon/graphdriver/graphtest/graphbench_unix.go
+++ b/daemon/graphdriver/graphtest/graphbench_unix.go
@@ -3,13 +3,13 @@
 package graphtest
 
 import (
-	"bytes"
 	"io"
 	"io/ioutil"
-	"path/filepath"
 	"testing"
 
+	contdriver "github.com/containerd/continuity/driver"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/stretchr/testify/require"
 )
 
 // DriverBenchExists benchmarks calls to exist
@@ -245,15 +245,13 @@
 	for i := 0; i < b.N; i++ {
 
 		// Read content
-		c, err := ioutil.ReadFile(filepath.Join(root, "testfile.txt"))
+		c, err := contdriver.ReadFile(root, root.Join(root.Path(), "testfile.txt"))
 		if err != nil {
 			b.Fatal(err)
 		}
 
 		b.StopTimer()
-		if bytes.Compare(c, content) != 0 {
-			b.Fatalf("Wrong content in file %v, expected %v", c, content)
-		}
+		require.Equal(b, content, c)
 		b.StartTimer()
 	}
 }
diff --git a/daemon/graphdriver/graphtest/graphtest_unix.go b/daemon/graphdriver/graphtest/graphtest_unix.go
index 2f8ae54..11dff48 100644
--- a/daemon/graphdriver/graphtest/graphtest_unix.go
+++ b/daemon/graphdriver/graphtest/graphtest_unix.go
@@ -97,10 +97,10 @@
 	dir, err := driver.Get("empty", "")
 	require.NoError(t, err)
 
-	verifyFile(t, dir, 0755|os.ModeDir, 0, 0)
+	verifyFile(t, dir.Path(), 0755|os.ModeDir, 0, 0)
 
 	// Verify that the directory is empty
-	fis, err := readDir(dir)
+	fis, err := readDir(dir, dir.Path())
 	require.NoError(t, err)
 	assert.Len(t, fis, 0)
 
@@ -328,9 +328,9 @@
 	}
 
 	quota := uint64(50 * units.MiB)
-	err = writeRandomFile(path.Join(mountPath, "file"), quota*2)
+
+	err = writeRandomFile(path.Join(mountPath.Path(), "file"), quota*2)
 	if pathError, ok := err.(*os.PathError); ok && pathError.Err != unix.EDQUOT {
 		t.Fatalf("expect write() to fail with %v, got %v", unix.EDQUOT, err)
 	}
-
 }
diff --git a/daemon/graphdriver/graphtest/testutil.go b/daemon/graphdriver/graphtest/testutil.go
index 35bf6d1..9463132 100644
--- a/daemon/graphdriver/graphtest/testutil.go
+++ b/daemon/graphdriver/graphtest/testutil.go
@@ -3,12 +3,11 @@
 import (
 	"bytes"
 	"fmt"
-	"io/ioutil"
 	"math/rand"
 	"os"
-	"path"
 	"sort"
 
+	"github.com/containerd/continuity/driver"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/stringid"
@@ -36,17 +35,17 @@
 	}
 	defer drv.Put(layer)
 
-	if err := ioutil.WriteFile(path.Join(root, "file-a"), randomContent(64, seed), 0755); err != nil {
+	if err := driver.WriteFile(root, root.Join(root.Path(), "file-a"), randomContent(64, seed), 0755); err != nil {
 		return err
 	}
-	if err := os.MkdirAll(path.Join(root, "dir-b"), 0755); err != nil {
+	if err := root.MkdirAll(root.Join(root.Path(), "dir-b"), 0755); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(path.Join(root, "dir-b", "file-b"), randomContent(128, seed+1), 0755); err != nil {
+	if err := driver.WriteFile(root, root.Join(root.Path(), "dir-b", "file-b"), randomContent(128, seed+1), 0755); err != nil {
 		return err
 	}
 
-	return ioutil.WriteFile(path.Join(root, "file-c"), randomContent(128*128, seed+2), 0755)
+	return driver.WriteFile(root, root.Join(root.Path(), "file-c"), randomContent(128*128, seed+2), 0755)
 }
 
 func checkFile(drv graphdriver.Driver, layer, filename string, content []byte) error {
@@ -56,12 +55,12 @@
 	}
 	defer drv.Put(layer)
 
-	fileContent, err := ioutil.ReadFile(path.Join(root, filename))
+	fileContent, err := driver.ReadFile(root, root.Join(root.Path(), filename))
 	if err != nil {
 		return err
 	}
 
-	if bytes.Compare(fileContent, content) != 0 {
+	if !bytes.Equal(fileContent, content) {
 		return fmt.Errorf("mismatched file content %v, expecting %v", fileContent, content)
 	}
 
@@ -75,7 +74,7 @@
 	}
 	defer drv.Put(layer)
 
-	return ioutil.WriteFile(path.Join(root, filename), content, 0755)
+	return driver.WriteFile(root, root.Join(root.Path(), filename), content, 0755)
 }
 
 func addDirectory(drv graphdriver.Driver, layer, dir string) error {
@@ -85,7 +84,7 @@
 	}
 	defer drv.Put(layer)
 
-	return os.MkdirAll(path.Join(root, dir), 0755)
+	return root.MkdirAll(root.Join(root.Path(), dir), 0755)
 }
 
 func removeAll(drv graphdriver.Driver, layer string, names ...string) error {
@@ -96,7 +95,7 @@
 	defer drv.Put(layer)
 
 	for _, filename := range names {
-		if err := os.RemoveAll(path.Join(root, filename)); err != nil {
+		if err := root.RemoveAll(root.Join(root.Path(), filename)); err != nil {
 			return err
 		}
 	}
@@ -110,8 +109,8 @@
 	}
 	defer drv.Put(layer)
 
-	if _, err := os.Stat(path.Join(root, filename)); err == nil {
-		return fmt.Errorf("file still exists: %s", path.Join(root, filename))
+	if _, err := root.Stat(root.Join(root.Path(), filename)); err == nil {
+		return fmt.Errorf("file still exists: %s", root.Join(root.Path(), filename))
 	} else if !os.IsNotExist(err) {
 		return err
 	}
@@ -127,13 +126,13 @@
 	defer drv.Put(layer)
 
 	for i := 0; i < count; i += 100 {
-		dir := path.Join(root, fmt.Sprintf("directory-%d", i))
-		if err := os.MkdirAll(dir, 0755); err != nil {
+		dir := root.Join(root.Path(), fmt.Sprintf("directory-%d", i))
+		if err := root.MkdirAll(dir, 0755); err != nil {
 			return err
 		}
 		for j := 0; i+j < count && j < 100; j++ {
-			file := path.Join(dir, fmt.Sprintf("file-%d", i+j))
-			if err := ioutil.WriteFile(file, randomContent(64, seed+int64(i+j)), 0755); err != nil {
+			file := root.Join(dir, fmt.Sprintf("file-%d", i+j))
+			if err := driver.WriteFile(root, file, randomContent(64, seed+int64(i+j)), 0755); err != nil {
 				return err
 			}
 		}
@@ -152,7 +151,7 @@
 	changes := []archive.Change{}
 	for i := 0; i < count; i += 100 {
 		archiveRoot := fmt.Sprintf("/directory-%d", i)
-		if err := os.MkdirAll(path.Join(root, archiveRoot), 0755); err != nil {
+		if err := root.MkdirAll(root.Join(root.Path(), archiveRoot), 0755); err != nil {
 			return nil, err
 		}
 		for j := 0; i+j < count && j < 100; j++ {
@@ -166,23 +165,23 @@
 			switch j % 3 {
 			// Update file
 			case 0:
-				change.Path = path.Join(archiveRoot, fmt.Sprintf("file-%d", i+j))
+				change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d", i+j))
 				change.Kind = archive.ChangeModify
-				if err := ioutil.WriteFile(path.Join(root, change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil {
+				if err := driver.WriteFile(root, root.Join(root.Path(), change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil {
 					return nil, err
 				}
 			// Add file
 			case 1:
-				change.Path = path.Join(archiveRoot, fmt.Sprintf("file-%d-%d", seed, i+j))
+				change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d-%d", seed, i+j))
 				change.Kind = archive.ChangeAdd
-				if err := ioutil.WriteFile(path.Join(root, change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil {
+				if err := driver.WriteFile(root, root.Join(root.Path(), change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil {
 					return nil, err
 				}
 			// Remove file
 			case 2:
-				change.Path = path.Join(archiveRoot, fmt.Sprintf("file-%d", i+j))
+				change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d", i+j))
 				change.Kind = archive.ChangeDelete
-				if err := os.Remove(path.Join(root, change.Path)); err != nil {
+				if err := root.Remove(root.Join(root.Path(), change.Path)); err != nil {
 					return nil, err
 				}
 			}
@@ -201,17 +200,17 @@
 	defer drv.Put(layer)
 
 	for i := 0; i < count; i += 100 {
-		dir := path.Join(root, fmt.Sprintf("directory-%d", i))
+		dir := root.Join(root.Path(), fmt.Sprintf("directory-%d", i))
 		for j := 0; i+j < count && j < 100; j++ {
-			file := path.Join(dir, fmt.Sprintf("file-%d", i+j))
-			fileContent, err := ioutil.ReadFile(file)
+			file := root.Join(dir, fmt.Sprintf("file-%d", i+j))
+			fileContent, err := driver.ReadFile(root, file)
 			if err != nil {
 				return err
 			}
 
 			content := randomContent(64, seed+int64(i+j))
 
-			if bytes.Compare(fileContent, content) != 0 {
+			if !bytes.Equal(fileContent, content) {
 				return fmt.Errorf("mismatched file content %v, expecting %v", fileContent, content)
 			}
 		}
@@ -254,17 +253,17 @@
 	}
 	defer drv.Put(layer)
 
-	if err := ioutil.WriteFile(path.Join(root, "top-id"), []byte(layer), 0755); err != nil {
+	if err := driver.WriteFile(root, root.Join(root.Path(), "top-id"), []byte(layer), 0755); err != nil {
 		return err
 	}
-	layerDir := path.Join(root, fmt.Sprintf("layer-%d", i))
-	if err := os.MkdirAll(layerDir, 0755); err != nil {
+	layerDir := root.Join(root.Path(), fmt.Sprintf("layer-%d", i))
+	if err := root.MkdirAll(layerDir, 0755); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(path.Join(layerDir, "layer-id"), []byte(layer), 0755); err != nil {
+	if err := driver.WriteFile(root, root.Join(layerDir, "layer-id"), []byte(layer), 0755); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(path.Join(layerDir, "parent-id"), []byte(parent), 0755); err != nil {
+	if err := driver.WriteFile(root, root.Join(layerDir, "parent-id"), []byte(parent), 0755); err != nil {
 		return err
 	}
 
@@ -295,26 +294,26 @@
 	}
 	defer drv.Put(layer)
 
-	layerIDBytes, err := ioutil.ReadFile(path.Join(root, "top-id"))
+	layerIDBytes, err := driver.ReadFile(root, root.Join(root.Path(), "top-id"))
 	if err != nil {
 		return err
 	}
 
-	if bytes.Compare(layerIDBytes, []byte(layer)) != 0 {
+	if !bytes.Equal(layerIDBytes, []byte(layer)) {
 		return fmt.Errorf("mismatched file content %v, expecting %v", layerIDBytes, []byte(layer))
 	}
 
 	for i := count; i > 0; i-- {
-		layerDir := path.Join(root, fmt.Sprintf("layer-%d", i))
+		layerDir := root.Join(root.Path(), fmt.Sprintf("layer-%d", i))
 
-		thisLayerIDBytes, err := ioutil.ReadFile(path.Join(layerDir, "layer-id"))
+		thisLayerIDBytes, err := driver.ReadFile(root, root.Join(layerDir, "layer-id"))
 		if err != nil {
 			return err
 		}
-		if bytes.Compare(thisLayerIDBytes, layerIDBytes) != 0 {
+		if !bytes.Equal(thisLayerIDBytes, layerIDBytes) {
 			return fmt.Errorf("mismatched file content %v, expecting %v", thisLayerIDBytes, layerIDBytes)
 		}
-		layerIDBytes, err = ioutil.ReadFile(path.Join(layerDir, "parent-id"))
+		layerIDBytes, err = driver.ReadFile(root, root.Join(layerDir, "parent-id"))
 		if err != nil {
 			return err
 		}
@@ -322,11 +321,11 @@
 	return nil
 }
 
-// readDir reads a directory just like ioutil.ReadDir()
+// readDir reads a directory just like driver.ReadDir()
 // then hides specific files (currently "lost+found")
 // so the tests don't "see" it
-func readDir(dir string) ([]os.FileInfo, error) {
-	a, err := ioutil.ReadDir(dir)
+func readDir(r driver.Driver, dir string) ([]os.FileInfo, error) {
+	a, err := driver.ReadDir(r, dir)
 	if err != nil {
 		return nil, err
 	}
diff --git a/daemon/graphdriver/graphtest/testutil_unix.go b/daemon/graphdriver/graphtest/testutil_unix.go
index 9647448..b5dec43 100644
--- a/daemon/graphdriver/graphtest/testutil_unix.go
+++ b/daemon/graphdriver/graphtest/testutil_unix.go
@@ -3,12 +3,11 @@
 package graphtest
 
 import (
-	"io/ioutil"
 	"os"
-	"path"
 	"syscall"
 	"testing"
 
+	contdriver "github.com/containerd/continuity/driver"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -40,31 +39,31 @@
 	err := driver.CreateReadWrite(name, "", nil)
 	require.NoError(t, err)
 
-	dir, err := driver.Get(name, "")
+	dirFS, err := driver.Get(name, "")
 	require.NoError(t, err)
 	defer driver.Put(name)
 
-	subdir := path.Join(dir, "a subdir")
-	require.NoError(t, os.Mkdir(subdir, 0705|os.ModeSticky))
-	require.NoError(t, os.Chown(subdir, 1, 2))
+	subdir := dirFS.Join(dirFS.Path(), "a subdir")
+	require.NoError(t, dirFS.Mkdir(subdir, 0705|os.ModeSticky))
+	require.NoError(t, dirFS.Lchown(subdir, 1, 2))
 
-	file := path.Join(dir, "a file")
-	err = ioutil.WriteFile(file, []byte("Some data"), 0222|os.ModeSetuid)
+	file := dirFS.Join(dirFS.Path(), "a file")
+	err = contdriver.WriteFile(dirFS, file, []byte("Some data"), 0222|os.ModeSetuid)
 	require.NoError(t, err)
 }
 
 func verifyBase(t testing.TB, driver graphdriver.Driver, name string) {
-	dir, err := driver.Get(name, "")
+	dirFS, err := driver.Get(name, "")
 	require.NoError(t, err)
 	defer driver.Put(name)
 
-	subdir := path.Join(dir, "a subdir")
+	subdir := dirFS.Join(dirFS.Path(), "a subdir")
 	verifyFile(t, subdir, 0705|os.ModeDir|os.ModeSticky, 1, 2)
 
-	file := path.Join(dir, "a file")
+	file := dirFS.Join(dirFS.Path(), "a file")
 	verifyFile(t, file, 0222|os.ModeSetuid, 0, 0)
 
-	files, err := readDir(dir)
+	files, err := readDir(dirFS, dirFS.Path())
 	require.NoError(t, err)
 	assert.Len(t, files, 2)
 }
diff --git a/daemon/graphdriver/lcow/lcow.go b/daemon/graphdriver/lcow/lcow.go
index 75c775b..c999d5b 100644
--- a/daemon/graphdriver/lcow/lcow.go
+++ b/daemon/graphdriver/lcow/lcow.go
@@ -13,7 +13,43 @@
 // operations. The downside of safe-mode is that operations are slower as
 // a new service utility VM has to be started and torn-down when needed.
 //
-// To enable global mode, run with --storage-opt lcow.globalmode=true
+// Options:
+//
+// The following options are read by the graphdriver itself:
+//
+//   * lcow.globalmode - Enables global service VM Mode
+//        -- Possible values:     true/false
+//        -- Default if omitted:  false
+//
+//   * lcow.sandboxsize - Specifies a custom sandbox size in GB for starting a container
+//        -- Possible values:      >= default sandbox size (opengcs defined, currently 20)
+//        -- Default if omitted:  20
+//
+// The following options are read by opengcs:
+//
+//   * lcow.kirdpath - Specifies a custom path to a kernel/initrd pair
+//        -- Possible values:      Any local path that is not a mapped drive
+//        -- Default if omitted:  %ProgramFiles%\Linux Containers
+//
+//   * lcow.kernel - Specifies a custom kernel file located in the `lcow.kirdpath` path
+//        -- Possible values:      Any valid filename
+//        -- Default if omitted:  bootx64.efi
+//
+//   * lcow.initrd - Specifies a custom initrd file located in the `lcow.kirdpath` path
+//        -- Possible values:      Any valid filename
+//        -- Default if omitted:  initrd.img
+//
+//   * lcow.bootparameters - Specifies additional boot parameters for booting in kernel+initrd mode
+//        -- Possible values:      Any valid linux kernel boot options
+//        -- Default if omitted:  <nil>
+//
+//   * lcow.vhdx - Specifies a custom vhdx file to boot (instead of a kernel+initrd)
+//        -- Possible values:      Any valid filename
+//        -- Default if omitted:  uvm.vhdx under `lcow.kirdpath`
+//
+//   * lcow.timeout - Specifies a timeout for utility VM operations in seconds
+//        -- Possible values:      >=0
+//        -- Default if omitted:  300
 
 // TODO: Grab logs from SVM at terminate or errors
 
@@ -29,16 +65,18 @@
 	"strconv"
 	"strings"
 	"sync"
+	"syscall"
 	"time"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
+	"github.com/Microsoft/opengcs/client"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/system"
-	"github.com/jhowardmsft/opengcs/gogcs/client"
+	"github.com/sirupsen/logrus"
 )
 
 // init registers this driver to the register. It gets initialised by the
@@ -60,8 +98,7 @@
 
 	// toolsScratchPath is a location in a service utility VM that the tools can use as a
 	// scratch space to avoid running out of memory.
-	// TODO @jhowardmsft. I really dislike this path! But needs a platform change or passing parameters to the tools.
-	toolsScratchPath = "/mnt/gcs/LinuxServiceVM/scratch"
+	toolsScratchPath = "/tmp/scratch"
 
 	// svmGlobalID is the ID used in the serviceVMs map for the global service VM when running in "global" mode.
 	svmGlobalID = "_lcow_global_svm_"
@@ -71,44 +108,32 @@
 
 	// scratchDirectory is the sub-folder under the driver's data-root used for scratch VHDs in service VMs
 	scratchDirectory = "scratch"
+
+	// errOperationPending is the HRESULT returned by the HCS when the VM termination operation is still pending.
+	errOperationPending syscall.Errno = 0xc0370103
 )
 
-// cacheItem is our internal structure representing an item in our local cache
-// of things that have been mounted.
-type cacheItem struct {
-	sync.Mutex        // Protects operations performed on this item
-	uvmPath    string // Path in utility VM
-	hostPath   string // Path on host
-	refCount   int    // How many times its been mounted
-	isSandbox  bool   // True if a sandbox
-	isMounted  bool   // True when mounted in a service VM
-}
-
-// serviceVMItem is our internal structure representing an item in our
-// map of service VMs we are maintaining.
-type serviceVMItem struct {
-	sync.Mutex                     // Serialises operations being performed in this service VM.
-	scratchAttached bool           // Has a scratch been attached?
-	config          *client.Config // Represents the service VM item.
-}
-
 // Driver represents an LCOW graph driver.
 type Driver struct {
-	dataRoot           string                    // Root path on the host where we are storing everything.
-	cachedSandboxFile  string                    // Location of the local default-sized cached sandbox.
-	cachedSandboxMutex sync.Mutex                // Protects race conditions from multiple threads creating the cached sandbox.
-	cachedScratchFile  string                    // Location of the local cached empty scratch space.
-	cachedScratchMutex sync.Mutex                // Protects race conditions from multiple threads creating the cached scratch.
-	options            []string                  // Graphdriver options we are initialised with.
-	serviceVmsMutex    sync.Mutex                // Protects add/updates/delete to the serviceVMs map.
-	serviceVms         map[string]*serviceVMItem // Map of the configs representing the service VM(s) we are running.
-	globalMode         bool                      // Indicates if running in an unsafe/global service VM mode.
+	dataRoot           string     // Root path on the host where we are storing everything.
+	cachedSandboxFile  string     // Location of the local default-sized cached sandbox.
+	cachedSandboxMutex sync.Mutex // Protects race conditions from multiple threads creating the cached sandbox.
+	cachedScratchFile  string     // Location of the local cached empty scratch space.
+	cachedScratchMutex sync.Mutex // Protects race conditions from multiple threads creating the cached scratch.
+	options            []string   // Graphdriver options we are initialised with.
+	globalMode         bool       // Indicates if running in an unsafe/global service VM mode.
 
 	// NOTE: It is OK to use a cache here because Windows does not support
 	// restoring containers when the daemon dies.
+	serviceVms *serviceVMMap // Map of the configs representing the service VM(s) we are running.
+}
 
-	cacheMutex sync.Mutex            // Protects add/update/deletes to cache.
-	cache      map[string]*cacheItem // Map holding a cache of all the IDs we've mounted/unmounted.
+// layerDetails is the structure returned by a helper function `getLayerDetails`
+// for getting information about a layer folder
+type layerDetails struct {
+	filename  string // \path\to\sandbox.vhdx or \path\to\layer.vhd
+	size      int64  // size of the above file
+	isSandbox bool   // true if sandbox.vhdx
 }
 
 // deletefiles is a helper function for initialisation where we delete any
@@ -133,9 +158,10 @@
 		options:           options,
 		cachedSandboxFile: filepath.Join(cd, sandboxFilename),
 		cachedScratchFile: filepath.Join(cd, scratchFilename),
-		cache:             make(map[string]*cacheItem),
-		serviceVms:        make(map[string]*serviceVMItem),
-		globalMode:        false,
+		serviceVms: &serviceVMMap{
+			svms: make(map[string]*serviceVMMapItem),
+		},
+		globalMode: false,
 	}
 
 	// Looks for relevant options
@@ -177,53 +203,59 @@
 	return d, nil
 }
 
+func (d *Driver) getVMID(id string) string {
+	if d.globalMode {
+		return svmGlobalID
+	}
+	return id
+}
+
 // startServiceVMIfNotRunning starts a service utility VM if it is not currently running.
 // It can optionally be started with a mapped virtual disk. Returns a opengcs config structure
 // representing the VM.
-func (d *Driver) startServiceVMIfNotRunning(id string, mvdToAdd *hcsshim.MappedVirtualDisk, context string) (*serviceVMItem, error) {
+func (d *Driver) startServiceVMIfNotRunning(id string, mvdToAdd []hcsshim.MappedVirtualDisk, context string) (_ *serviceVM, err error) {
 	// Use the global ID if in global mode
-	if d.globalMode {
-		id = svmGlobalID
-	}
+	id = d.getVMID(id)
 
 	title := fmt.Sprintf("lcowdriver: startservicevmifnotrunning %s:", id)
 
-	// Make sure thread-safe when interrogating the map
-	logrus.Debugf("%s taking serviceVmsMutex", title)
-	d.serviceVmsMutex.Lock()
+	// Attempt to add ID to the service vm map
+	logrus.Debugf("%s: Adding entry to service vm map", title)
+	svm, exists, err := d.serviceVms.add(id)
+	if err != nil && err == errVMisTerminating {
+		// VM is in the process of terminating. Wait until it's done and and then try again
+		logrus.Debugf("%s: VM with current ID still in the process of terminating: %s", title, id)
+		if err := svm.getStopError(); err != nil {
+			logrus.Debugf("%s: VM %s did not stop successfully: %s", title, id, err)
+			return nil, err
+		}
+		return d.startServiceVMIfNotRunning(id, mvdToAdd, context)
+	} else if err != nil {
+		logrus.Debugf("%s: failed to add service vm to map: %s", err)
+		return nil, fmt.Errorf("%s: failed to add to service vm map: %s", title, err)
+	}
 
-	// Nothing to do if it's already running except add the mapped drive if supplied.
-	if svm, ok := d.serviceVms[id]; ok {
-		logrus.Debugf("%s exists, releasing serviceVmsMutex", title)
-		d.serviceVmsMutex.Unlock()
-
-		if mvdToAdd != nil {
-			logrus.Debugf("hot-adding %s to %s", mvdToAdd.HostPath, mvdToAdd.ContainerPath)
-
-			// Ensure the item is locked while doing this
-			logrus.Debugf("%s locking serviceVmItem %s", title, svm.config.Name)
-			svm.Lock()
-
-			if err := svm.config.HotAddVhd(mvdToAdd.HostPath, mvdToAdd.ContainerPath); err != nil {
-				logrus.Debugf("%s releasing serviceVmItem %s on hot-add failure %s", title, svm.config.Name, err)
-				svm.Unlock()
-				return nil, fmt.Errorf("%s hot add %s to %s failed: %s", title, mvdToAdd.HostPath, mvdToAdd.ContainerPath, err)
-			}
-
-			logrus.Debugf("%s releasing serviceVmItem %s", title, svm.config.Name)
-			svm.Unlock()
+	if exists {
+		// Service VM is already up and running. In this case, just hot add the vhds.
+		logrus.Debugf("%s: service vm already exists. Just hot adding: %+v", title, mvdToAdd)
+		if err := svm.hotAddVHDs(mvdToAdd...); err != nil {
+			logrus.Debugf("%s: failed to hot add vhds on service vm creation: %s", title, err)
+			return nil, fmt.Errorf("%s: failed to hot add vhds on service vm: %s", title, err)
 		}
 		return svm, nil
 	}
 
-	// Release the lock early
-	logrus.Debugf("%s releasing serviceVmsMutex", title)
-	d.serviceVmsMutex.Unlock()
+	// We are the first service for this id, so we need to start it
+	logrus.Debugf("%s: service vm doesn't exist. Now starting it up: %s", title, id)
 
-	// So we are starting one. First need an enpty structure.
-	svm := &serviceVMItem{
-		config: &client.Config{},
-	}
+	defer func() {
+		// Signal that start has finished, passing in the error if any.
+		svm.signalStartFinished(err)
+		if err != nil {
+			// We added a ref to the VM, since we failed, we should delete the ref.
+			d.terminateServiceVM(id, "error path on startServiceVMIfNotRunning", false)
+		}
+	}()
 
 	// Generate a default configuration
 	if err := svm.config.GenerateDefault(d.options); err != nil {
@@ -264,120 +296,96 @@
 		svm.config.MappedVirtualDisks = append(svm.config.MappedVirtualDisks, mvd)
 		svm.scratchAttached = true
 	}
+
 	logrus.Debugf("%s releasing cachedScratchMutex", title)
 	d.cachedScratchMutex.Unlock()
 
 	// If requested to start it with a mapped virtual disk, add it now.
-	if mvdToAdd != nil {
-		svm.config.MappedVirtualDisks = append(svm.config.MappedVirtualDisks, *mvdToAdd)
+	svm.config.MappedVirtualDisks = append(svm.config.MappedVirtualDisks, mvdToAdd...)
+	for _, mvd := range svm.config.MappedVirtualDisks {
+		svm.attachedVHDs[mvd.HostPath] = 1
 	}
 
 	// Start it.
 	logrus.Debugf("lcowdriver: startServiceVmIfNotRunning: (%s) starting %s", context, svm.config.Name)
-	if err := svm.config.Create(); err != nil {
+	if err := svm.config.StartUtilityVM(); err != nil {
 		return nil, fmt.Errorf("failed to start service utility VM (%s): %s", context, err)
 	}
 
-	// As it's now running, add it to the map, checking for a race where another
-	// thread has simultaneously tried to start it.
-	logrus.Debugf("%s locking serviceVmsMutex for insertion", title)
-	d.serviceVmsMutex.Lock()
-	if svm, ok := d.serviceVms[id]; ok {
-		logrus.Debugf("%s releasing serviceVmsMutex after insertion but exists", title)
-		d.serviceVmsMutex.Unlock()
-		return svm, nil
-	}
-	d.serviceVms[id] = svm
-	logrus.Debugf("%s releasing serviceVmsMutex after insertion", title)
-	d.serviceVmsMutex.Unlock()
+	// defer function to terminate the VM if the next steps fail
+	defer func() {
+		if err != nil {
+			waitTerminate(svm, fmt.Sprintf("startServiceVmIfNotRunning: %s (%s)", id, context))
+		}
+	}()
 
 	// Now we have a running service VM, we can create the cached scratch file if it doesn't exist.
 	logrus.Debugf("%s locking cachedScratchMutex", title)
 	d.cachedScratchMutex.Lock()
 	if _, err := os.Stat(d.cachedScratchFile); err != nil {
-		// TODO: Not a typo, but needs fixing when the platform sandbox stuff has been sorted out.
-		logrus.Debugf("%s (%s): creating an SVM scratch - locking serviceVM", title, context)
-		svm.Lock()
-		if err := svm.config.CreateSandbox(d.cachedScratchFile, client.DefaultSandboxSizeMB, d.cachedSandboxFile); err != nil {
-			logrus.Debugf("%s (%s): releasing serviceVM on error path", title, context)
-			svm.Unlock()
+		logrus.Debugf("%s (%s): creating an SVM scratch", title, context)
+
+		// Don't use svm.CreateExt4Vhdx since that only works when the service vm is setup,
+		// but we're still in that process right now.
+		if err := svm.config.CreateExt4Vhdx(scratchTargetFile, client.DefaultVhdxSizeGB, d.cachedScratchFile); err != nil {
 			logrus.Debugf("%s (%s): releasing cachedScratchMutex on error path", title, context)
 			d.cachedScratchMutex.Unlock()
-			// TODO: NEED TO REMOVE FROM MAP HERE AND STOP IT
+			logrus.Debugf("%s: failed to create vm scratch %s: %s", title, scratchTargetFile, err)
 			return nil, fmt.Errorf("failed to create SVM scratch VHDX (%s): %s", context, err)
 		}
-		logrus.Debugf("%s (%s): releasing serviceVM on error path", title, context)
-		svm.Unlock()
 	}
 	logrus.Debugf("%s (%s): releasing cachedScratchMutex", title, context)
 	d.cachedScratchMutex.Unlock()
 
 	// Hot-add the scratch-space if not already attached
 	if !svm.scratchAttached {
-		// Make a copy of it to the layer directory
-		logrus.Debugf("lcowdriver: startServiceVmIfNotRunning: (%s) cloning cached scratch for hot-add", context)
-		if err := client.CopyFile(d.cachedScratchFile, scratchTargetFile, true); err != nil {
-			// TODO: NEED TO REMOVE FROM MAP HERE AND STOP IT
-			return nil, err
-		}
-
-		logrus.Debugf("lcowdriver: startServiceVmIfNotRunning: (%s) hot-adding scratch %s - locking serviceVM", context, scratchTargetFile)
-		svm.Lock()
-		if err := svm.config.HotAddVhd(scratchTargetFile, toolsScratchPath); err != nil {
-			logrus.Debugf("%s (%s): releasing serviceVM on error path", title, context)
-			svm.Unlock()
-			// TODOL NEED TO REMOVE FROM MAP HERE AND STOP IT
+		logrus.Debugf("lcowdriver: startServiceVmIfNotRunning: (%s) hot-adding scratch %s", context, scratchTargetFile)
+		if err := svm.hotAddVHDsAtStart(hcsshim.MappedVirtualDisk{
+			HostPath:          scratchTargetFile,
+			ContainerPath:     toolsScratchPath,
+			CreateInUtilityVM: true,
+		}); err != nil {
+			logrus.Debugf("%s: failed to hot-add scratch %s: %s", title, scratchTargetFile, err)
 			return nil, fmt.Errorf("failed to hot-add %s failed: %s", scratchTargetFile, err)
 		}
-		logrus.Debugf("%s (%s): releasing serviceVM", title, context)
-		svm.Unlock()
+		svm.scratchAttached = true
 	}
 
 	logrus.Debugf("lcowdriver: startServiceVmIfNotRunning: (%s) success", context)
 	return svm, nil
 }
 
-// getServiceVM returns the appropriate service utility VM instance, optionally
-// deleting it from the map (but not the global one)
-func (d *Driver) getServiceVM(id string, deleteFromMap bool) (*serviceVMItem, error) {
-	logrus.Debugf("lcowdriver: getservicevm:locking serviceVmsMutex")
-	d.serviceVmsMutex.Lock()
-	defer func() {
-		logrus.Debugf("lcowdriver: getservicevm:releasing serviceVmsMutex")
-		d.serviceVmsMutex.Unlock()
-	}()
-	if d.globalMode {
-		id = svmGlobalID
-	}
-	if _, ok := d.serviceVms[id]; !ok {
-		return nil, fmt.Errorf("getservicevm for %s failed as not found", id)
-	}
-	svm := d.serviceVms[id]
-	if deleteFromMap && id != svmGlobalID {
-		logrus.Debugf("lcowdriver: getservicevm: removing %s from map", id)
-		delete(d.serviceVms, id)
-	}
-	return svm, nil
-}
-
-// terminateServiceVM terminates a service utility VM if its running, but does nothing
-// when in global mode as it's lifetime is limited to that of the daemon.
-func (d *Driver) terminateServiceVM(id, context string, force bool) error {
-
+// terminateServiceVM terminates a service utility VM if its running if it's,
+// not being used by any goroutine, but does nothing when in global mode as it's
+// lifetime is limited to that of the daemon. If the force flag is set, then
+// the VM will be killed regardless of the ref count or if it's global.
+func (d *Driver) terminateServiceVM(id, context string, force bool) (err error) {
 	// We don't do anything in safe mode unless the force flag has been passed, which
 	// is only the case for cleanup at driver termination.
-	if d.globalMode {
-		if !force {
-			logrus.Debugf("lcowdriver: terminateservicevm: %s (%s) - doing nothing as in global mode", id, context)
-			return nil
-		}
-		id = svmGlobalID
+	if d.globalMode && !force {
+		logrus.Debugf("lcowdriver: terminateservicevm: %s (%s) - doing nothing as in global mode", id, context)
+		return nil
 	}
 
-	// Get the service VM and delete it from the map
-	svm, err := d.getServiceVM(id, true)
-	if err != nil {
-		return err
+	id = d.getVMID(id)
+
+	var svm *serviceVM
+	var lastRef bool
+	if !force {
+		// In the not force case, we ref count
+		svm, lastRef, err = d.serviceVms.decrementRefCount(id)
+	} else {
+		// In the force case, we ignore the ref count and just set it to 0
+		svm, err = d.serviceVms.setRefCountZero(id)
+		lastRef = true
+	}
+
+	if err == errVMUnknown {
+		return nil
+	} else if err == errVMisTerminating {
+		return svm.getStopError()
+	} else if !lastRef {
+		return nil
 	}
 
 	// We run the deletion of the scratch as a deferred function to at least attempt
@@ -386,29 +394,67 @@
 		if svm.scratchAttached {
 			scratchTargetFile := filepath.Join(d.dataRoot, scratchDirectory, fmt.Sprintf("%s.vhdx", id))
 			logrus.Debugf("lcowdriver: terminateservicevm: %s (%s) - deleting scratch %s", id, context, scratchTargetFile)
-			if err := os.Remove(scratchTargetFile); err != nil {
-				logrus.Warnf("failed to remove scratch file %s (%s): %s", scratchTargetFile, context, err)
+			if errRemove := os.Remove(scratchTargetFile); errRemove != nil {
+				logrus.Warnf("failed to remove scratch file %s (%s): %s", scratchTargetFile, context, errRemove)
+				err = errRemove
 			}
 		}
+
+		// This function shouldn't actually return error unless there is a bug
+		if errDelete := d.serviceVms.deleteID(id); errDelete != nil {
+			logrus.Warnf("failed to service vm from svm map %s (%s): %s", id, context, errDelete)
+		}
+
+		// Signal that this VM has stopped
+		svm.signalStopFinished(err)
 	}()
 
-	// Nothing to do if it's not running
-	if svm.config.Uvm != nil {
-		logrus.Debugf("lcowdriver: terminateservicevm: %s (%s) - calling terminate", id, context)
-		if err := svm.config.Uvm.Terminate(); err != nil {
-			return fmt.Errorf("failed to terminate utility VM (%s): %s", context, err)
-		}
+	// Now it's possible that the serivce VM failed to start and now we are trying to termiante it.
+	// In this case, we will relay the error to the goroutines waiting for this vm to stop.
+	if err := svm.getStartError(); err != nil {
+		logrus.Debugf("lcowdriver: terminateservicevm: %s had failed to start up: %s", id, err)
+		return err
+	}
 
-		logrus.Debugf("lcowdriver: terminateservicevm: %s (%s) - waiting for utility VM to terminate", id, context)
-		if err := svm.config.Uvm.WaitTimeout(time.Duration(svm.config.UvmTimeoutSeconds) * time.Second); err != nil {
-			return fmt.Errorf("failed waiting for utility VM to terminate (%s): %s", context, err)
-		}
+	if err := waitTerminate(svm, fmt.Sprintf("terminateservicevm: %s (%s)", id, context)); err != nil {
+		return err
 	}
 
 	logrus.Debugf("lcowdriver: terminateservicevm: %s (%s) - success", id, context)
 	return nil
 }
 
+func waitTerminate(svm *serviceVM, context string) error {
+	if svm.config == nil {
+		return fmt.Errorf("lcowdriver: waitTermiante: Nil utility VM. %s", context)
+	}
+
+	logrus.Debugf("lcowdriver: waitTerminate: Calling terminate: %s", context)
+	if err := svm.config.Uvm.Terminate(); err != nil {
+		// We might get operation still pending from the HCS. In that case, we shouldn't return
+		// an error since we call wait right after.
+		underlyingError := err
+		if conterr, ok := err.(*hcsshim.ContainerError); ok {
+			underlyingError = conterr.Err
+		}
+
+		if syscallErr, ok := underlyingError.(syscall.Errno); ok {
+			underlyingError = syscallErr
+		}
+
+		if underlyingError != errOperationPending {
+			return fmt.Errorf("failed to terminate utility VM (%s): %s", context, err)
+		}
+		logrus.Debugf("lcowdriver: waitTerminate: uvm.Terminate() returned operation pending (%s)", context)
+	}
+
+	logrus.Debugf("lcowdriver: waitTerminate: (%s) - waiting for utility VM to terminate", context)
+	if err := svm.config.Uvm.WaitTimeout(time.Duration(svm.config.UvmTimeoutSeconds) * time.Second); err != nil {
+		return fmt.Errorf("failed waiting for utility VM to terminate (%s): %s", context, err)
+	}
+	return nil
+}
+
 // String returns the string representation of a driver. This should match
 // the name the graph driver has been registered with.
 func (d *Driver) String() string {
@@ -441,26 +487,43 @@
 		return err
 	}
 
+	// Look for an explicit sandbox size option.
+	sandboxSize := uint64(client.DefaultVhdxSizeGB)
+	for k, v := range opts.StorageOpt {
+		switch strings.ToLower(k) {
+		case "lcow.sandboxsize":
+			var err error
+			sandboxSize, err = strconv.ParseUint(v, 10, 32)
+			if err != nil {
+				return fmt.Errorf("%s failed to parse value '%s' for 'lcow.sandboxsize'", title, v)
+			}
+			if sandboxSize < client.DefaultVhdxSizeGB {
+				return fmt.Errorf("%s 'lcow.sandboxsize' option cannot be less than %d", title, client.DefaultVhdxSizeGB)
+			}
+			break
+		}
+	}
+
 	// Massive perf optimisation here. If we know that the RW layer is the default size,
 	// and that the cached sandbox already exists, and we are running in safe mode, we
 	// can just do a simple copy into the layers sandbox file without needing to start a
-	// unique service VM. For a global service VM, it doesn't really matter.
+	// unique service VM. For a global service VM, it doesn't really matter. Of course,
+	// this is only the case where the sandbox is the default size.
 	//
-	// TODO: @jhowardmsft Where are we going to get the required size from?
-	// We need to look at the CreateOpts for that, I think....
-
 	// Make sure we have the sandbox mutex taken while we are examining it.
-	logrus.Debugf("%s: locking cachedSandboxMutex", title)
-	d.cachedSandboxMutex.Lock()
-	_, err := os.Stat(d.cachedSandboxFile)
-	logrus.Debugf("%s: releasing cachedSandboxMutex", title)
-	d.cachedSandboxMutex.Unlock()
-	if err == nil {
-		logrus.Debugf("%s: using cached sandbox to populate", title)
-		if err := client.CopyFile(d.cachedSandboxFile, filepath.Join(d.dir(id), sandboxFilename), true); err != nil {
-			return err
+	if sandboxSize == client.DefaultVhdxSizeGB {
+		logrus.Debugf("%s: locking cachedSandboxMutex", title)
+		d.cachedSandboxMutex.Lock()
+		_, err := os.Stat(d.cachedSandboxFile)
+		logrus.Debugf("%s: releasing cachedSandboxMutex", title)
+		d.cachedSandboxMutex.Unlock()
+		if err == nil {
+			logrus.Debugf("%s: using cached sandbox to populate", title)
+			if err := client.CopyFile(d.cachedSandboxFile, filepath.Join(d.dir(id), sandboxFilename), true); err != nil {
+				return err
+			}
+			return nil
 		}
-		return nil
 	}
 
 	logrus.Debugf("%s: creating SVM to create sandbox", title)
@@ -470,25 +533,29 @@
 	}
 	defer d.terminateServiceVM(id, "createreadwrite", false)
 
-	// So the cached sandbox needs creating. Ensure we are the only thread creating it.
-	logrus.Debugf("%s: locking cachedSandboxMutex for creation", title)
-	d.cachedSandboxMutex.Lock()
-	defer func() {
-		logrus.Debugf("%s: releasing cachedSandboxMutex for creation", title)
-		d.cachedSandboxMutex.Unlock()
-	}()
-
-	// Synchronise the operation in the service VM.
-	logrus.Debugf("%s: locking svm for sandbox creation", title)
-	svm.Lock()
-	defer func() {
-		logrus.Debugf("%s: releasing svm for sandbox creation", title)
-		svm.Unlock()
-	}()
-	if err := svm.config.CreateSandbox(filepath.Join(d.dir(id), sandboxFilename), client.DefaultSandboxSizeMB, d.cachedSandboxFile); err != nil {
-		return err
+	// So the sandbox needs creating. If default size ensure we are the only thread populating the cache.
+	// Non-default size we don't store, just create them one-off so no need to lock the cachedSandboxMutex.
+	if sandboxSize == client.DefaultVhdxSizeGB {
+		logrus.Debugf("%s: locking cachedSandboxMutex for creation", title)
+		d.cachedSandboxMutex.Lock()
+		defer func() {
+			logrus.Debugf("%s: releasing cachedSandboxMutex for creation", title)
+			d.cachedSandboxMutex.Unlock()
+		}()
 	}
 
+	// Make sure we don't write to our local cached copy if this is for a non-default size request.
+	targetCacheFile := d.cachedSandboxFile
+	if sandboxSize != client.DefaultVhdxSizeGB {
+		targetCacheFile = ""
+	}
+
+	// Create the ext4 vhdx
+	logrus.Debugf("%s: creating sandbox ext4 vhdx", title)
+	if err := svm.createExt4VHDX(filepath.Join(d.dir(id), sandboxFilename), uint32(sandboxSize), targetCacheFile); err != nil {
+		logrus.Debugf("%s: failed to create sandbox vhdx for %s: %s", title, id, err)
+		return err
+	}
 	return nil
 }
 
@@ -537,6 +604,21 @@
 	layerPath := d.dir(id)
 
 	logrus.Debugf("lcowdriver: remove: id %s: layerPath %s", id, layerPath)
+
+	// Unmount all the layers
+	err := d.Put(id)
+	if err != nil {
+		logrus.Debugf("lcowdriver: remove id %s: failed to unmount: %s", id, err)
+		return err
+	}
+
+	// for non-global case just kill the vm
+	if !d.globalMode {
+		if err := d.terminateServiceVM(id, fmt.Sprintf("Remove %s", id), true); err != nil {
+			return err
+		}
+	}
+
 	if err := os.Rename(layerPath, tmpLayerPath); err != nil && !os.IsNotExist(err) {
 		return err
 	}
@@ -558,48 +640,24 @@
 // For optimisation, we don't actually mount the filesystem (which in our
 // case means [hot-]adding it to a service VM. But we track that and defer
 // the actual adding to the point we need to access it.
-func (d *Driver) Get(id, mountLabel string) (string, error) {
+func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	title := fmt.Sprintf("lcowdriver: get: %s", id)
 	logrus.Debugf(title)
 
-	// Work out what we are working on
-	vhdFilename, vhdSize, isSandbox, err := getLayerDetails(d.dir(id))
+	// Generate the mounts needed for the defered operation.
+	disks, err := d.getAllMounts(id)
 	if err != nil {
-		logrus.Debugf("%s failed to get layer details from %s: %s", title, d.dir(id), err)
-		return "", fmt.Errorf("%s failed to open layer or sandbox VHD to open in %s: %s", title, d.dir(id), err)
+		logrus.Debugf("%s failed to get all layer details for %s: %s", title, d.dir(id), err)
+		return nil, fmt.Errorf("%s failed to get layer details for %s: %s", title, d.dir(id), err)
 	}
-	logrus.Debugf("%s %s, size %d, isSandbox %t", title, vhdFilename, vhdSize, isSandbox)
 
-	// Add item to cache, or update existing item, but ensure we have the
-	// lock while updating items.
-	logrus.Debugf("%s: locking cacheMutex", title)
-	d.cacheMutex.Lock()
-	var cacheEntry *cacheItem
-	if entry, ok := d.cache[id]; !ok {
-		// The item is not currently in the cache.
-		cacheEntry = &cacheItem{
-			refCount:  1,
-			isSandbox: isSandbox,
-			hostPath:  vhdFilename,
-			uvmPath:   fmt.Sprintf("/mnt/%s", id),
-			isMounted: false, // we defer this as an optimisation
-		}
-		d.cache[id] = cacheEntry
-		logrus.Debugf("%s: added cache entry %+v", title, cacheEntry)
-	} else {
-		// Increment the reference counter in the cache.
-		logrus.Debugf("%s: locking cache item for increment", title)
-		entry.Lock()
-		entry.refCount++
-		logrus.Debugf("%s: releasing cache item for increment", title)
-		entry.Unlock()
-		logrus.Debugf("%s: incremented refcount on cache entry %+v", title, cacheEntry)
-	}
-	logrus.Debugf("%s: releasing cacheMutex", title)
-	d.cacheMutex.Unlock()
-
-	logrus.Debugf("%s %s success. %s: %+v: size %d", title, id, d.dir(id), cacheEntry, vhdSize)
-	return d.dir(id), nil
+	logrus.Debugf("%s: got layer mounts: %+v", title, disks)
+	return &lcowfs{
+		root:        unionMountName(disks),
+		d:           d,
+		mappedDisks: disks,
+		vmID:        d.getVMID(id),
+	}, nil
 }
 
 // Put does the reverse of get. If there are no more references to
@@ -607,70 +665,45 @@
 func (d *Driver) Put(id string) error {
 	title := fmt.Sprintf("lcowdriver: put: %s", id)
 
-	logrus.Debugf("%s: locking cacheMutex", title)
-	d.cacheMutex.Lock()
-	entry, ok := d.cache[id]
-	if !ok {
-		logrus.Debugf("%s: releasing cacheMutex on error path", title)
-		d.cacheMutex.Unlock()
-		return fmt.Errorf("%s possible ref-count error, or invalid id was passed to the graphdriver. Cannot handle id %s as it's not in the cache", title, id)
-	}
-
-	// Are we just decrementing the reference count?
-	logrus.Debugf("%s: locking cache item for possible decrement", title)
-	entry.Lock()
-	if entry.refCount > 1 {
-		entry.refCount--
-		logrus.Debugf("%s: releasing cache item for decrement and early get-out as refCount is now %d", title, entry.refCount)
-		entry.Unlock()
-		logrus.Debugf("%s: refCount decremented to %d. Releasing cacheMutex", title, entry.refCount)
-		d.cacheMutex.Unlock()
+	// Get the service VM that we need to remove from
+	svm, err := d.serviceVms.get(d.getVMID(id))
+	if err == errVMUnknown {
 		return nil
+	} else if err == errVMisTerminating {
+		return svm.getStopError()
 	}
-	logrus.Debugf("%s: releasing cache item", title)
-	entry.Unlock()
-	logrus.Debugf("%s: releasing cacheMutex. Ref count has dropped to zero", title)
-	d.cacheMutex.Unlock()
 
-	// To reach this point, the reference count has dropped to zero. If we have
-	// done a mount and we are in global mode, then remove it. We don't
-	// need to remove in safe mode as the service VM is going to be torn down
-	// anyway.
+	// Generate the mounts that Get() might have mounted
+	disks, err := d.getAllMounts(id)
+	if err != nil {
+		logrus.Debugf("%s failed to get all layer details for %s: %s", title, d.dir(id), err)
+		return fmt.Errorf("%s failed to get layer details for %s: %s", title, d.dir(id), err)
+	}
 
-	if d.globalMode {
-		logrus.Debugf("%s: locking cache item at zero ref-count", title)
-		entry.Lock()
-		defer func() {
-			logrus.Debugf("%s: releasing cache item at zero ref-count", title)
-			entry.Unlock()
-		}()
-		if entry.isMounted {
-			svm, err := d.getServiceVM(id, false)
-			if err != nil {
-				return err
-			}
+	// Now, we want to perform the unmounts, hot-remove and stop the service vm.
+	// We want to go though all the steps even if we have an error to clean up properly
+	err = svm.deleteUnionMount(unionMountName(disks), disks...)
+	if err != nil {
+		logrus.Debugf("%s failed to delete union mount %s: %s", title, id, err)
+	}
 
-			logrus.Debugf("%s: Hot-Removing %s. Locking svm", title, entry.hostPath)
-			svm.Lock()
-			if err := svm.config.HotRemoveVhd(entry.hostPath); err != nil {
-				logrus.Debugf("%s: releasing svm on error path", title)
-				svm.Unlock()
-				return fmt.Errorf("%s failed to hot-remove %s from global service utility VM: %s", title, entry.hostPath, err)
-			}
-			logrus.Debugf("%s: releasing svm", title)
-			svm.Unlock()
+	err1 := svm.hotRemoveVHDs(disks...)
+	if err1 != nil {
+		logrus.Debugf("%s failed to hot remove vhds %s: %s", title, id, err)
+		if err == nil {
+			err = err1
 		}
 	}
 
-	// Remove from the cache map.
-	logrus.Debugf("%s: Locking cacheMutex to delete item from cache", title)
-	d.cacheMutex.Lock()
-	delete(d.cache, id)
-	logrus.Debugf("%s: releasing cacheMutex after item deleted from cache", title)
-	d.cacheMutex.Unlock()
-
-	logrus.Debugf("%s %s: refCount 0. %s (%s) completed successfully", title, id, entry.hostPath, entry.uvmPath)
-	return nil
+	err1 = d.terminateServiceVM(id, fmt.Sprintf("Put %s", id), false)
+	if err1 != nil {
+		logrus.Debugf("%s failed to terminate service vm %s: %s", title, id, err1)
+		if err == nil {
+			err = err1
+		}
+	}
+	logrus.Debugf("Put succeeded on id %s", id)
+	return err
 }
 
 // Cleanup ensures the information the driver stores is properly removed.
@@ -679,15 +712,6 @@
 func (d *Driver) Cleanup() error {
 	title := "lcowdriver: cleanup"
 
-	d.cacheMutex.Lock()
-	for k, v := range d.cache {
-		logrus.Debugf("%s cache entry: %s: %+v", title, k, v)
-		if v.refCount > 0 {
-			logrus.Warnf("%s leaked %s: %+v", title, k, v)
-		}
-	}
-	d.cacheMutex.Unlock()
-
 	items, err := ioutil.ReadDir(d.dataRoot)
 	if err != nil {
 		if os.IsNotExist(err) {
@@ -712,7 +736,7 @@
 
 	// Cleanup any service VMs we have running, along with their scratch spaces.
 	// We don't take the lock for this as it's taken in terminateServiceVm.
-	for k, v := range d.serviceVms {
+	for k, v := range d.serviceVms.svms {
 		logrus.Debugf("%s svm entry: %s: %+v", title, k, v)
 		d.terminateServiceVM(k, "cleanup", true)
 	}
@@ -730,69 +754,41 @@
 func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
 	title := fmt.Sprintf("lcowdriver: diff: %s", id)
 
-	logrus.Debugf("%s: locking cacheMutex", title)
-	d.cacheMutex.Lock()
-	if _, ok := d.cache[id]; !ok {
-		logrus.Debugf("%s: releasing cacheMutex on error path", title)
-		d.cacheMutex.Unlock()
-		return nil, fmt.Errorf("%s fail as %s is not in the cache", title, id)
-	}
-	cacheEntry := d.cache[id]
-	logrus.Debugf("%s: releasing cacheMutex", title)
-	d.cacheMutex.Unlock()
-
-	// Stat to get size
-	logrus.Debugf("%s: locking cacheEntry", title)
-	cacheEntry.Lock()
-	fileInfo, err := os.Stat(cacheEntry.hostPath)
+	// Get VHDX info
+	ld, err := getLayerDetails(d.dir(id))
 	if err != nil {
-		logrus.Debugf("%s: releasing cacheEntry on error path", title)
-		cacheEntry.Unlock()
-		return nil, fmt.Errorf("%s failed to stat %s: %s", title, cacheEntry.hostPath, err)
+		logrus.Debugf("%s: failed to get vhdx information of %s: %s", title, d.dir(id), err)
+		return nil, err
 	}
-	logrus.Debugf("%s: releasing cacheEntry", title)
-	cacheEntry.Unlock()
 
 	// Start the SVM with a mapped virtual disk. Note that if the SVM is
-	// already runing and we are in global mode, this will be
+	// already running and we are in global mode, this will be
 	// hot-added.
-	mvd := &hcsshim.MappedVirtualDisk{
-		HostPath:          cacheEntry.hostPath,
-		ContainerPath:     cacheEntry.uvmPath,
+	mvd := hcsshim.MappedVirtualDisk{
+		HostPath:          ld.filename,
+		ContainerPath:     hostToGuest(ld.filename),
 		CreateInUtilityVM: true,
 		ReadOnly:          true,
 	}
 
 	logrus.Debugf("%s: starting service VM", title)
-	svm, err := d.startServiceVMIfNotRunning(id, mvd, fmt.Sprintf("diff %s", id))
+	svm, err := d.startServiceVMIfNotRunning(id, []hcsshim.MappedVirtualDisk{mvd}, fmt.Sprintf("diff %s", id))
 	if err != nil {
 		return nil, err
 	}
 
-	// Set `isMounted` for the cache entry. Note that we re-scan the cache
-	// at this point as it's possible the cacheEntry changed during the long-
-	// running operation above when we weren't holding the cacheMutex lock.
-	logrus.Debugf("%s: locking cacheMutex for updating isMounted", title)
-	d.cacheMutex.Lock()
-	if _, ok := d.cache[id]; !ok {
-		logrus.Debugf("%s: releasing cacheMutex on error path of isMounted", title)
-		d.cacheMutex.Unlock()
+	logrus.Debugf("lcowdriver: diff: waiting for svm to finish booting")
+	err = svm.getStartError()
+	if err != nil {
 		d.terminateServiceVM(id, fmt.Sprintf("diff %s", id), false)
-		return nil, fmt.Errorf("%s fail as %s is not in the cache when updating isMounted", title, id)
+		return nil, fmt.Errorf("lcowdriver: diff: svm failed to boot: %s", err)
 	}
-	cacheEntry = d.cache[id]
-	logrus.Debugf("%s: locking cacheEntry for updating isMounted", title)
-	cacheEntry.Lock()
-	cacheEntry.isMounted = true
-	logrus.Debugf("%s: releasing cacheEntry for updating isMounted", title)
-	cacheEntry.Unlock()
-	logrus.Debugf("%s: releasing cacheMutex for updating isMounted", title)
-	d.cacheMutex.Unlock()
 
 	// Obtain the tar stream for it
-	logrus.Debugf("%s %s, size %d, isSandbox %t", title, cacheEntry.hostPath, fileInfo.Size(), cacheEntry.isSandbox)
-	tarReadCloser, err := svm.config.VhdToTar(cacheEntry.hostPath, cacheEntry.uvmPath, cacheEntry.isSandbox, fileInfo.Size())
+	logrus.Debugf("%s: %s %s, size %d, ReadOnly %t", title, ld.filename, mvd.ContainerPath, ld.size, ld.isSandbox)
+	tarReadCloser, err := svm.config.VhdToTar(mvd.HostPath, mvd.ContainerPath, ld.isSandbox, ld.size)
 	if err != nil {
+		svm.hotRemoveVHDs(mvd)
 		d.terminateServiceVM(id, fmt.Sprintf("diff %s", id), false)
 		return nil, fmt.Errorf("%s failed to export layer to tar stream for id: %s, parent: %s : %s", title, id, parent, err)
 	}
@@ -800,14 +796,12 @@
 	logrus.Debugf("%s id %s parent %s completed successfully", title, id, parent)
 
 	// In safe/non-global mode, we can't tear down the service VM until things have been read.
-	if !d.globalMode {
-		return ioutils.NewReadCloserWrapper(tarReadCloser, func() error {
-			tarReadCloser.Close()
-			d.terminateServiceVM(id, fmt.Sprintf("diff %s", id), false)
-			return nil
-		}), nil
-	}
-	return tarReadCloser, nil
+	return ioutils.NewReadCloserWrapper(tarReadCloser, func() error {
+		tarReadCloser.Close()
+		svm.hotRemoveVHDs(mvd)
+		d.terminateServiceVM(id, fmt.Sprintf("diff %s", id), false)
+		return nil
+	}), nil
 }
 
 // ApplyDiff extracts the changeset from the given diff into the
@@ -824,6 +818,12 @@
 	}
 	defer d.terminateServiceVM(id, fmt.Sprintf("applydiff %s", id), false)
 
+	logrus.Debugf("lcowdriver: applydiff: waiting for svm to finish booting")
+	err = svm.getStartError()
+	if err != nil {
+		return 0, fmt.Errorf("lcowdriver: applydiff: svm failed to boot: %s", err)
+	}
+
 	// TODO @jhowardmsft - the retries are temporary to overcome platform reliablity issues.
 	// Obviously this will be removed as platform bugs are fixed.
 	retries := 0
@@ -866,6 +866,11 @@
 	return m, nil
 }
 
+// GetLayerPath gets the layer path on host (path to VHD/VHDX)
+func (d *Driver) GetLayerPath(id string) (string, error) {
+	return d.dir(id), nil
+}
+
 // dir returns the absolute path to the layer.
 func (d *Driver) dir(id string) string {
 	return filepath.Join(d.dataRoot, filepath.Base(id))
@@ -909,21 +914,53 @@
 // getLayerDetails is a utility for getting a file name, size and indication of
 // sandbox for a VHD(x) in a folder. A read-only layer will be layer.vhd. A
 // read-write layer will be sandbox.vhdx.
-func getLayerDetails(folder string) (string, int64, bool, error) {
+func getLayerDetails(folder string) (*layerDetails, error) {
 	var fileInfo os.FileInfo
-	isSandbox := false
-	filename := filepath.Join(folder, layerFilename)
-	var err error
-
-	if fileInfo, err = os.Stat(filename); err != nil {
-		filename = filepath.Join(folder, sandboxFilename)
-		if fileInfo, err = os.Stat(filename); err != nil {
-			if os.IsNotExist(err) {
-				return "", 0, isSandbox, fmt.Errorf("could not find layer or sandbox in %s", folder)
-			}
-			return "", 0, isSandbox, fmt.Errorf("error locating layer or sandbox in %s: %s", folder, err)
-		}
-		isSandbox = true
+	ld := &layerDetails{
+		isSandbox: false,
+		filename:  filepath.Join(folder, layerFilename),
 	}
-	return filename, fileInfo.Size(), isSandbox, nil
+
+	fileInfo, err := os.Stat(ld.filename)
+	if err != nil {
+		ld.filename = filepath.Join(folder, sandboxFilename)
+		if fileInfo, err = os.Stat(ld.filename); err != nil {
+			return nil, fmt.Errorf("failed to locate layer or sandbox in %s", folder)
+		}
+		ld.isSandbox = true
+	}
+	ld.size = fileInfo.Size()
+
+	return ld, nil
+}
+
+func (d *Driver) getAllMounts(id string) ([]hcsshim.MappedVirtualDisk, error) {
+	layerChain, err := d.getLayerChain(id)
+	if err != nil {
+		return nil, err
+	}
+	layerChain = append([]string{d.dir(id)}, layerChain...)
+
+	logrus.Debugf("getting all  layers: %v", layerChain)
+	disks := make([]hcsshim.MappedVirtualDisk, len(layerChain), len(layerChain))
+	for i := range layerChain {
+		ld, err := getLayerDetails(layerChain[i])
+		if err != nil {
+			logrus.Debugf("Failed to get LayerVhdDetails from %s: %s", layerChain[i], err)
+			return nil, err
+		}
+		disks[i].HostPath = ld.filename
+		disks[i].ContainerPath = hostToGuest(ld.filename)
+		disks[i].CreateInUtilityVM = true
+		disks[i].ReadOnly = !ld.isSandbox
+	}
+	return disks, nil
+}
+
+func hostToGuest(hostpath string) string {
+	return fmt.Sprintf("/tmp/%s", filepath.Base(filepath.Dir(hostpath)))
+}
+
+func unionMountName(disks []hcsshim.MappedVirtualDisk) string {
+	return fmt.Sprintf("%s-mount", disks[0].ContainerPath)
 }
diff --git a/daemon/graphdriver/lcow/lcow_svm.go b/daemon/graphdriver/lcow/lcow_svm.go
new file mode 100644
index 0000000..26f6df4
--- /dev/null
+++ b/daemon/graphdriver/lcow/lcow_svm.go
@@ -0,0 +1,373 @@
+// +build windows
+
+package lcow
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/Microsoft/hcsshim"
+	"github.com/Microsoft/opengcs/client"
+	"github.com/sirupsen/logrus"
+)
+
+// Code for all the service VM management for the LCOW graphdriver
+
+var errVMisTerminating = errors.New("service VM is shutting down")
+var errVMUnknown = errors.New("service vm id is unknown")
+var errVMStillHasReference = errors.New("Attemping to delete a VM that is still being used")
+
+// serviceVMMap is the struct representing the id -> service VM mapping.
+type serviceVMMap struct {
+	sync.Mutex
+	svms map[string]*serviceVMMapItem
+}
+
+// serviceVMMapItem is our internal structure representing an item in our
+// map of service VMs we are maintaining.
+type serviceVMMapItem struct {
+	svm      *serviceVM // actual service vm object
+	refCount int        // refcount for VM
+}
+
+type serviceVM struct {
+	sync.Mutex                     // Serialises operations being performed in this service VM.
+	scratchAttached bool           // Has a scratch been attached?
+	config          *client.Config // Represents the service VM item.
+
+	// Indicates that the vm is started
+	startStatus chan interface{}
+	startError  error
+
+	// Indicates that the vm is stopped
+	stopStatus chan interface{}
+	stopError  error
+
+	attachedVHDs map[string]int // Map ref counting all the VHDS we've hot-added/hot-removed.
+	unionMounts  map[string]int // Map ref counting all the union filesystems we mounted.
+}
+
+// add will add an id to the service vm map. There are three cases:
+// 	- entry doesn't exist:
+// 		- add id to map and return a new vm that the caller can manually configure+start
+//	- entry does exist
+//  	- return vm in map and increment ref count
+//  - entry does exist but the ref count is 0
+//		- return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
+func (svmMap *serviceVMMap) add(id string) (svm *serviceVM, alreadyExists bool, err error) {
+	svmMap.Lock()
+	defer svmMap.Unlock()
+	if svm, ok := svmMap.svms[id]; ok {
+		if svm.refCount == 0 {
+			return svm.svm, true, errVMisTerminating
+		}
+		svm.refCount++
+		return svm.svm, true, nil
+	}
+
+	// Doesn't exist, so create an empty svm to put into map and return
+	newSVM := &serviceVM{
+		startStatus:  make(chan interface{}),
+		stopStatus:   make(chan interface{}),
+		attachedVHDs: make(map[string]int),
+		unionMounts:  make(map[string]int),
+		config:       &client.Config{},
+	}
+	svmMap.svms[id] = &serviceVMMapItem{
+		svm:      newSVM,
+		refCount: 1,
+	}
+	return newSVM, false, nil
+}
+
+// get will get the service vm from the map. There are three cases:
+// 	- entry doesn't exist:
+// 		- return errVMUnknown
+//	- entry does exist
+//  	- return vm with no error
+//  - entry does exist but the ref count is 0
+//		- return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
+func (svmMap *serviceVMMap) get(id string) (*serviceVM, error) {
+	svmMap.Lock()
+	defer svmMap.Unlock()
+	svm, ok := svmMap.svms[id]
+	if !ok {
+		return nil, errVMUnknown
+	}
+	if svm.refCount == 0 {
+		return svm.svm, errVMisTerminating
+	}
+	return svm.svm, nil
+}
+
+// decrementRefCount decrements the ref count of the given ID from the map. There are four cases:
+// 	- entry doesn't exist:
+// 		- return errVMUnknown
+//  - entry does exist but the ref count is 0
+//		- return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
+//	- entry does exist but ref count is 1
+//  	- return vm and set lastRef to true. The caller can then stop the vm, delete the id from this map
+//      - and execute svm.signalStopFinished to signal the threads that the svm has been terminated.
+//	- entry does exist and ref count > 1
+//		- just reduce ref count and return svm
+func (svmMap *serviceVMMap) decrementRefCount(id string) (_ *serviceVM, lastRef bool, _ error) {
+	svmMap.Lock()
+	defer svmMap.Unlock()
+
+	svm, ok := svmMap.svms[id]
+	if !ok {
+		return nil, false, errVMUnknown
+	}
+	if svm.refCount == 0 {
+		return svm.svm, false, errVMisTerminating
+	}
+	svm.refCount--
+	return svm.svm, svm.refCount == 0, nil
+}
+
+// setRefCountZero works the same way as decrementRefCount, but sets ref count to 0 instead of decrementing it.
+func (svmMap *serviceVMMap) setRefCountZero(id string) (*serviceVM, error) {
+	svmMap.Lock()
+	defer svmMap.Unlock()
+
+	svm, ok := svmMap.svms[id]
+	if !ok {
+		return nil, errVMUnknown
+	}
+	if svm.refCount == 0 {
+		return svm.svm, errVMisTerminating
+	}
+	svm.refCount = 0
+	return svm.svm, nil
+}
+
+// deleteID deletes the given ID from the map. If the refcount is not 0 or the
+// VM does not exist, then this function returns an error.
+func (svmMap *serviceVMMap) deleteID(id string) error {
+	svmMap.Lock()
+	defer svmMap.Unlock()
+	svm, ok := svmMap.svms[id]
+	if !ok {
+		return errVMUnknown
+	}
+	if svm.refCount != 0 {
+		return errVMStillHasReference
+	}
+	delete(svmMap.svms, id)
+	return nil
+}
+
+func (svm *serviceVM) signalStartFinished(err error) {
+	svm.Lock()
+	svm.startError = err
+	svm.Unlock()
+	close(svm.startStatus)
+}
+
+func (svm *serviceVM) getStartError() error {
+	<-svm.startStatus
+	svm.Lock()
+	defer svm.Unlock()
+	return svm.startError
+}
+
+func (svm *serviceVM) signalStopFinished(err error) {
+	svm.Lock()
+	svm.stopError = err
+	svm.Unlock()
+	close(svm.stopStatus)
+}
+
+func (svm *serviceVM) getStopError() error {
+	<-svm.stopStatus
+	svm.Lock()
+	defer svm.Unlock()
+	return svm.stopError
+}
+
+// hotAddVHDs waits for the service vm to start and then attaches the vhds.
+func (svm *serviceVM) hotAddVHDs(mvds ...hcsshim.MappedVirtualDisk) error {
+	if err := svm.getStartError(); err != nil {
+		return err
+	}
+	return svm.hotAddVHDsAtStart(mvds...)
+}
+
+// hotAddVHDsAtStart works the same way as hotAddVHDs but does not wait for the VM to start.
+func (svm *serviceVM) hotAddVHDsAtStart(mvds ...hcsshim.MappedVirtualDisk) error {
+	svm.Lock()
+	defer svm.Unlock()
+	for i, mvd := range mvds {
+		if _, ok := svm.attachedVHDs[mvd.HostPath]; ok {
+			svm.attachedVHDs[mvd.HostPath]++
+			continue
+		}
+
+		if err := svm.config.HotAddVhd(mvd.HostPath, mvd.ContainerPath, mvd.ReadOnly, !mvd.AttachOnly); err != nil {
+			svm.hotRemoveVHDsAtStart(mvds[:i]...)
+			return err
+		}
+		svm.attachedVHDs[mvd.HostPath] = 1
+	}
+	return nil
+}
+
+// hotRemoveVHDs waits for the service vm to start and then removes the vhds.
+func (svm *serviceVM) hotRemoveVHDs(mvds ...hcsshim.MappedVirtualDisk) error {
+	if err := svm.getStartError(); err != nil {
+		return err
+	}
+	return svm.hotRemoveVHDsAtStart(mvds...)
+}
+
+// hotRemoveVHDsAtStart works the same way as hotRemoveVHDs but does not wait for the VM to start.
+func (svm *serviceVM) hotRemoveVHDsAtStart(mvds ...hcsshim.MappedVirtualDisk) error {
+	svm.Lock()
+	defer svm.Unlock()
+	var retErr error
+	for _, mvd := range mvds {
+		if _, ok := svm.attachedVHDs[mvd.HostPath]; !ok {
+			// We continue instead of returning an error if we try to hot remove a non-existent VHD.
+			// This is because one of the callers of the function is graphdriver.Put(). Since graphdriver.Get()
+			// defers the VM start to the first operation, it's possible that nothing have been hot-added
+			// when Put() is called. To avoid Put returning an error in that case, we simply continue if we
+			// don't find the vhd attached.
+			continue
+		}
+
+		if svm.attachedVHDs[mvd.HostPath] > 1 {
+			svm.attachedVHDs[mvd.HostPath]--
+			continue
+		}
+
+		// last VHD, so remove from VM and map
+		if err := svm.config.HotRemoveVhd(mvd.HostPath); err == nil {
+			delete(svm.attachedVHDs, mvd.HostPath)
+		} else {
+			// Take note of the error, but still continue to remove the other VHDs
+			logrus.Warnf("Failed to hot remove %s: %s", mvd.HostPath, err)
+			if retErr == nil {
+				retErr = err
+			}
+		}
+	}
+	return retErr
+}
+
+func (svm *serviceVM) createExt4VHDX(destFile string, sizeGB uint32, cacheFile string) error {
+	if err := svm.getStartError(); err != nil {
+		return err
+	}
+
+	svm.Lock()
+	defer svm.Unlock()
+	return svm.config.CreateExt4Vhdx(destFile, sizeGB, cacheFile)
+}
+
+func (svm *serviceVM) createUnionMount(mountName string, mvds ...hcsshim.MappedVirtualDisk) (err error) {
+	if len(mvds) == 0 {
+		return fmt.Errorf("createUnionMount: error must have at least 1 layer")
+	}
+
+	if err = svm.getStartError(); err != nil {
+		return err
+	}
+
+	svm.Lock()
+	defer svm.Unlock()
+	if _, ok := svm.unionMounts[mountName]; ok {
+		svm.unionMounts[mountName]++
+		return nil
+	}
+
+	var lowerLayers []string
+	if mvds[0].ReadOnly {
+		lowerLayers = append(lowerLayers, mvds[0].ContainerPath)
+	}
+
+	for i := 1; i < len(mvds); i++ {
+		lowerLayers = append(lowerLayers, mvds[i].ContainerPath)
+	}
+
+	logrus.Debugf("Doing the overlay mount with union directory=%s", mountName)
+	if err = svm.runProcess(fmt.Sprintf("mkdir -p %s", mountName), nil, nil, nil); err != nil {
+		return err
+	}
+
+	var cmd string
+	if mvds[0].ReadOnly {
+		// Readonly overlay
+		cmd = fmt.Sprintf("mount -t overlay overlay -olowerdir=%s %s",
+			strings.Join(lowerLayers, ","),
+			mountName)
+	} else {
+		upper := fmt.Sprintf("%s/upper", mvds[0].ContainerPath)
+		work := fmt.Sprintf("%s/work", mvds[0].ContainerPath)
+
+		if err = svm.runProcess(fmt.Sprintf("mkdir -p %s %s", upper, work), nil, nil, nil); err != nil {
+			return err
+		}
+
+		cmd = fmt.Sprintf("mount -t overlay overlay -olowerdir=%s,upperdir=%s,workdir=%s %s",
+			strings.Join(lowerLayers, ":"),
+			upper,
+			work,
+			mountName)
+	}
+
+	logrus.Debugf("createUnionMount: Executing mount=%s", cmd)
+	if err = svm.runProcess(cmd, nil, nil, nil); err != nil {
+		return err
+	}
+
+	svm.unionMounts[mountName] = 1
+	return nil
+}
+
+func (svm *serviceVM) deleteUnionMount(mountName string, disks ...hcsshim.MappedVirtualDisk) error {
+	if err := svm.getStartError(); err != nil {
+		return err
+	}
+
+	svm.Lock()
+	defer svm.Unlock()
+	if _, ok := svm.unionMounts[mountName]; !ok {
+		return nil
+	}
+
+	if svm.unionMounts[mountName] > 1 {
+		svm.unionMounts[mountName]--
+		return nil
+	}
+
+	logrus.Debugf("Removing union mount %s", mountName)
+	if err := svm.runProcess(fmt.Sprintf("umount %s", mountName), nil, nil, nil); err != nil {
+		return err
+	}
+
+	delete(svm.unionMounts, mountName)
+	return nil
+}
+
+func (svm *serviceVM) runProcess(command string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
+	process, err := svm.config.RunProcess(command, stdin, stdout, stderr)
+	if err != nil {
+		return err
+	}
+	defer process.Close()
+
+	process.WaitTimeout(time.Duration(int(time.Second) * svm.config.UvmTimeoutSeconds))
+	exitCode, err := process.ExitCode()
+	if err != nil {
+		return err
+	}
+
+	if exitCode != 0 {
+		return fmt.Errorf("svm.runProcess: command %s failed with exit code %d", command, exitCode)
+	}
+	return nil
+}
diff --git a/daemon/graphdriver/lcow/remotefs.go b/daemon/graphdriver/lcow/remotefs.go
new file mode 100644
index 0000000..148e3c0
--- /dev/null
+++ b/daemon/graphdriver/lcow/remotefs.go
@@ -0,0 +1,139 @@
+// +build windows
+
+package lcow
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"runtime"
+	"strings"
+	"sync"
+
+	"github.com/Microsoft/hcsshim"
+	"github.com/Microsoft/opengcs/service/gcsutils/remotefs"
+	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
+	"github.com/sirupsen/logrus"
+)
+
+type lcowfs struct {
+	root        string
+	d           *Driver
+	mappedDisks []hcsshim.MappedVirtualDisk
+	vmID        string
+	currentSVM  *serviceVM
+	sync.Mutex
+}
+
+var _ containerfs.ContainerFS = &lcowfs{}
+
+// ErrNotSupported is an error for unsupported operations in the remotefs
+var ErrNotSupported = fmt.Errorf("not supported")
+
+// Functions to implement the ContainerFS interface
+func (l *lcowfs) Path() string {
+	return l.root
+}
+
+func (l *lcowfs) ResolveScopedPath(path string, rawPath bool) (string, error) {
+	logrus.Debugf("remotefs.resolvescopedpath inputs: %s %s ", path, l.root)
+
+	arg1 := l.Join(l.root, path)
+	if !rawPath {
+		// The l.Join("/", path) will make path an absolute path and then clean it
+		// so if path = ../../X, it will become /X.
+		arg1 = l.Join(l.root, l.Join("/", path))
+	}
+	arg2 := l.root
+
+	output := &bytes.Buffer{}
+	if err := l.runRemoteFSProcess(nil, output, remotefs.ResolvePathCmd, arg1, arg2); err != nil {
+		return "", err
+	}
+
+	logrus.Debugf("remotefs.resolvescopedpath success. Output: %s\n", output.String())
+	return output.String(), nil
+}
+
+func (l *lcowfs) OS() string {
+	return "linux"
+}
+
+func (l *lcowfs) Architecture() string {
+	return runtime.GOARCH
+}
+
+// Other functions that are used by docker like the daemon Archiver/Extractor
+func (l *lcowfs) ExtractArchive(src io.Reader, dst string, opts *archive.TarOptions) error {
+	logrus.Debugf("remotefs.ExtractArchve inputs: %s %+v", dst, opts)
+
+	tarBuf := &bytes.Buffer{}
+	if err := remotefs.WriteTarOptions(tarBuf, opts); err != nil {
+		return fmt.Errorf("failed to marshall tar opts: %s", err)
+	}
+
+	input := io.MultiReader(tarBuf, src)
+	if err := l.runRemoteFSProcess(input, nil, remotefs.ExtractArchiveCmd, dst); err != nil {
+		return fmt.Errorf("failed to extract archive to %s: %s", dst, err)
+	}
+	return nil
+}
+
+func (l *lcowfs) ArchivePath(src string, opts *archive.TarOptions) (io.ReadCloser, error) {
+	logrus.Debugf("remotefs.ArchivePath: %s %+v", src, opts)
+
+	tarBuf := &bytes.Buffer{}
+	if err := remotefs.WriteTarOptions(tarBuf, opts); err != nil {
+		return nil, fmt.Errorf("failed to marshall tar opts: %s", err)
+	}
+
+	r, w := io.Pipe()
+	go func() {
+		defer w.Close()
+		if err := l.runRemoteFSProcess(tarBuf, w, remotefs.ArchivePathCmd, src); err != nil {
+			logrus.Debugf("REMOTEFS: Failed to extract archive: %s %+v %s", src, opts, err)
+		}
+	}()
+	return r, nil
+}
+
+// Helper functions
+func (l *lcowfs) startVM() error {
+	l.Lock()
+	defer l.Unlock()
+	if l.currentSVM != nil {
+		return nil
+	}
+
+	svm, err := l.d.startServiceVMIfNotRunning(l.vmID, l.mappedDisks, fmt.Sprintf("lcowfs.startVM"))
+	if err != nil {
+		return err
+	}
+
+	if err = svm.createUnionMount(l.root, l.mappedDisks...); err != nil {
+		return err
+	}
+	l.currentSVM = svm
+	return nil
+}
+
+func (l *lcowfs) runRemoteFSProcess(stdin io.Reader, stdout io.Writer, args ...string) error {
+	if err := l.startVM(); err != nil {
+		return err
+	}
+
+	// Append remotefs prefix and setup as a command line string
+	cmd := fmt.Sprintf("%s %s", remotefs.RemotefsCmd, strings.Join(args, " "))
+	stderr := &bytes.Buffer{}
+	if err := l.currentSVM.runProcess(cmd, stdin, stdout, stderr); err != nil {
+		return err
+	}
+
+	eerr, err := remotefs.ReadError(stderr)
+	if eerr != nil {
+		// Process returned an error so return that.
+		return remotefs.ExportedToError(eerr)
+	}
+	return err
+}
diff --git a/daemon/graphdriver/lcow/remotefs_file.go b/daemon/graphdriver/lcow/remotefs_file.go
new file mode 100644
index 0000000..c134319
--- /dev/null
+++ b/daemon/graphdriver/lcow/remotefs_file.go
@@ -0,0 +1,211 @@
+// +build windows
+
+package lcow
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/json"
+	"fmt"
+	"io"
+	"os"
+	"strconv"
+
+	"github.com/Microsoft/hcsshim"
+	"github.com/Microsoft/opengcs/service/gcsutils/remotefs"
+	"github.com/containerd/continuity/driver"
+)
+
+type lcowfile struct {
+	process   hcsshim.Process
+	stdin     io.WriteCloser
+	stdout    io.ReadCloser
+	stderr    io.ReadCloser
+	fs        *lcowfs
+	guestPath string
+}
+
+func (l *lcowfs) Open(path string) (driver.File, error) {
+	return l.OpenFile(path, os.O_RDONLY, 0)
+}
+
+func (l *lcowfs) OpenFile(path string, flag int, perm os.FileMode) (_ driver.File, err error) {
+	flagStr := strconv.FormatInt(int64(flag), 10)
+	permStr := strconv.FormatUint(uint64(perm), 8)
+
+	commandLine := fmt.Sprintf("%s %s %s %s", remotefs.RemotefsCmd, remotefs.OpenFileCmd, flagStr, permStr)
+	env := make(map[string]string)
+	env["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:"
+	processConfig := &hcsshim.ProcessConfig{
+		EmulateConsole:    false,
+		CreateStdInPipe:   true,
+		CreateStdOutPipe:  true,
+		CreateStdErrPipe:  true,
+		CreateInUtilityVm: true,
+		WorkingDirectory:  "/bin",
+		Environment:       env,
+		CommandLine:       commandLine,
+	}
+
+	process, err := l.currentSVM.config.Uvm.CreateProcess(processConfig)
+	if err != nil {
+		return nil, fmt.Errorf("failed to open file %s: %s", path, err)
+	}
+
+	stdin, stdout, stderr, err := process.Stdio()
+	if err != nil {
+		process.Kill()
+		process.Close()
+		return nil, fmt.Errorf("failed to open file pipes %s: %s", path, err)
+	}
+
+	lf := &lcowfile{
+		process:   process,
+		stdin:     stdin,
+		stdout:    stdout,
+		stderr:    stderr,
+		fs:        l,
+		guestPath: path,
+	}
+
+	if _, err := lf.getResponse(); err != nil {
+		return nil, fmt.Errorf("failed to open file %s: %s", path, err)
+	}
+	return lf, nil
+}
+
+func (l *lcowfile) Read(b []byte) (int, error) {
+	hdr := &remotefs.FileHeader{
+		Cmd:  remotefs.Read,
+		Size: uint64(len(b)),
+	}
+
+	if err := remotefs.WriteFileHeader(l.stdin, hdr, nil); err != nil {
+		return 0, err
+	}
+
+	buf, err := l.getResponse()
+	if err != nil {
+		return 0, nil
+	}
+
+	n := copy(b, buf)
+	return n, nil
+}
+
+func (l *lcowfile) Write(b []byte) (int, error) {
+	hdr := &remotefs.FileHeader{
+		Cmd:  remotefs.Write,
+		Size: uint64(len(b)),
+	}
+
+	if err := remotefs.WriteFileHeader(l.stdin, hdr, b); err != nil {
+		return 0, err
+	}
+
+	_, err := l.getResponse()
+	if err != nil {
+		return 0, nil
+	}
+
+	return len(b), nil
+}
+
+func (l *lcowfile) Seek(offset int64, whence int) (int64, error) {
+	seekHdr := &remotefs.SeekHeader{
+		Offset: offset,
+		Whence: int32(whence),
+	}
+
+	buf := &bytes.Buffer{}
+	if err := binary.Write(buf, binary.BigEndian, seekHdr); err != nil {
+		return 0, err
+	}
+
+	hdr := &remotefs.FileHeader{
+		Cmd:  remotefs.Write,
+		Size: uint64(buf.Len()),
+	}
+	if err := remotefs.WriteFileHeader(l.stdin, hdr, buf.Bytes()); err != nil {
+		return 0, err
+	}
+
+	resBuf, err := l.getResponse()
+	if err != nil {
+		return 0, err
+	}
+
+	var res int64
+	if err := binary.Read(bytes.NewBuffer(resBuf), binary.BigEndian, &res); err != nil {
+		return 0, err
+	}
+	return res, nil
+}
+
+func (l *lcowfile) Close() error {
+	hdr := &remotefs.FileHeader{
+		Cmd:  remotefs.Close,
+		Size: 0,
+	}
+
+	if err := remotefs.WriteFileHeader(l.stdin, hdr, nil); err != nil {
+		return err
+	}
+
+	_, err := l.getResponse()
+	return err
+}
+
+func (l *lcowfile) Readdir(n int) ([]os.FileInfo, error) {
+	nStr := strconv.FormatInt(int64(n), 10)
+
+	// Unlike the other File functions, this one can just be run without maintaining state,
+	// so just do the normal runRemoteFSProcess way.
+	buf := &bytes.Buffer{}
+	if err := l.fs.runRemoteFSProcess(nil, buf, remotefs.ReadDirCmd, l.guestPath, nStr); err != nil {
+		return nil, err
+	}
+
+	var info []remotefs.FileInfo
+	if err := json.Unmarshal(buf.Bytes(), &info); err != nil {
+		return nil, nil
+	}
+
+	osInfo := make([]os.FileInfo, len(info))
+	for i := range info {
+		osInfo[i] = &info[i]
+	}
+	return osInfo, nil
+}
+
+func (l *lcowfile) getResponse() ([]byte, error) {
+	hdr, err := remotefs.ReadFileHeader(l.stdout)
+	if err != nil {
+		return nil, err
+	}
+
+	if hdr.Cmd != remotefs.CmdOK {
+		// Something went wrong during the openfile in the server.
+		// Parse stderr and return that as an error
+		eerr, err := remotefs.ReadError(l.stderr)
+		if eerr != nil {
+			return nil, remotefs.ExportedToError(eerr)
+		}
+
+		// Maybe the parsing went wrong?
+		if err != nil {
+			return nil, err
+		}
+
+		// At this point, we know something went wrong in the remotefs program, but
+		// we we don't know why.
+		return nil, fmt.Errorf("unknown error")
+	}
+
+	// Successful command, we might have some data to read (for Read + Seek)
+	buf := make([]byte, hdr.Size, hdr.Size)
+	if _, err := io.ReadFull(l.stdout, buf); err != nil {
+		return nil, err
+	}
+	return buf, nil
+}
diff --git a/daemon/graphdriver/lcow/remotefs_filedriver.go b/daemon/graphdriver/lcow/remotefs_filedriver.go
new file mode 100644
index 0000000..a3e0d9e
--- /dev/null
+++ b/daemon/graphdriver/lcow/remotefs_filedriver.go
@@ -0,0 +1,123 @@
+// +build windows
+
+package lcow
+
+import (
+	"bytes"
+	"encoding/json"
+	"os"
+	"strconv"
+
+	"github.com/Microsoft/opengcs/service/gcsutils/remotefs"
+
+	"github.com/containerd/continuity/driver"
+	"github.com/sirupsen/logrus"
+)
+
+var _ driver.Driver = &lcowfs{}
+
+func (l *lcowfs) Readlink(p string) (string, error) {
+	logrus.Debugf("removefs.readlink args: %s", p)
+
+	result := &bytes.Buffer{}
+	if err := l.runRemoteFSProcess(nil, result, remotefs.ReadlinkCmd, p); err != nil {
+		return "", err
+	}
+	return result.String(), nil
+}
+
+func (l *lcowfs) Mkdir(path string, mode os.FileMode) error {
+	return l.mkdir(path, mode, remotefs.MkdirCmd)
+}
+
+func (l *lcowfs) MkdirAll(path string, mode os.FileMode) error {
+	return l.mkdir(path, mode, remotefs.MkdirAllCmd)
+}
+
+func (l *lcowfs) mkdir(path string, mode os.FileMode, cmd string) error {
+	modeStr := strconv.FormatUint(uint64(mode), 8)
+	logrus.Debugf("remotefs.%s args: %s %s", cmd, path, modeStr)
+	return l.runRemoteFSProcess(nil, nil, cmd, path, modeStr)
+}
+
+func (l *lcowfs) Remove(path string) error {
+	return l.remove(path, remotefs.RemoveCmd)
+}
+
+func (l *lcowfs) RemoveAll(path string) error {
+	return l.remove(path, remotefs.RemoveAllCmd)
+}
+
+func (l *lcowfs) remove(path string, cmd string) error {
+	logrus.Debugf("remotefs.%s args: %s", cmd, path)
+	return l.runRemoteFSProcess(nil, nil, cmd, path)
+}
+
+func (l *lcowfs) Link(oldname, newname string) error {
+	return l.link(oldname, newname, remotefs.LinkCmd)
+}
+
+func (l *lcowfs) Symlink(oldname, newname string) error {
+	return l.link(oldname, newname, remotefs.SymlinkCmd)
+}
+
+func (l *lcowfs) link(oldname, newname, cmd string) error {
+	logrus.Debugf("remotefs.%s args: %s %s", cmd, oldname, newname)
+	return l.runRemoteFSProcess(nil, nil, cmd, oldname, newname)
+}
+
+func (l *lcowfs) Lchown(name string, uid, gid int64) error {
+	uidStr := strconv.FormatInt(uid, 10)
+	gidStr := strconv.FormatInt(gid, 10)
+
+	logrus.Debugf("remotefs.lchown args: %s %s %s", name, uidStr, gidStr)
+	return l.runRemoteFSProcess(nil, nil, remotefs.LchownCmd, name, uidStr, gidStr)
+}
+
+// Lchmod changes the mode of an file not following symlinks.
+func (l *lcowfs) Lchmod(path string, mode os.FileMode) error {
+	modeStr := strconv.FormatUint(uint64(mode), 8)
+	logrus.Debugf("remotefs.lchmod args: %s %s", path, modeStr)
+	return l.runRemoteFSProcess(nil, nil, remotefs.LchmodCmd, path, modeStr)
+}
+
+func (l *lcowfs) Mknod(path string, mode os.FileMode, major, minor int) error {
+	modeStr := strconv.FormatUint(uint64(mode), 8)
+	majorStr := strconv.FormatUint(uint64(major), 10)
+	minorStr := strconv.FormatUint(uint64(minor), 10)
+
+	logrus.Debugf("remotefs.mknod args: %s %s %s %s", path, modeStr, majorStr, minorStr)
+	return l.runRemoteFSProcess(nil, nil, remotefs.MknodCmd, path, modeStr, majorStr, minorStr)
+}
+
+func (l *lcowfs) Mkfifo(path string, mode os.FileMode) error {
+	modeStr := strconv.FormatUint(uint64(mode), 8)
+	logrus.Debugf("remotefs.mkfifo args: %s %s", path, modeStr)
+	return l.runRemoteFSProcess(nil, nil, remotefs.MkfifoCmd, path, modeStr)
+}
+
+func (l *lcowfs) Stat(p string) (os.FileInfo, error) {
+	return l.stat(p, remotefs.StatCmd)
+}
+
+func (l *lcowfs) Lstat(p string) (os.FileInfo, error) {
+	return l.stat(p, remotefs.LstatCmd)
+}
+
+func (l *lcowfs) stat(path string, cmd string) (os.FileInfo, error) {
+	logrus.Debugf("remotefs.stat inputs: %s %s", cmd, path)
+
+	output := &bytes.Buffer{}
+	err := l.runRemoteFSProcess(nil, output, cmd, path)
+	if err != nil {
+		return nil, err
+	}
+
+	var fi remotefs.FileInfo
+	if err := json.Unmarshal(output.Bytes(), &fi); err != nil {
+		return nil, err
+	}
+
+	logrus.Debugf("remotefs.stat success. got: %v\n", fi)
+	return &fi, nil
+}
diff --git a/daemon/graphdriver/lcow/remotefs_pathdriver.go b/daemon/graphdriver/lcow/remotefs_pathdriver.go
new file mode 100644
index 0000000..95d3e71
--- /dev/null
+++ b/daemon/graphdriver/lcow/remotefs_pathdriver.go
@@ -0,0 +1,212 @@
+// +build windows
+
+package lcow
+
+import (
+	"errors"
+	"os"
+	pathpkg "path"
+	"path/filepath"
+	"sort"
+	"strings"
+
+	"github.com/containerd/continuity/pathdriver"
+)
+
+var _ pathdriver.PathDriver = &lcowfs{}
+
+// Continuity Path functions can be done locally
+func (l *lcowfs) Join(path ...string) string {
+	return pathpkg.Join(path...)
+}
+
+func (l *lcowfs) IsAbs(path string) bool {
+	return pathpkg.IsAbs(path)
+}
+
+func sameWord(a, b string) bool {
+	return a == b
+}
+
+// Implementation taken from the Go standard library
+func (l *lcowfs) Rel(basepath, targpath string) (string, error) {
+	baseVol := ""
+	targVol := ""
+	base := l.Clean(basepath)
+	targ := l.Clean(targpath)
+	if sameWord(targ, base) {
+		return ".", nil
+	}
+	base = base[len(baseVol):]
+	targ = targ[len(targVol):]
+	if base == "." {
+		base = ""
+	}
+	// Can't use IsAbs - `\a` and `a` are both relative in Windows.
+	baseSlashed := len(base) > 0 && base[0] == l.Separator()
+	targSlashed := len(targ) > 0 && targ[0] == l.Separator()
+	if baseSlashed != targSlashed || !sameWord(baseVol, targVol) {
+		return "", errors.New("Rel: can't make " + targpath + " relative to " + basepath)
+	}
+	// Position base[b0:bi] and targ[t0:ti] at the first differing elements.
+	bl := len(base)
+	tl := len(targ)
+	var b0, bi, t0, ti int
+	for {
+		for bi < bl && base[bi] != l.Separator() {
+			bi++
+		}
+		for ti < tl && targ[ti] != l.Separator() {
+			ti++
+		}
+		if !sameWord(targ[t0:ti], base[b0:bi]) {
+			break
+		}
+		if bi < bl {
+			bi++
+		}
+		if ti < tl {
+			ti++
+		}
+		b0 = bi
+		t0 = ti
+	}
+	if base[b0:bi] == ".." {
+		return "", errors.New("Rel: can't make " + targpath + " relative to " + basepath)
+	}
+	if b0 != bl {
+		// Base elements left. Must go up before going down.
+		seps := strings.Count(base[b0:bl], string(l.Separator()))
+		size := 2 + seps*3
+		if tl != t0 {
+			size += 1 + tl - t0
+		}
+		buf := make([]byte, size)
+		n := copy(buf, "..")
+		for i := 0; i < seps; i++ {
+			buf[n] = l.Separator()
+			copy(buf[n+1:], "..")
+			n += 3
+		}
+		if t0 != tl {
+			buf[n] = l.Separator()
+			copy(buf[n+1:], targ[t0:])
+		}
+		return string(buf), nil
+	}
+	return targ[t0:], nil
+}
+
+func (l *lcowfs) Base(path string) string {
+	return pathpkg.Base(path)
+}
+
+func (l *lcowfs) Dir(path string) string {
+	return pathpkg.Dir(path)
+}
+
+func (l *lcowfs) Clean(path string) string {
+	return pathpkg.Clean(path)
+}
+
+func (l *lcowfs) Split(path string) (dir, file string) {
+	return pathpkg.Split(path)
+}
+
+func (l *lcowfs) Separator() byte {
+	return '/'
+}
+
+func (l *lcowfs) Abs(path string) (string, error) {
+	// Abs is supposed to add the current working directory, which is meaningless in lcow.
+	// So, return an error.
+	return "", ErrNotSupported
+}
+
+// Implementation taken from the Go standard library
+func (l *lcowfs) Walk(root string, walkFn filepath.WalkFunc) error {
+	info, err := l.Lstat(root)
+	if err != nil {
+		err = walkFn(root, nil, err)
+	} else {
+		err = l.walk(root, info, walkFn)
+	}
+	if err == filepath.SkipDir {
+		return nil
+	}
+	return err
+}
+
+// walk recursively descends path, calling w.
+func (l *lcowfs) walk(path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
+	err := walkFn(path, info, nil)
+	if err != nil {
+		if info.IsDir() && err == filepath.SkipDir {
+			return nil
+		}
+		return err
+	}
+
+	if !info.IsDir() {
+		return nil
+	}
+
+	names, err := l.readDirNames(path)
+	if err != nil {
+		return walkFn(path, info, err)
+	}
+
+	for _, name := range names {
+		filename := l.Join(path, name)
+		fileInfo, err := l.Lstat(filename)
+		if err != nil {
+			if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
+				return err
+			}
+		} else {
+			err = l.walk(filename, fileInfo, walkFn)
+			if err != nil {
+				if !fileInfo.IsDir() || err != filepath.SkipDir {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// readDirNames reads the directory named by dirname and returns
+// a sorted list of directory entries.
+func (l *lcowfs) readDirNames(dirname string) ([]string, error) {
+	f, err := l.Open(dirname)
+	if err != nil {
+		return nil, err
+	}
+	files, err := f.Readdir(-1)
+	f.Close()
+	if err != nil {
+		return nil, err
+	}
+
+	names := make([]string, len(files), len(files))
+	for i := range files {
+		names[i] = files[i].Name()
+	}
+
+	sort.Strings(names)
+	return names, nil
+}
+
+// Note that Go's filepath.FromSlash/ToSlash convert between OS paths and '/'. Since the path separator
+// for LCOW (and Unix) is '/', they are no-ops.
+func (l *lcowfs) FromSlash(path string) string {
+	return path
+}
+
+func (l *lcowfs) ToSlash(path string) string {
+	return path
+}
+
+func (l *lcowfs) Match(pattern, name string) (matched bool, err error) {
+	return pathpkg.Match(pattern, name)
+}
diff --git a/daemon/graphdriver/overlay/copy.go b/daemon/graphdriver/overlay/copy.go
index 53ea5bf..f7e35e2 100644
--- a/daemon/graphdriver/overlay/copy.go
+++ b/daemon/graphdriver/overlay/copy.go
@@ -121,7 +121,7 @@
 			}
 
 		default:
-			return fmt.Errorf("Unknown file type for %s\n", srcPath)
+			return fmt.Errorf("unknown file type for %s", srcPath)
 		}
 
 		// Everything below is copying metadata from src to dst. All this metadata
@@ -157,6 +157,7 @@
 		}
 
 		// system.Chtimes doesn't support a NOFOLLOW flag atm
+		// nolint: unconvert
 		if !isSymlink {
 			aTime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
 			mTime := time.Unix(int64(stat.Mtim.Sec), int64(stat.Mtim.Nsec))
diff --git a/daemon/graphdriver/overlay/overlay.go b/daemon/graphdriver/overlay/overlay.go
index 9db2e94..9012722 100644
--- a/daemon/graphdriver/overlay/overlay.go
+++ b/daemon/graphdriver/overlay/overlay.go
@@ -12,16 +12,17 @@
 	"path"
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/daemon/graphdriver/overlayutils"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/fsutils"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/locker"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/system"
 	"github.com/opencontainers/selinux/go-selinux/label"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
@@ -269,10 +270,7 @@
 
 	// Toplevel images are just a "root" dir
 	if parent == "" {
-		if err := idtools.MkdirAs(path.Join(dir, "root"), 0755, rootUID, rootGID); err != nil {
-			return err
-		}
-		return nil
+		return idtools.MkdirAndChown(path.Join(dir, "root"), 0755, idtools.IDPair{rootUID, rootGID})
 	}
 
 	parentDir := d.dir(parent)
@@ -344,21 +342,21 @@
 }
 
 // Get creates and mounts the required file system for the given id and returns the mount path.
-func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
+func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, err error) {
 	d.locker.Lock(id)
 	defer d.locker.Unlock(id)
 	dir := d.dir(id)
 	if _, err := os.Stat(dir); err != nil {
-		return "", err
+		return nil, err
 	}
 	// If id has a root, just return it
 	rootDir := path.Join(dir, "root")
 	if _, err := os.Stat(rootDir); err == nil {
-		return rootDir, nil
+		return containerfs.NewLocalContainerFS(rootDir), nil
 	}
 	mergedDir := path.Join(dir, "merged")
 	if count := d.ctr.Increment(mergedDir); count > 1 {
-		return mergedDir, nil
+		return containerfs.NewLocalContainerFS(mergedDir), nil
 	}
 	defer func() {
 		if err != nil {
@@ -369,7 +367,7 @@
 	}()
 	lowerID, err := ioutil.ReadFile(path.Join(dir, "lower-id"))
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 	var (
 		lowerDir = path.Join(d.dir(string(lowerID)), "root")
@@ -378,18 +376,18 @@
 		opts     = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lowerDir, upperDir, workDir)
 	)
 	if err := unix.Mount("overlay", mergedDir, "overlay", 0, label.FormatMountLabel(opts, mountLabel)); err != nil {
-		return "", fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
+		return nil, fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
 	}
 	// chown "workdir/work" to the remapped root UID/GID. Overlay fs inside a
 	// user namespace requires this to move a directory from lower to upper.
 	rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 	if err := os.Chown(path.Join(workDir, "work"), rootUID, rootGID); err != nil {
-		return "", err
+		return nil, err
 	}
-	return mergedDir, nil
+	return containerfs.NewLocalContainerFS(mergedDir), nil
 }
 
 // Put unmounts the mount path created for the give id.
diff --git a/daemon/graphdriver/overlay2/check.go b/daemon/graphdriver/overlay2/check.go
index fac147f..f29630b 100644
--- a/daemon/graphdriver/overlay2/check.go
+++ b/daemon/graphdriver/overlay2/check.go
@@ -10,9 +10,9 @@
 	"path/filepath"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/system"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/graphdriver/overlay2/mount.go b/daemon/graphdriver/overlay2/mount.go
index 77bff06..e59178c 100644
--- a/daemon/graphdriver/overlay2/mount.go
+++ b/daemon/graphdriver/overlay2/mount.go
@@ -49,18 +49,19 @@
 	output := bytes.NewBuffer(nil)
 	cmd.Stdout = output
 	cmd.Stderr = output
-
 	if err := cmd.Start(); err != nil {
+		w.Close()
 		return fmt.Errorf("mountfrom error on re-exec cmd: %v", err)
 	}
 	//write the options to the pipe for the untar exec to read
 	if err := json.NewEncoder(w).Encode(options); err != nil {
+		w.Close()
 		return fmt.Errorf("mountfrom json encode to pipe failed: %v", err)
 	}
 	w.Close()
 
 	if err := cmd.Wait(); err != nil {
-		return fmt.Errorf("mountfrom re-exec error: %v: output: %s", err, output)
+		return fmt.Errorf("mountfrom re-exec error: %v: output: %v", err, output)
 	}
 	return nil
 }
diff --git a/daemon/graphdriver/overlay2/overlay.go b/daemon/graphdriver/overlay2/overlay.go
index 6a417e8..0f252e6 100644
--- a/daemon/graphdriver/overlay2/overlay.go
+++ b/daemon/graphdriver/overlay2/overlay.go
@@ -16,13 +16,14 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/daemon/graphdriver/overlayutils"
 	"github.com/docker/docker/daemon/graphdriver/quota"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/chrootarchive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/directory"
 	"github.com/docker/docker/pkg/fsutils"
 	"github.com/docker/docker/pkg/idtools"
@@ -514,12 +515,12 @@
 }
 
 // Get creates and mounts the required file system for the given id and returns the mount path.
-func (d *Driver) Get(id string, mountLabel string) (s string, err error) {
+func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr error) {
 	d.locker.Lock(id)
 	defer d.locker.Unlock(id)
 	dir := d.dir(id)
 	if _, err := os.Stat(dir); err != nil {
-		return "", err
+		return nil, err
 	}
 
 	diffDir := path.Join(dir, "diff")
@@ -527,19 +528,21 @@
 	if err != nil {
 		// If no lower, just return diff directory
 		if os.IsNotExist(err) {
-			return diffDir, nil
+			return containerfs.NewLocalContainerFS(diffDir), nil
 		}
-		return "", err
+		return nil, err
 	}
 
 	mergedDir := path.Join(dir, "merged")
 	if count := d.ctr.Increment(mergedDir); count > 1 {
-		return mergedDir, nil
+		return containerfs.NewLocalContainerFS(mergedDir), nil
 	}
 	defer func() {
-		if err != nil {
+		if retErr != nil {
 			if c := d.ctr.Decrement(mergedDir); c <= 0 {
-				unix.Unmount(mergedDir, 0)
+				if mntErr := unix.Unmount(mergedDir, 0); mntErr != nil {
+					logrus.Errorf("error unmounting %v: %v", mergedDir, mntErr)
+				}
 			}
 		}
 	}()
@@ -574,7 +577,7 @@
 		opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", string(lowers), path.Join(id, "diff"), path.Join(id, "work"))
 		mountData = label.FormatMountLabel(opts, mountLabel)
 		if len(mountData) > pageSize {
-			return "", fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData))
+			return nil, fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData))
 		}
 
 		mount = func(source string, target string, mType string, flags uintptr, label string) error {
@@ -584,21 +587,21 @@
 	}
 
 	if err := mount("overlay", mountTarget, "overlay", 0, mountData); err != nil {
-		return "", fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
+		return nil, fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err)
 	}
 
 	// chown "workdir/work" to the remapped root UID/GID. Overlay fs inside a
 	// user namespace requires this to move a directory from lower to upper.
 	rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 
 	if err := os.Chown(path.Join(workDir, "work"), rootUID, rootGID); err != nil {
-		return "", err
+		return nil, err
 	}
 
-	return mergedDir, nil
+	return containerfs.NewLocalContainerFS(mergedDir), nil
 }
 
 // Put unmounts the mount path created for the give id.
diff --git a/daemon/graphdriver/overlay2/randomid.go b/daemon/graphdriver/overlay2/randomid.go
index 04212c0..30d6f3b 100644
--- a/daemon/graphdriver/overlay2/randomid.go
+++ b/daemon/graphdriver/overlay2/randomid.go
@@ -11,7 +11,7 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/graphdriver/plugin.go b/daemon/graphdriver/plugin.go
index f6852f0..5d433e5 100644
--- a/daemon/graphdriver/plugin.go
+++ b/daemon/graphdriver/plugin.go
@@ -2,22 +2,12 @@
 
 import (
 	"fmt"
-	"io"
 	"path/filepath"
 
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/plugin/v2"
 )
 
-type pluginClient interface {
-	// Call calls the specified method with the specified arguments for the plugin.
-	Call(string, interface{}, interface{}) error
-	// Stream calls the specified method with the specified arguments for the plugin and returns the response IO stream
-	Stream(string, interface{}) (io.ReadCloser, error)
-	// SendFile calls the specified method, and passes through the IO stream
-	SendFile(string, io.Reader, interface{}) error
-}
-
 func lookupPlugin(name string, pg plugingetter.PluginGetter, config Options) (Driver, error) {
 	if !config.ExperimentalEnabled {
 		return nil, fmt.Errorf("graphdriver plugins are only supported with experimental mode")
diff --git a/daemon/graphdriver/proxy.go b/daemon/graphdriver/proxy.go
index 120afad..81ef872 100644
--- a/daemon/graphdriver/proxy.go
+++ b/daemon/graphdriver/proxy.go
@@ -7,6 +7,7 @@
 	"path/filepath"
 
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugins"
@@ -129,20 +130,20 @@
 	return nil
 }
 
-func (d *graphDriverProxy) Get(id, mountLabel string) (string, error) {
+func (d *graphDriverProxy) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	args := &graphDriverRequest{
 		ID:         id,
 		MountLabel: mountLabel,
 	}
 	var ret graphDriverResponse
 	if err := d.p.Client().Call("GraphDriver.Get", args, &ret); err != nil {
-		return "", err
+		return nil, err
 	}
 	var err error
 	if ret.Err != "" {
 		err = errors.New(ret.Err)
 	}
-	return filepath.Join(d.p.BasePath(), ret.Dir), err
+	return containerfs.NewLocalContainerFS(filepath.Join(d.p.BasePath(), ret.Dir)), err
 }
 
 func (d *graphDriverProxy) Put(id string) error {
diff --git a/daemon/graphdriver/quota/projectquota.go b/daemon/graphdriver/quota/projectquota.go
index b784dc4..0e70515 100644
--- a/daemon/graphdriver/quota/projectquota.go
+++ b/daemon/graphdriver/quota/projectquota.go
@@ -56,7 +56,7 @@
 	"path/filepath"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/graphdriver/register/register_devicemapper.go b/daemon/graphdriver/register/register_devicemapper.go
index bb2e9ef..09dfb71 100644
--- a/daemon/graphdriver/register/register_devicemapper.go
+++ b/daemon/graphdriver/register/register_devicemapper.go
@@ -1,4 +1,4 @@
-// +build !exclude_graphdriver_devicemapper,linux
+// +build !exclude_graphdriver_devicemapper,!static_build,linux
 
 package register
 
diff --git a/daemon/graphdriver/vfs/driver.go b/daemon/graphdriver/vfs/driver.go
index 15a4de3..0482dcc 100644
--- a/daemon/graphdriver/vfs/driver.go
+++ b/daemon/graphdriver/vfs/driver.go
@@ -7,6 +7,7 @@
 
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/chrootarchive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/system"
 	"github.com/opencontainers/selinux/go-selinux/label"
@@ -94,7 +95,7 @@
 	if err != nil {
 		return fmt.Errorf("%s: %s", parent, err)
 	}
-	return CopyWithTar(parentDir, dir)
+	return CopyWithTar(parentDir.Path(), dir)
 }
 
 func (d *Driver) dir(id string) string {
@@ -103,21 +104,18 @@
 
 // Remove deletes the content from the directory for a given id.
 func (d *Driver) Remove(id string) error {
-	if err := system.EnsureRemoveAll(d.dir(id)); err != nil {
-		return err
-	}
-	return nil
+	return system.EnsureRemoveAll(d.dir(id))
 }
 
 // Get returns the directory for the given id.
-func (d *Driver) Get(id, mountLabel string) (string, error) {
+func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	dir := d.dir(id)
 	if st, err := os.Stat(dir); err != nil {
-		return "", err
+		return nil, err
 	} else if !st.IsDir() {
-		return "", fmt.Errorf("%s: not a directory", dir)
+		return nil, fmt.Errorf("%s: not a directory", dir)
 	}
-	return dir, nil
+	return containerfs.NewLocalContainerFS(dir), nil
 }
 
 // Put is a noop for vfs that return nil for the error, since this driver has no runtime resources to clean up.
diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go
index 49c8d34..e7130d8 100644
--- a/daemon/graphdriver/windows/windows.go
+++ b/daemon/graphdriver/windows/windows.go
@@ -24,15 +24,16 @@
 	"github.com/Microsoft/go-winio/archive/tar"
 	"github.com/Microsoft/go-winio/backuptar"
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/longpath"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/system"
 	units "github.com/docker/go-units"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/windows"
 )
 
@@ -354,36 +355,36 @@
 }
 
 // Get returns the rootfs path for the id. This will mount the dir at its given path.
-func (d *Driver) Get(id, mountLabel string) (string, error) {
+func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	panicIfUsedByLcow()
 	logrus.Debugf("WindowsGraphDriver Get() id %s mountLabel %s", id, mountLabel)
 	var dir string
 
 	rID, err := d.resolveID(id)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 	if count := d.ctr.Increment(rID); count > 1 {
-		return d.cache[rID], nil
+		return containerfs.NewLocalContainerFS(d.cache[rID]), nil
 	}
 
 	// Getting the layer paths must be done outside of the lock.
 	layerChain, err := d.getLayerChain(rID)
 	if err != nil {
 		d.ctr.Decrement(rID)
-		return "", err
+		return nil, err
 	}
 
 	if err := hcsshim.ActivateLayer(d.info, rID); err != nil {
 		d.ctr.Decrement(rID)
-		return "", err
+		return nil, err
 	}
 	if err := hcsshim.PrepareLayer(d.info, rID, layerChain); err != nil {
 		d.ctr.Decrement(rID)
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
 		}
-		return "", err
+		return nil, err
 	}
 
 	mountPath, err := hcsshim.GetLayerMountPath(d.info, rID)
@@ -395,7 +396,7 @@
 		if err2 := hcsshim.DeactivateLayer(d.info, rID); err2 != nil {
 			logrus.Warnf("Failed to Deactivate %s: %s", id, err)
 		}
-		return "", err
+		return nil, err
 	}
 	d.cacheMu.Lock()
 	d.cache[rID] = mountPath
@@ -409,7 +410,7 @@
 		dir = d.dir(id)
 	}
 
-	return dir, nil
+	return containerfs.NewLocalContainerFS(dir), nil
 }
 
 // Put adds a new layer to the driver.
@@ -618,7 +619,7 @@
 	}
 	defer d.Put(id)
 
-	return archive.ChangesSize(layerFs, changes), nil
+	return archive.ChangesSize(layerFs.Path(), changes), nil
 }
 
 // GetMetadata returns custom driver information.
diff --git a/daemon/graphdriver/zfs/zfs.go b/daemon/graphdriver/zfs/zfs.go
index a772cc9..4caedef 100644
--- a/daemon/graphdriver/zfs/zfs.go
+++ b/daemon/graphdriver/zfs/zfs.go
@@ -12,13 +12,14 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/parsers"
 	zfs "github.com/mistifyio/go-zfs"
 	"github.com/opencontainers/selinux/go-selinux/label"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
@@ -356,10 +357,10 @@
 }
 
 // Get returns the mountpoint for the given id after creating the target directories if necessary.
-func (d *Driver) Get(id, mountLabel string) (string, error) {
+func (d *Driver) Get(id, mountLabel string) (containerfs.ContainerFS, error) {
 	mountpoint := d.mountPath(id)
 	if count := d.ctr.Increment(mountpoint); count > 1 {
-		return mountpoint, nil
+		return containerfs.NewLocalContainerFS(mountpoint), nil
 	}
 
 	filesystem := d.zfsPath(id)
@@ -369,17 +370,17 @@
 	rootUID, rootGID, err := idtools.GetRootUIDGID(d.uidMaps, d.gidMaps)
 	if err != nil {
 		d.ctr.Decrement(mountpoint)
-		return "", err
+		return nil, err
 	}
 	// Create the target directories if they don't exist
 	if err := idtools.MkdirAllAs(mountpoint, 0755, rootUID, rootGID); err != nil {
 		d.ctr.Decrement(mountpoint)
-		return "", err
+		return nil, err
 	}
 
 	if err := mount.Mount(filesystem, mountpoint, "zfs", options); err != nil {
 		d.ctr.Decrement(mountpoint)
-		return "", fmt.Errorf("error creating zfs mount of %s to %s: %v", filesystem, mountpoint, err)
+		return nil, fmt.Errorf("error creating zfs mount of %s to %s: %v", filesystem, mountpoint, err)
 	}
 
 	// this could be our first mount after creation of the filesystem, and the root dir may still have root
@@ -387,10 +388,10 @@
 	if err := os.Chown(mountpoint, rootUID, rootGID); err != nil {
 		mount.Unmount(mountpoint)
 		d.ctr.Decrement(mountpoint)
-		return "", fmt.Errorf("error modifying zfs mountpoint (%s) directory ownership: %v", mountpoint, err)
+		return nil, fmt.Errorf("error modifying zfs mountpoint (%s) directory ownership: %v", mountpoint, err)
 	}
 
-	return mountpoint, nil
+	return containerfs.NewLocalContainerFS(mountpoint), nil
 }
 
 // Put removes the existing mountpoint for the given id if it exists.
@@ -416,5 +417,5 @@
 func (d *Driver) Exists(id string) bool {
 	d.Lock()
 	defer d.Unlock()
-	return d.filesystemsCache[d.zfsPath(id)] == true
+	return d.filesystemsCache[d.zfsPath(id)]
 }
diff --git a/daemon/graphdriver/zfs/zfs_freebsd.go b/daemon/graphdriver/zfs/zfs_freebsd.go
index e02012a..bbc3216 100644
--- a/daemon/graphdriver/zfs/zfs_freebsd.go
+++ b/daemon/graphdriver/zfs/zfs_freebsd.go
@@ -4,8 +4,8 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/graphdriver/zfs/zfs_linux.go b/daemon/graphdriver/zfs/zfs_linux.go
index 53aa4c8..71d6d3c 100644
--- a/daemon/graphdriver/zfs/zfs_linux.go
+++ b/daemon/graphdriver/zfs/zfs_linux.go
@@ -3,8 +3,8 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/graphdriver/zfs/zfs_solaris.go b/daemon/graphdriver/zfs/zfs_solaris.go
index bb4a85b..ce347f2 100644
--- a/daemon/graphdriver/zfs/zfs_solaris.go
+++ b/daemon/graphdriver/zfs/zfs_solaris.go
@@ -20,25 +20,24 @@
 	"strings"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/graphdriver"
+	"github.com/sirupsen/logrus"
 )
 
 func checkRootdirFs(rootdir string) error {
 
 	cs := C.CString(filepath.Dir(rootdir))
+	defer C.free(unsafe.Pointer(cs))
 	buf := C.getstatfs(cs)
+	defer C.free(unsafe.Pointer(buf))
 
 	// on Solaris buf.f_basetype contains ['z', 'f', 's', 0 ... ]
 	if (buf.f_basetype[0] != 122) || (buf.f_basetype[1] != 102) || (buf.f_basetype[2] != 115) ||
 		(buf.f_basetype[3] != 0) {
 		logrus.Debugf("[zfs] no zfs dataset found for rootdir '%s'", rootdir)
-		C.free(unsafe.Pointer(buf))
 		return graphdriver.ErrPrerequisites
 	}
 
-	C.free(unsafe.Pointer(buf))
-	C.free(unsafe.Pointer(cs))
 	return nil
 }
 
diff --git a/daemon/health.go b/daemon/health.go
index 61b5314..7d8c84a 100644
--- a/daemon/health.go
+++ b/daemon/health.go
@@ -10,12 +10,12 @@
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/strslice"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/exec"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -45,8 +45,7 @@
 const (
 	// Exit status codes that can be returned by the probe command.
 
-	exitStatusHealthy   = 0 // Container is healthy
-	exitStatusUnhealthy = 1 // Container is unhealthy
+	exitStatusHealthy = 0 // Container is healthy
 )
 
 // probe implementations know how to run a particular type of probe.
@@ -101,7 +100,7 @@
 		return nil, err
 	}
 	if info.ExitCode == nil {
-		return nil, fmt.Errorf("Healthcheck for container %s has no exit code!", cntr.ID)
+		return nil, fmt.Errorf("healthcheck for container %s has no exit code", cntr.ID)
 	}
 	// Note: Go's json package will handle invalid UTF-8 for us
 	out := output.String()
diff --git a/daemon/image.go b/daemon/image.go
index a51049d..23670c4 100644
--- a/daemon/image.go
+++ b/daemon/image.go
@@ -2,18 +2,19 @@
 
 import (
 	"fmt"
+	"runtime"
 
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/stringid"
 )
 
-// ErrImageDoesNotExist is error returned when no image can be found for a reference.
-type ErrImageDoesNotExist struct {
+// errImageDoesNotExist is error returned when no image can be found for a reference.
+type errImageDoesNotExist struct {
 	ref reference.Reference
 }
 
-func (e ErrImageDoesNotExist) Error() string {
+func (e errImageDoesNotExist) Error() string {
 	ref := e.ref
 	if named, ok := ref.(reference.Named); ok {
 		ref = reference.TagNameOnly(named)
@@ -21,18 +22,20 @@
 	return fmt.Sprintf("No such image: %s", reference.FamiliarString(ref))
 }
 
+func (e errImageDoesNotExist) NotFound() {}
+
 // GetImageIDAndPlatform returns an image ID and platform corresponding to the image referred to by
 // refOrID.
 func (daemon *Daemon) GetImageIDAndPlatform(refOrID string) (image.ID, string, error) {
 	ref, err := reference.ParseAnyReference(refOrID)
 	if err != nil {
-		return "", "", err
+		return "", "", validationError{err}
 	}
 	namedRef, ok := ref.(reference.Named)
 	if !ok {
 		digested, ok := ref.(reference.Digested)
 		if !ok {
-			return "", "", ErrImageDoesNotExist{ref}
+			return "", "", errImageDoesNotExist{ref}
 		}
 		id := image.IDFromDigest(digested.Digest())
 		for platform := range daemon.stores {
@@ -40,13 +43,20 @@
 				return id, platform, nil
 			}
 		}
-		return "", "", ErrImageDoesNotExist{ref}
+		return "", "", errImageDoesNotExist{ref}
 	}
 
-	for platform := range daemon.stores {
-		if id, err := daemon.stores[platform].referenceStore.Get(namedRef); err == nil {
-			return image.IDFromDigest(id), platform, nil
+	if digest, err := daemon.referenceStore.Get(namedRef); err == nil {
+		// Search the image stores to get the platform, defaulting to host OS.
+		imagePlatform := runtime.GOOS
+		id := image.IDFromDigest(digest)
+		for platform := range daemon.stores {
+			if img, err := daemon.stores[platform].imageStore.Get(id); err == nil {
+				imagePlatform = img.Platform()
+				break
+			}
 		}
+		return id, imagePlatform, nil
 	}
 
 	// deprecated: repo:shortid https://github.com/docker/docker/pull/799
@@ -54,7 +64,7 @@
 		if tag := tagged.Tag(); stringid.IsShortID(stringid.TruncateID(tag)) {
 			for platform := range daemon.stores {
 				if id, err := daemon.stores[platform].imageStore.Search(tag); err == nil {
-					for _, storeRef := range daemon.stores[platform].referenceStore.References(id.Digest()) {
+					for _, storeRef := range daemon.referenceStore.References(id.Digest()) {
 						if storeRef.Name() == namedRef.Name() {
 							return id, platform, nil
 						}
@@ -71,7 +81,7 @@
 		}
 	}
 
-	return "", "", ErrImageDoesNotExist{ref}
+	return "", "", errImageDoesNotExist{ref}
 }
 
 // GetImage returns an image corresponding to the image referred to by refOrID.
diff --git a/daemon/image_delete.go b/daemon/image_delete.go
index 4e22859..9873924 100644
--- a/daemon/image_delete.go
+++ b/daemon/image_delete.go
@@ -6,11 +6,11 @@
 	"time"
 
 	"github.com/docker/distribution/reference"
-	"github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/pkg/errors"
 )
 
 type conflictType int
@@ -67,10 +67,10 @@
 
 	imgID, platform, err := daemon.GetImageIDAndPlatform(imageRef)
 	if err != nil {
-		return nil, daemon.imageNotExistToErrcode(err)
+		return nil, err
 	}
 
-	repoRefs := daemon.stores[platform].referenceStore.References(imgID.Digest())
+	repoRefs := daemon.referenceStore.References(imgID.Digest())
 
 	var removedRepositoryRef bool
 	if !isImageIDPrefix(imgID.String(), imageRef) {
@@ -84,8 +84,8 @@
 				// this image would remain "dangling" and since
 				// we really want to avoid that the client must
 				// explicitly force its removal.
-				err := fmt.Errorf("conflict: unable to remove repository reference %q (must force) - container %s is using its referenced image %s", imageRef, stringid.TruncateID(container.ID), stringid.TruncateID(imgID.String()))
-				return nil, errors.NewRequestConflictError(err)
+				err := errors.Errorf("conflict: unable to remove repository reference %q (must force) - container %s is using its referenced image %s", imageRef, stringid.TruncateID(container.ID), stringid.TruncateID(imgID.String()))
+				return nil, stateConflictError{err}
 			}
 		}
 
@@ -104,7 +104,7 @@
 		daemon.LogImageEvent(imgID.String(), imgID.String(), "untag")
 		records = append(records, untaggedRecord)
 
-		repoRefs = daemon.stores[platform].referenceStore.References(imgID.Digest())
+		repoRefs = daemon.referenceStore.References(imgID.Digest())
 
 		// If a tag reference was removed and the only remaining
 		// references to the same repository are digest references,
@@ -237,7 +237,7 @@
 	// Ignore the boolean value returned, as far as we're concerned, this
 	// is an idempotent operation and it's okay if the reference didn't
 	// exist in the first place.
-	_, err := daemon.stores[platform].referenceStore.Delete(ref)
+	_, err := daemon.referenceStore.Delete(ref)
 
 	return ref, err
 }
@@ -248,7 +248,7 @@
 // daemon's event service. An "Untagged" types.ImageDeleteResponseItem is added to the
 // given list of records.
 func (daemon *Daemon) removeAllReferencesToImageID(imgID image.ID, platform string, records *[]types.ImageDeleteResponseItem) error {
-	imageRefs := daemon.stores[platform].referenceStore.References(imgID.Digest())
+	imageRefs := daemon.referenceStore.References(imgID.Digest())
 
 	for _, imageRef := range imageRefs {
 		parsedRef, err := daemon.removeImageRef(platform, imageRef)
@@ -285,6 +285,8 @@
 	return fmt.Sprintf("conflict: unable to delete %s (%s) - %s", stringid.TruncateID(idc.imgID.String()), forceMsg, idc.message)
 }
 
+func (idc *imageDeleteConflict) Conflict() {}
+
 // imageDeleteHelper attempts to delete the given image from this daemon. If
 // the image has any hard delete conflicts (child images or running containers
 // using the image) then it cannot be deleted. If the image has any soft delete
@@ -381,7 +383,7 @@
 	}
 
 	// Check if any repository tags/digest reference this image.
-	if mask&conflictActiveReference != 0 && len(daemon.stores[platform].referenceStore.References(imgID.Digest())) > 0 {
+	if mask&conflictActiveReference != 0 && len(daemon.referenceStore.References(imgID.Digest())) > 0 {
 		return &imageDeleteConflict{
 			imgID:   imgID,
 			message: "image is referenced in multiple repositories",
@@ -409,5 +411,5 @@
 // that there are no repository references to the given image and it has no
 // child images.
 func (daemon *Daemon) imageIsDangling(imgID image.ID, platform string) bool {
-	return !(len(daemon.stores[platform].referenceStore.References(imgID.Digest())) > 0 || len(daemon.stores[platform].imageStore.Children(imgID)) > 0)
+	return !(len(daemon.referenceStore.References(imgID.Digest())) > 0 || len(daemon.stores[platform].imageStore.Children(imgID)) > 0)
 }
diff --git a/daemon/image_exporter.go b/daemon/image_exporter.go
index a7b0be6..ce9aa7a 100644
--- a/daemon/image_exporter.go
+++ b/daemon/image_exporter.go
@@ -19,7 +19,7 @@
 	if system.LCOWSupported() {
 		platform = "linux"
 	}
-	imageExporter := tarexport.NewTarExporter(daemon.stores[platform].imageStore, daemon.stores[platform].layerStore, daemon.stores[platform].referenceStore, daemon)
+	imageExporter := tarexport.NewTarExporter(daemon.stores[platform].imageStore, daemon.stores[platform].layerStore, daemon.referenceStore, daemon)
 	return imageExporter.Save(names, outStream)
 }
 
@@ -32,6 +32,6 @@
 	if system.LCOWSupported() {
 		platform = "linux"
 	}
-	imageExporter := tarexport.NewTarExporter(daemon.stores[platform].imageStore, daemon.stores[platform].layerStore, daemon.stores[platform].referenceStore, daemon)
+	imageExporter := tarexport.NewTarExporter(daemon.stores[platform].imageStore, daemon.stores[platform].layerStore, daemon.referenceStore, daemon)
 	return imageExporter.Load(inTar, outStream, quiet)
 }
diff --git a/daemon/image_history.go b/daemon/image_history.go
index c9e8155..e7dd85c 100644
--- a/daemon/image_history.go
+++ b/daemon/image_history.go
@@ -69,7 +69,7 @@
 		h.ID = id.String()
 
 		var tags []string
-		for _, r := range daemon.stores[platform].referenceStore.References(id.Digest()) {
+		for _, r := range daemon.referenceStore.References(id.Digest()) {
 			if _, ok := r.(reference.NamedTagged); ok {
 				tags = append(tags, reference.FamiliarString(r))
 			}
diff --git a/daemon/image_inspect.go b/daemon/image_inspect.go
index 3baf265..fefb93c 100644
--- a/daemon/image_inspect.go
+++ b/daemon/image_inspect.go
@@ -24,7 +24,7 @@
 		platform = runtime.GOOS
 	}
 
-	refs := daemon.stores[platform].referenceStore.References(img.ID().Digest())
+	refs := daemon.referenceStore.References(img.ID().Digest())
 	repoTags := []string{}
 	repoDigests := []string{}
 	for _, ref := range refs {
diff --git a/daemon/image_pull.go b/daemon/image_pull.go
index abc81ec..aef1876 100644
--- a/daemon/image_pull.go
+++ b/daemon/image_pull.go
@@ -26,7 +26,7 @@
 
 	ref, err := reference.ParseNormalizedNamed(image)
 	if err != nil {
-		return err
+		return validationError{err}
 	}
 
 	if tag != "" {
@@ -39,7 +39,7 @@
 			ref, err = reference.WithTag(ref, tag)
 		}
 		if err != nil {
-			return err
+			return validationError{err}
 		}
 	}
 
@@ -74,7 +74,7 @@
 			ImageEventLogger: daemon.LogImageEvent,
 			MetadataStore:    daemon.stores[platform].distributionMetadataStore,
 			ImageStore:       distribution.NewImageConfigStoreFromStore(daemon.stores[platform].imageStore),
-			ReferenceStore:   daemon.stores[platform].referenceStore,
+			ReferenceStore:   daemon.referenceStore,
 		},
 		DownloadManager: daemon.downloadManager,
 		Schema2Types:    distribution.ImageTypes,
@@ -96,7 +96,7 @@
 	}
 	// makes sure name is not empty or `scratch`
 	if err := distribution.ValidateRepoName(repoInfo.Name); err != nil {
-		return nil, false, err
+		return nil, false, validationError{err}
 	}
 
 	// get endpoints
diff --git a/daemon/image_push.go b/daemon/image_push.go
index c2e5967..b558073 100644
--- a/daemon/image_push.go
+++ b/daemon/image_push.go
@@ -56,7 +56,7 @@
 			ImageEventLogger: daemon.LogImageEvent,
 			MetadataStore:    daemon.stores[platform].distributionMetadataStore,
 			ImageStore:       distribution.NewImageConfigStoreFromStore(daemon.stores[platform].imageStore),
-			ReferenceStore:   daemon.stores[platform].referenceStore,
+			ReferenceStore:   daemon.referenceStore,
 		},
 		ConfigMediaType: schema2.MediaTypeImageConfig,
 		LayerStore:      distribution.NewLayerProviderFromStore(daemon.stores[platform].layerStore),
diff --git a/daemon/image_tag.go b/daemon/image_tag.go
index 5f28dae..0c1d761 100644
--- a/daemon/image_tag.go
+++ b/daemon/image_tag.go
@@ -28,7 +28,7 @@
 
 // TagImageWithReference adds the given reference to the image ID provided.
 func (daemon *Daemon) TagImageWithReference(imageID image.ID, platform string, newTag reference.Named) error {
-	if err := daemon.stores[platform].referenceStore.AddTag(newTag, imageID.Digest(), true); err != nil {
+	if err := daemon.referenceStore.AddTag(newTag, imageID.Digest(), true); err != nil {
 		return err
 	}
 
diff --git a/daemon/images.go b/daemon/images.go
index 4baf703..27860d9 100644
--- a/daemon/images.go
+++ b/daemon/images.go
@@ -67,11 +67,11 @@
 		return nil, err
 	}
 
-	if imageFilters.Include("dangling") {
+	if imageFilters.Contains("dangling") {
 		if imageFilters.ExactMatch("dangling", "true") {
 			danglingOnly = true
 		} else if !imageFilters.ExactMatch("dangling", "false") {
-			return nil, fmt.Errorf("Invalid filter 'dangling=%s'", imageFilters.Get("dangling"))
+			return nil, invalidFilter{"dangling", imageFilters.Get("dangling")}
 		}
 	}
 	if danglingOnly {
@@ -116,7 +116,7 @@
 			}
 		}
 
-		if imageFilters.Include("label") {
+		if imageFilters.Contains("label") {
 			// Very old image that do not have image.Config (or even labels)
 			if img.Config == nil {
 				continue
@@ -149,8 +149,8 @@
 
 		newImage := newImage(img, size)
 
-		for _, ref := range daemon.stores[platform].referenceStore.References(id.Digest()) {
-			if imageFilters.Include("reference") {
+		for _, ref := range daemon.referenceStore.References(id.Digest()) {
+			if imageFilters.Contains("reference") {
 				var found bool
 				var matchErr error
 				for _, pattern := range imageFilters.Get("reference") {
@@ -173,11 +173,11 @@
 		if newImage.RepoDigests == nil && newImage.RepoTags == nil {
 			if all || len(daemon.stores[platform].imageStore.Children(id)) == 0 {
 
-				if imageFilters.Include("dangling") && !danglingOnly {
+				if imageFilters.Contains("dangling") && !danglingOnly {
 					//dangling=false case, so dangling image is not needed
 					continue
 				}
-				if imageFilters.Include("reference") { // skip images with no references if filtering by reference
+				if imageFilters.Contains("reference") { // skip images with no references if filtering by reference
 					continue
 				}
 				newImage.RepoDigests = []string{"<none>@<none>"}
@@ -301,12 +301,10 @@
 	}
 	defer daemon.stores[img.Platform()].layerStore.Release(newL)
 
-	var newImage image.Image
-	newImage = *img
+	newImage := *img
 	newImage.RootFS = nil
 
-	var rootFS image.RootFS
-	rootFS = *parentImg.RootFS
+	rootFS := *parentImg.RootFS
 	rootFS.DiffIDs = append(rootFS.DiffIDs, newL.DiffID())
 	newImage.RootFS = &rootFS
 
diff --git a/daemon/import.go b/daemon/import.go
index 0409cd6..e58d912 100644
--- a/daemon/import.go
+++ b/daemon/import.go
@@ -42,16 +42,16 @@
 		var err error
 		newRef, err = reference.ParseNormalizedNamed(repository)
 		if err != nil {
-			return err
+			return validationError{err}
 		}
 		if _, isCanonical := newRef.(reference.Canonical); isCanonical {
-			return errors.New("cannot import digest reference")
+			return validationError{errors.New("cannot import digest reference")}
 		}
 
 		if tag != "" {
 			newRef, err = reference.WithTag(newRef, tag)
 			if err != nil {
-				return err
+				return validationError{err}
 			}
 		}
 	}
@@ -69,7 +69,7 @@
 		}
 		u, err := url.Parse(src)
 		if err != nil {
-			return err
+			return validationError{err}
 		}
 
 		resp, err = remotecontext.GetWithStatusError(u.String())
diff --git a/daemon/info.go b/daemon/info.go
index 1de899f..b14e7ba 100644
--- a/daemon/info.go
+++ b/daemon/info.go
@@ -7,7 +7,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/cli/debug"
@@ -22,6 +21,7 @@
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/volume/drivers"
 	"github.com/docker/go-connections/sockets"
+	"github.com/sirupsen/logrus"
 )
 
 // SystemInfo returns information about the host server the daemon is running on.
@@ -97,10 +97,10 @@
 	drivers = strings.TrimSpace(drivers)
 	v := &types.Info{
 		ID:                 daemon.ID,
-		Containers:         int(cRunning + cPaused + cStopped),
-		ContainersRunning:  int(cRunning),
-		ContainersPaused:   int(cPaused),
-		ContainersStopped:  int(cStopped),
+		Containers:         cRunning + cPaused + cStopped,
+		ContainersRunning:  cRunning,
+		ContainersPaused:   cPaused,
+		ContainersStopped:  cStopped,
 		Images:             imageCount,
 		Driver:             drivers,
 		DriverStatus:       daemon.stores[p].layerStore.DriverStatus(),
diff --git a/daemon/info_unix.go b/daemon/info_unix.go
index e816f8d..f43af62 100644
--- a/daemon/info_unix.go
+++ b/daemon/info_unix.go
@@ -7,11 +7,11 @@
 	"os/exec"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // FillPlatformInfo fills the platform related info.
diff --git a/daemon/initlayer/setup_solaris.go b/daemon/initlayer/setup_solaris.go
index 66d53f0..57bc116 100644
--- a/daemon/initlayer/setup_solaris.go
+++ b/daemon/initlayer/setup_solaris.go
@@ -2,12 +2,14 @@
 
 package initlayer
 
+import "github.com/docker/docker/pkg/containerfs"
+
 // Setup populates a directory with mountpoints suitable
 // for bind-mounting dockerinit into the container. The mountpoint is simply an
 // empty file at /.dockerinit
 //
 // This extra layer is used by all containers as the top-most ro layer. It protects
 // the container from unwanted side-effects on the rw layer.
-func Setup(initLayer string, rootUID, rootGID int) error {
+func Setup(initLayer containerfs.ContainerFS, rootUID, rootGID int) error {
 	return nil
 }
diff --git a/daemon/initlayer/setup_unix.go b/daemon/initlayer/setup_unix.go
index e26d3a0..a02cea6 100644
--- a/daemon/initlayer/setup_unix.go
+++ b/daemon/initlayer/setup_unix.go
@@ -7,6 +7,7 @@
 	"path/filepath"
 	"strings"
 
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"golang.org/x/sys/unix"
 )
@@ -16,7 +17,10 @@
 //
 // This extra layer is used by all containers as the top-most ro layer. It protects
 // the container from unwanted side-effects on the rw layer.
-func Setup(initLayer string, rootIDs idtools.IDPair) error {
+func Setup(initLayerFs containerfs.ContainerFS, rootIDs idtools.IDPair) error {
+	// Since all paths are local to the container, we can just extract initLayerFs.Path()
+	initLayer := initLayerFs.Path()
+
 	for pth, typ := range map[string]string{
 		"/dev/pts":         "dir",
 		"/dev/shm":         "dir",
diff --git a/daemon/initlayer/setup_windows.go b/daemon/initlayer/setup_windows.go
index 2b22f58..b47563e 100644
--- a/daemon/initlayer/setup_windows.go
+++ b/daemon/initlayer/setup_windows.go
@@ -3,6 +3,7 @@
 package initlayer
 
 import (
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 )
 
@@ -12,6 +13,6 @@
 //
 // This extra layer is used by all containers as the top-most ro layer. It protects
 // the container from unwanted side-effects on the rw layer.
-func Setup(initLayer string, rootIDs idtools.IDPair) error {
+func Setup(initLayer containerfs.ContainerFS, rootIDs idtools.IDPair) error {
 	return nil
 }
diff --git a/daemon/inspect.go b/daemon/inspect.go
index fcdeb81..98f291c 100644
--- a/daemon/inspect.go
+++ b/daemon/inspect.go
@@ -11,6 +11,7 @@
 	"github.com/docker/docker/api/types/versions/v1p20"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/network"
+	volumestore "github.com/docker/docker/volume/store"
 	"github.com/docker/go-connections/nat"
 )
 
@@ -187,7 +188,7 @@
 	// could have been removed, it will cause error if we try to get the metadata,
 	// we can ignore the error if the container is dead.
 	if err != nil && !container.Dead {
-		return nil, err
+		return nil, systemError{err}
 	}
 	contJSONBase.GraphDriver.Data = graphDriverData
 
@@ -228,7 +229,10 @@
 func (daemon *Daemon) VolumeInspect(name string) (*types.Volume, error) {
 	v, err := daemon.volumes.Get(name)
 	if err != nil {
-		return nil, err
+		if volumestore.IsNotExist(err) {
+			return nil, volumeNotFound(name)
+		}
+		return nil, systemError{err}
 	}
 	apiV := volumeToAPIType(v)
 	apiV.Mountpoint = v.Path()
diff --git a/daemon/kill.go b/daemon/kill.go
index b118160..bb3e87c 100644
--- a/daemon/kill.go
+++ b/daemon/kill.go
@@ -8,9 +8,10 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	containerpkg "github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/signal"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 type errNoSuchProcess struct {
@@ -22,6 +23,8 @@
 	return fmt.Sprintf("Cannot kill process (pid=%d) with signal %d: no such process.", e.pid, e.signal)
 }
 
+func (errNoSuchProcess) NotFound() {}
+
 // isErrNoSuchProcess returns true if the error
 // is an instance of errNoSuchProcess.
 func isErrNoSuchProcess(err error) bool {
@@ -61,7 +64,7 @@
 	defer container.Unlock()
 
 	if !container.Running {
-		return errNotRunning{container.ID}
+		return errNotRunning(container.ID)
 	}
 
 	var unpause bool
@@ -91,8 +94,9 @@
 	}
 
 	if err := daemon.kill(container, sig); err != nil {
-		err = fmt.Errorf("Cannot kill container %s: %s", container.ID, err)
+		err = errors.Wrapf(err, "Cannot kill container %s", container.ID)
 		// if container or process not exists, ignore the error
+		// TODO: we shouldn't have to parse error strings from containerd
 		if strings.Contains(err.Error(), "container not found") ||
 			strings.Contains(err.Error(), "no such process") {
 			logrus.Warnf("container kill failed because of 'container not found' or 'no such process': %s", err.Error())
@@ -119,7 +123,7 @@
 // Kill forcefully terminates a container.
 func (daemon *Daemon) Kill(container *containerpkg.Container) error {
 	if !container.IsRunning() {
-		return errNotRunning{container.ID}
+		return errNotRunning(container.ID)
 	}
 
 	// 1. Send SIGKILL
@@ -156,7 +160,7 @@
 
 	// Wait for exit with no timeout.
 	// Ignore returned status.
-	_ = <-container.Wait(context.Background(), containerpkg.WaitConditionNotRunning)
+	<-container.Wait(context.Background(), containerpkg.WaitConditionNotRunning)
 
 	return nil
 }
diff --git a/daemon/links.go b/daemon/links.go
index 7f691d4..219a502 100644
--- a/daemon/links.go
+++ b/daemon/links.go
@@ -76,12 +76,16 @@
 }
 
 // delete deletes all link relationships referencing this container
-func (l *linkIndex) delete(container *container.Container) {
+func (l *linkIndex) delete(container *container.Container) []string {
 	l.mu.Lock()
-	for _, child := range l.idx[container] {
+
+	var aliases []string
+	for alias, child := range l.idx[container] {
+		aliases = append(aliases, alias)
 		delete(l.childIdx[child], container)
 	}
 	delete(l.idx, container)
 	delete(l.childIdx, container)
 	l.mu.Unlock()
+	return aliases
 }
diff --git a/daemon/list.go b/daemon/list.go
index 6889c55..9d43be2 100644
--- a/daemon/list.go
+++ b/daemon/list.go
@@ -1,19 +1,19 @@
 package daemon
 
 import (
-	"errors"
 	"fmt"
 	"sort"
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/volume"
 	"github.com/docker/go-connections/nat"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 var acceptedVolumeFilterTags = map[string]bool{
@@ -265,7 +265,7 @@
 
 	err = psFilters.WalkValues("status", func(value string) error {
 		if !container.IsValidStateString(value) {
-			return fmt.Errorf("Unrecognised filter value for status: %s", value)
+			return invalidFilter{"status", value}
 		}
 
 		config.All = true
@@ -276,7 +276,7 @@
 	}
 
 	var taskFilter, isTask bool
-	if psFilters.Include("is-task") {
+	if psFilters.Contains("is-task") {
 		if psFilters.ExactMatch("is-task", "true") {
 			taskFilter = true
 			isTask = true
@@ -284,13 +284,13 @@
 			taskFilter = true
 			isTask = false
 		} else {
-			return nil, fmt.Errorf("Invalid filter 'is-task=%s'", psFilters.Get("is-task"))
+			return nil, invalidFilter{"is-task", psFilters.Get("is-task")}
 		}
 	}
 
 	err = psFilters.WalkValues("health", func(value string) error {
 		if !container.IsValidHealthString(value) {
-			return fmt.Errorf("Unrecognised filter value for health: %s", value)
+			return validationError{errors.Errorf("Unrecognised filter value for health: %s", value)}
 		}
 
 		return nil
@@ -319,7 +319,7 @@
 
 	imagesFilter := map[image.ID]bool{}
 	var ancestorFilter bool
-	if psFilters.Include("ancestor") {
+	if psFilters.Contains("ancestor") {
 		ancestorFilter = true
 		psFilters.WalkValues("ancestor", func(ancestor string) error {
 			id, platform, err := daemon.GetImageIDAndPlatform(ancestor)
@@ -465,7 +465,7 @@
 		return excludeContainer
 	}
 
-	if ctx.filters.Include("volume") {
+	if ctx.filters.Contains("volume") {
 		volumesByName := make(map[string]types.MountPoint)
 		for _, m := range container.Mounts {
 			if m.Name != "" {
@@ -509,7 +509,7 @@
 		networkExist = errors.New("container part of network")
 		noNetworks   = errors.New("container is not part of any networks")
 	)
-	if ctx.filters.Include("network") {
+	if ctx.filters.Contains("network") {
 		err := ctx.filters.WalkValues("network", func(value string) error {
 			if container.NetworkSettings == nil {
 				return noNetworks
@@ -567,7 +567,7 @@
 	image := s.Image // keep the original ref if still valid (hasn't changed)
 	if image != s.ImageID {
 		id, _, err := daemon.GetImageIDAndPlatform(image)
-		if _, isDNE := err.(ErrImageDoesNotExist); err != nil && !isDNE {
+		if _, isDNE := err.(errImageDoesNotExist); err != nil && !isDNE {
 			return nil, err
 		}
 		if err != nil || id.String() != s.ImageID {
@@ -585,7 +585,7 @@
 	var (
 		volumesOut []*types.Volume
 	)
-	volFilters, err := filters.FromParam(filter)
+	volFilters, err := filters.FromJSON(filter)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -627,17 +627,17 @@
 
 	var retVols []volume.Volume
 	for _, vol := range vols {
-		if filter.Include("name") {
+		if filter.Contains("name") {
 			if !filter.Match("name", vol.Name()) {
 				continue
 			}
 		}
-		if filter.Include("driver") {
+		if filter.Contains("driver") {
 			if !filter.ExactMatch("driver", vol.DriverName()) {
 				continue
 			}
 		}
-		if filter.Include("label") {
+		if filter.Contains("label") {
 			v, ok := vol.(volume.DetailedVolume)
 			if !ok {
 				continue
@@ -649,11 +649,11 @@
 		retVols = append(retVols, vol)
 	}
 	danglingOnly := false
-	if filter.Include("dangling") {
+	if filter.Contains("dangling") {
 		if filter.ExactMatch("dangling", "true") || filter.ExactMatch("dangling", "1") {
 			danglingOnly = true
 		} else if !filter.ExactMatch("dangling", "false") && !filter.ExactMatch("dangling", "0") {
-			return nil, fmt.Errorf("Invalid filter 'dangling=%s'", filter.Get("dangling"))
+			return nil, invalidFilter{"dangling", filter.Get("dangling")}
 		}
 		retVols = daemon.volumes.FilterByUsed(retVols, !danglingOnly)
 	}
diff --git a/pkg/listeners/group_unix.go b/daemon/listeners/group_unix.go
similarity index 100%
rename from pkg/listeners/group_unix.go
rename to daemon/listeners/group_unix.go
diff --git a/pkg/listeners/listeners_solaris.go b/daemon/listeners/listeners_solaris.go
similarity index 96%
rename from pkg/listeners/listeners_solaris.go
rename to daemon/listeners/listeners_solaris.go
index c9003bc..ee1bd0f 100644
--- a/pkg/listeners/listeners_solaris.go
+++ b/daemon/listeners/listeners_solaris.go
@@ -6,8 +6,8 @@
 	"net"
 	"os"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/go-connections/sockets"
+	"github.com/sirupsen/logrus"
 )
 
 // Init creates new listeners for the server.
diff --git a/pkg/listeners/listeners_unix.go b/daemon/listeners/listeners_unix.go
similarity index 97%
rename from pkg/listeners/listeners_unix.go
rename to daemon/listeners/listeners_unix.go
index 25c98fb..0a4e5e4 100644
--- a/pkg/listeners/listeners_unix.go
+++ b/daemon/listeners/listeners_unix.go
@@ -9,9 +9,9 @@
 	"os"
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/coreos/go-systemd/activation"
 	"github.com/docker/go-connections/sockets"
+	"github.com/sirupsen/logrus"
 )
 
 // Init creates new listeners for the server.
@@ -86,7 +86,7 @@
 		return nil, fmt.Errorf("failed to parse systemd fd address: should be a number: %v", addr)
 	}
 	fdOffset := fdNum - 3
-	if len(listeners) < int(fdOffset)+1 {
+	if len(listeners) < fdOffset+1 {
 		return nil, fmt.Errorf("too few socket activated files passed in by systemd")
 	}
 	if listeners[fdOffset] == nil {
diff --git a/pkg/listeners/listeners_windows.go b/daemon/listeners/listeners_windows.go
similarity index 100%
rename from pkg/listeners/listeners_windows.go
rename to daemon/listeners/listeners_windows.go
diff --git a/daemon/logger/adapter.go b/daemon/logger/adapter.go
index a187b30..98852e8 100644
--- a/daemon/logger/adapter.go
+++ b/daemon/logger/adapter.go
@@ -7,10 +7,10 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/plugins/logdriver"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // pluginAdapter takes a plugin and implements the Logger interface for logger
diff --git a/daemon/logger/awslogs/cloudwatchlogs.go b/daemon/logger/awslogs/cloudwatchlogs.go
index 4d98468..3a7f2f6 100644
--- a/daemon/logger/awslogs/cloudwatchlogs.go
+++ b/daemon/logger/awslogs/cloudwatchlogs.go
@@ -2,7 +2,6 @@
 package awslogs
 
 import (
-	"bytes"
 	"fmt"
 	"os"
 	"regexp"
@@ -13,7 +12,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/ec2metadata"
@@ -23,8 +21,8 @@
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/loggerutils"
 	"github.com/docker/docker/dockerversion"
-	"github.com/docker/docker/pkg/templates"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -194,19 +192,6 @@
 	/*milliseconds          */ `%L`: `\.\d{3}`,
 }
 
-func parseLogGroup(info logger.Info, groupTemplate string) (string, error) {
-	tmpl, err := templates.NewParse("log-group", groupTemplate)
-	if err != nil {
-		return "", err
-	}
-	buf := new(bytes.Buffer)
-	if err := tmpl.Execute(buf, &info); err != nil {
-		return "", err
-	}
-
-	return buf.String(), nil
-}
-
 // newRegionFinder is a variable such that the implementation
 // can be swapped out for unit tests.
 var newRegionFinder = func() regionFinder {
@@ -384,15 +369,18 @@
 				eventBufferNegative := eventBufferAge < 0
 				if eventBufferExpired || eventBufferNegative {
 					events = l.processEvent(events, eventBuffer, eventBufferTimestamp)
+					eventBuffer = eventBuffer[:0]
 				}
 			}
 			l.publishBatch(events)
 			events = events[:0]
 		case msg, more := <-l.messages:
 			if !more {
-				// Flush event buffer
+				// Flush event buffer and release resources
 				events = l.processEvent(events, eventBuffer, eventBufferTimestamp)
+				eventBuffer = eventBuffer[:0]
 				l.publishBatch(events)
+				events = events[:0]
 				return
 			}
 			if eventBufferTimestamp == 0 {
@@ -400,17 +388,13 @@
 			}
 			unprocessedLine := msg.Line
 			if l.multilinePattern != nil {
-				if l.multilinePattern.Match(unprocessedLine) {
-					// This is a new log event so flush the current eventBuffer to events
+				if l.multilinePattern.Match(unprocessedLine) || len(eventBuffer)+len(unprocessedLine) > maximumBytesPerEvent {
+					// This is a new log event or we will exceed max bytes per event
+					// so flush the current eventBuffer to events and reset timestamp
 					events = l.processEvent(events, eventBuffer, eventBufferTimestamp)
 					eventBufferTimestamp = msg.Timestamp.UnixNano() / int64(time.Millisecond)
 					eventBuffer = eventBuffer[:0]
 				}
-				// If we will exceed max bytes per event flush the current event buffer before appending
-				if len(eventBuffer)+len(unprocessedLine) > maximumBytesPerEvent {
-					events = l.processEvent(events, eventBuffer, eventBufferTimestamp)
-					eventBuffer = eventBuffer[:0]
-				}
 				// Append new line
 				processedLine := append(unprocessedLine, "\n"...)
 				eventBuffer = append(eventBuffer, processedLine...)
diff --git a/daemon/logger/awslogs/cloudwatchlogs_test.go b/daemon/logger/awslogs/cloudwatchlogs_test.go
index e3862ff..989eb6f 100644
--- a/daemon/logger/awslogs/cloudwatchlogs_test.go
+++ b/daemon/logger/awslogs/cloudwatchlogs_test.go
@@ -162,7 +162,7 @@
 		client: mockClient,
 	}
 	mockClient.createLogStreamResult <- &createLogStreamResult{
-		errorResult: errors.New("Error!"),
+		errorResult: errors.New("Error"),
 	}
 
 	err := stream.create()
@@ -243,7 +243,7 @@
 		sequenceToken: aws.String(sequenceToken),
 	}
 	mockClient.putLogEventsResult <- &putLogEventsResult{
-		errorResult: errors.New("Error!"),
+		errorResult: errors.New("Error"),
 	}
 
 	events := []wrappedEvent{
@@ -641,7 +641,7 @@
 	})
 
 	// Fire ticker batchPublishFrequency seconds later
-	ticks <- time.Now().Add(batchPublishFrequency * time.Second)
+	ticks <- time.Now().Add(batchPublishFrequency + time.Second)
 
 	// Verify single multiline event is flushed after maximum event buffer age (batchPublishFrequency)
 	argument := <-mockClient.putLogEventsArgument
@@ -649,6 +649,20 @@
 	assert.Equal(t, 1, len(argument.LogEvents), "Expected single multiline event")
 	assert.Equal(t, logline+"\n"+logline+"\n", *argument.LogEvents[0].Message, "Received incorrect multiline message")
 
+	// Log an event 1 second later
+	stream.Log(&logger.Message{
+		Line:      []byte(logline),
+		Timestamp: time.Now().Add(time.Second),
+	})
+
+	// Fire ticker another batchPublishFrequency seconds later
+	ticks <- time.Now().Add(2*batchPublishFrequency + time.Second)
+
+	// Verify the event buffer is truly flushed - we should only receive a single event
+	argument = <-mockClient.putLogEventsArgument
+	assert.NotNil(t, argument, "Expected non-nil PutLogEventsInput")
+	assert.Equal(t, 1, len(argument.LogEvents), "Expected single multiline event")
+	assert.Equal(t, logline+"\n", *argument.LogEvents[0].Message, "Received incorrect multiline message")
 	stream.Close()
 }
 
diff --git a/daemon/logger/copier.go b/daemon/logger/copier.go
index 65d8fb1..c773fc6 100644
--- a/daemon/logger/copier.go
+++ b/daemon/logger/copier.go
@@ -6,7 +6,7 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/daemon/logger/etwlogs/etwlogs_windows.go b/daemon/logger/etwlogs/etwlogs_windows.go
index 8608f15..aa530e7 100644
--- a/daemon/logger/etwlogs/etwlogs_windows.go
+++ b/daemon/logger/etwlogs/etwlogs_windows.go
@@ -18,8 +18,8 @@
 	"sync"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/windows"
 )
 
diff --git a/daemon/logger/factory.go b/daemon/logger/factory.go
index 3200159..2ef3bf8 100644
--- a/daemon/logger/factory.go
+++ b/daemon/logger/factory.go
@@ -93,7 +93,7 @@
 	lf.m.Lock()
 	defer lf.m.Unlock()
 
-	c, _ := lf.optValidator[name]
+	c := lf.optValidator[name]
 	return c
 }
 
diff --git a/daemon/logger/fluentd/fluentd.go b/daemon/logger/fluentd/fluentd.go
index c8977ec..6a0653e 100644
--- a/daemon/logger/fluentd/fluentd.go
+++ b/daemon/logger/fluentd/fluentd.go
@@ -11,13 +11,13 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/loggerutils"
 	"github.com/docker/docker/pkg/urlutil"
 	"github.com/docker/go-units"
 	"github.com/fluent/fluent-logger-golang/fluent"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 type fluentd struct {
diff --git a/daemon/logger/gcplogs/gcplogging.go b/daemon/logger/gcplogs/gcplogging.go
index a33566a..5fdd137 100644
--- a/daemon/logger/gcplogs/gcplogging.go
+++ b/daemon/logger/gcplogs/gcplogging.go
@@ -10,7 +10,7 @@
 
 	"cloud.google.com/go/compute/metadata"
 	"cloud.google.com/go/logging"
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
 )
diff --git a/daemon/logger/gcplogs/gcplogging_linux.go b/daemon/logger/gcplogs/gcplogging_linux.go
index 9af8b3c..8917bdd 100644
--- a/daemon/logger/gcplogs/gcplogging_linux.go
+++ b/daemon/logger/gcplogs/gcplogging_linux.go
@@ -5,9 +5,9 @@
 import (
 	"os"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/pkg/homedir"
+	"github.com/sirupsen/logrus"
 )
 
 // ensureHomeIfIAmStatic ensure $HOME to be set if dockerversion.IAmStatic is "true".
diff --git a/daemon/logger/gelf/gelf.go b/daemon/logger/gelf/gelf.go
index 4b0130d..de209ce 100644
--- a/daemon/logger/gelf/gelf.go
+++ b/daemon/logger/gelf/gelf.go
@@ -14,10 +14,10 @@
 	"time"
 
 	"github.com/Graylog2/go-gelf/gelf"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/loggerutils"
 	"github.com/docker/docker/pkg/urlutil"
+	"github.com/sirupsen/logrus"
 )
 
 const name = "gelf"
diff --git a/daemon/logger/journald/journald.go b/daemon/logger/journald/journald.go
index 86d7378..46aac83 100644
--- a/daemon/logger/journald/journald.go
+++ b/daemon/logger/journald/journald.go
@@ -9,10 +9,10 @@
 	"sync"
 	"unicode"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/coreos/go-systemd/journal"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/loggerutils"
+	"github.com/sirupsen/logrus"
 )
 
 const name = "journald"
diff --git a/daemon/logger/journald/read.go b/daemon/logger/journald/read.go
index 4c6301a..4d9b999 100644
--- a/daemon/logger/journald/read.go
+++ b/daemon/logger/journald/read.go
@@ -155,10 +155,10 @@
 	"time"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/coreos/go-systemd/journal"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/sirupsen/logrus"
 )
 
 func (s *journald) Close() error {
diff --git a/daemon/logger/jsonfilelog/jsonfilelog.go b/daemon/logger/jsonfilelog/jsonfilelog.go
index e8df0ec..177c070 100644
--- a/daemon/logger/jsonfilelog/jsonfilelog.go
+++ b/daemon/logger/jsonfilelog/jsonfilelog.go
@@ -11,12 +11,12 @@
 	"strconv"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog"
 	"github.com/docker/docker/daemon/logger/loggerutils"
-	"github.com/docker/docker/pkg/jsonlog"
-	"github.com/docker/go-units"
+	units "github.com/docker/go-units"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // Name is the name of the file that the jsonlogger logs to.
@@ -106,25 +106,19 @@
 		return err
 	}
 	logger.PutMessage(m)
-	if _, err := w.Write(buf.Bytes()); err != nil {
-		return errors.Wrap(err, "error writing log entry")
-	}
-	return nil
+	_, err := w.Write(buf.Bytes())
+	return errors.Wrap(err, "error writing log entry")
 }
 
 func marshalMessage(msg *logger.Message, extra json.RawMessage, buf *bytes.Buffer) error {
-	timestamp, err := jsonlog.FastTimeMarshalJSON(msg.Timestamp)
-	if err != nil {
-		return err
-	}
 	logLine := msg.Line
 	if !msg.Partial {
 		logLine = append(msg.Line, '\n')
 	}
-	err = (&jsonlog.JSONLogs{
+	err := (&jsonlog.JSONLogs{
 		Log:      logLine,
 		Stream:   msg.Source,
-		Created:  timestamp,
+		Created:  msg.Timestamp,
 		RawAttrs: extra,
 	}).MarshalJSONBuf(buf)
 	if err != nil {
diff --git a/daemon/logger/jsonfilelog/jsonfilelog_test.go b/daemon/logger/jsonfilelog/jsonfilelog_test.go
index d2d36e9..2b2b2b5 100644
--- a/daemon/logger/jsonfilelog/jsonfilelog_test.go
+++ b/daemon/logger/jsonfilelog/jsonfilelog_test.go
@@ -1,6 +1,7 @@
 package jsonfilelog
 
 import (
+	"bytes"
 	"encoding/json"
 	"io/ioutil"
 	"os"
@@ -11,7 +12,9 @@
 	"time"
 
 	"github.com/docker/docker/daemon/logger"
-	"github.com/docker/docker/pkg/jsonlog"
+	"github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog"
+	"github.com/gotestyourself/gotestyourself/fs"
+	"github.com/stretchr/testify/require"
 )
 
 func TestJSONFileLogger(t *testing.T) {
@@ -54,36 +57,38 @@
 	}
 }
 
-func BenchmarkJSONFileLogger(b *testing.B) {
-	cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
-	tmp, err := ioutil.TempDir("", "docker-logger-")
-	if err != nil {
-		b.Fatal(err)
-	}
-	defer os.RemoveAll(tmp)
-	filename := filepath.Join(tmp, "container.log")
-	l, err := New(logger.Info{
-		ContainerID: cid,
-		LogPath:     filename,
-	})
-	if err != nil {
-		b.Fatal(err)
-	}
-	defer l.Close()
+func BenchmarkJSONFileLoggerLog(b *testing.B) {
+	tmp := fs.NewDir(b, "bench-jsonfilelog")
+	defer tmp.Remove()
 
-	testLine := "Line that thinks that it is log line from docker\n"
-	msg := &logger.Message{Line: []byte(testLine), Source: "stderr", Timestamp: time.Now().UTC()}
-	jsonlog, err := (&jsonlog.JSONLog{Log: string(msg.Line) + "\n", Stream: msg.Source, Created: msg.Timestamp}).MarshalJSON()
-	if err != nil {
-		b.Fatal(err)
+	jsonlogger, err := New(logger.Info{
+		ContainerID: "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657",
+		LogPath:     tmp.Join("container.log"),
+		Config: map[string]string{
+			"labels": "first,second",
+		},
+		ContainerLabels: map[string]string{
+			"first":  "label_value",
+			"second": "label_foo",
+		},
+	})
+	require.NoError(b, err)
+	defer jsonlogger.Close()
+
+	msg := &logger.Message{
+		Line:      []byte("Line that thinks that it is log line from docker\n"),
+		Source:    "stderr",
+		Timestamp: time.Now().UTC(),
 	}
-	b.SetBytes(int64(len(jsonlog)+1) * 30)
+
+	buf := bytes.NewBuffer(nil)
+	require.NoError(b, marshalMessage(msg, jsonlogger.(*JSONFileLogger).extra, buf))
+	b.SetBytes(int64(buf.Len()))
+
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		for j := 0; j < 30; j++ {
-			if err := l.Log(msg); err != nil {
-				b.Fatal(err)
-			}
+		if err := jsonlogger.Log(msg); err != nil {
+			b.Fatal(err)
 		}
 	}
 }
@@ -200,50 +205,3 @@
 		t.Fatalf("Wrong log attrs: %q, expected %q", extra, expected)
 	}
 }
-
-func BenchmarkJSONFileLoggerWithReader(b *testing.B) {
-	b.StopTimer()
-	b.ResetTimer()
-	cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
-	dir, err := ioutil.TempDir("", "json-logger-bench")
-	if err != nil {
-		b.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
-
-	l, err := New(logger.Info{
-		ContainerID: cid,
-		LogPath:     filepath.Join(dir, "container.log"),
-	})
-	if err != nil {
-		b.Fatal(err)
-	}
-	defer l.Close()
-	msg := &logger.Message{Line: []byte("line"), Source: "src1"}
-	jsonlog, err := (&jsonlog.JSONLog{Log: string(msg.Line) + "\n", Stream: msg.Source, Created: msg.Timestamp}).MarshalJSON()
-	if err != nil {
-		b.Fatal(err)
-	}
-	b.SetBytes(int64(len(jsonlog)+1) * 30)
-
-	b.StartTimer()
-
-	go func() {
-		for i := 0; i < b.N; i++ {
-			for j := 0; j < 30; j++ {
-				l.Log(msg)
-			}
-		}
-		l.Close()
-	}()
-
-	lw := l.(logger.LogReader).ReadLogs(logger.ReadConfig{Follow: true})
-	watchClose := lw.WatchClose()
-	for {
-		select {
-		case <-lw.Msg:
-		case <-watchClose:
-			return
-		}
-	}
-}
diff --git a/daemon/logger/jsonfilelog/jsonlog/jsonlog.go b/daemon/logger/jsonfilelog/jsonlog/jsonlog.go
new file mode 100644
index 0000000..549e355
--- /dev/null
+++ b/daemon/logger/jsonfilelog/jsonlog/jsonlog.go
@@ -0,0 +1,25 @@
+package jsonlog
+
+import (
+	"time"
+)
+
+// JSONLog is a log message, typically a single entry from a given log stream.
+type JSONLog struct {
+	// Log is the log message
+	Log string `json:"log,omitempty"`
+	// Stream is the log source
+	Stream string `json:"stream,omitempty"`
+	// Created is the created timestamp of log
+	Created time.Time `json:"time"`
+	// Attrs is the list of extra attributes provided by the user
+	Attrs map[string]string `json:"attrs,omitempty"`
+}
+
+// Reset all fields to their zero value.
+func (jl *JSONLog) Reset() {
+	jl.Log = ""
+	jl.Stream = ""
+	jl.Created = time.Time{}
+	jl.Attrs = make(map[string]string)
+}
diff --git a/pkg/jsonlog/jsonlogbytes.go b/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes.go
similarity index 77%
rename from pkg/jsonlog/jsonlogbytes.go
rename to daemon/logger/jsonfilelog/jsonlog/jsonlogbytes.go
index 0ba716f..37604ae 100644
--- a/pkg/jsonlog/jsonlogbytes.go
+++ b/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes.go
@@ -3,23 +3,22 @@
 import (
 	"bytes"
 	"encoding/json"
+	"time"
 	"unicode/utf8"
 )
 
-// JSONLogs is based on JSONLog.
-// It allows marshalling JSONLog from Log as []byte
-// and an already marshalled Created timestamp.
+// JSONLogs marshals encoded JSONLog objects
 type JSONLogs struct {
-	Log     []byte `json:"log,omitempty"`
-	Stream  string `json:"stream,omitempty"`
-	Created string `json:"time"`
+	Log     []byte    `json:"log,omitempty"`
+	Stream  string    `json:"stream,omitempty"`
+	Created time.Time `json:"time"`
 
 	// json-encoded bytes
 	RawAttrs json.RawMessage `json:"attrs,omitempty"`
 }
 
-// MarshalJSONBuf is based on the same method from JSONLog
-// It has been modified to take into account the necessary changes.
+// MarshalJSONBuf is an optimized JSON marshaller that avoids reflection
+// and unnecessary allocation.
 func (mj *JSONLogs) MarshalJSONBuf(buf *bytes.Buffer) error {
 	var first = true
 
@@ -36,7 +35,7 @@
 			buf.WriteString(`,`)
 		}
 		buf.WriteString(`"stream":`)
-		ffjsonWriteJSONString(buf, mj.Stream)
+		ffjsonWriteJSONBytesAsString(buf, []byte(mj.Stream))
 	}
 	if len(mj.RawAttrs) > 0 {
 		if first {
@@ -50,14 +49,18 @@
 	if !first {
 		buf.WriteString(`,`)
 	}
+
+	created, err := fastTimeMarshalJSON(mj.Created)
+	if err != nil {
+		return err
+	}
+
 	buf.WriteString(`"time":`)
-	buf.WriteString(mj.Created)
+	buf.WriteString(created)
 	buf.WriteString(`}`)
 	return nil
 }
 
-// This is based on ffjsonWriteJSONBytesAsString. It has been changed
-// to accept a string passed as a slice of bytes.
 func ffjsonWriteJSONBytesAsString(buf *bytes.Buffer, s []byte) {
 	const hex = "0123456789abcdef"
 
diff --git a/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go b/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go
new file mode 100644
index 0000000..4645cd4
--- /dev/null
+++ b/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go
@@ -0,0 +1,40 @@
+package jsonlog
+
+import (
+	"bytes"
+	"encoding/json"
+	"regexp"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestJSONLogsMarshalJSONBuf(t *testing.T) {
+	logs := map[*JSONLogs]string{
+		{Log: []byte(`"A log line with \\"`)}:                  `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":`,
+		{Log: []byte("A log line")}:                            `^{\"log\":\"A log line\",\"time\":`,
+		{Log: []byte("A log line with \r")}:                    `^{\"log\":\"A log line with \\r\",\"time\":`,
+		{Log: []byte("A log line with & < >")}:                 `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":`,
+		{Log: []byte("A log line with utf8 : 🚀 ψ ω β")}:        `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":`,
+		{Stream: "stdout"}:                                     `^{\"stream\":\"stdout\",\"time\":`,
+		{Stream: "stdout", Log: []byte("A log line")}:          `^{\"log\":\"A log line\",\"stream\":\"stdout\",\"time\":`,
+		{Created: time.Date(2017, 9, 1, 1, 1, 1, 1, time.UTC)}: `^{\"time\":"2017-09-01T01:01:01.000000001Z"}$`,
+
+		{}: `^{\"time\":"0001-01-01T00:00:00Z"}$`,
+		// These ones are a little weird
+		{Log: []byte("\u2028 \u2029")}: `^{\"log\":\"\\u2028 \\u2029\",\"time\":`,
+		{Log: []byte{0xaF}}:            `^{\"log\":\"\\ufffd\",\"time\":`,
+		{Log: []byte{0x7F}}:            `^{\"log\":\"\x7f\",\"time\":`,
+		// with raw attributes
+		{Log: []byte("A log line"), RawAttrs: []byte(`{"hello":"world","value":1234}`)}: `^{\"log\":\"A log line\",\"attrs\":{\"hello\":\"world\",\"value\":1234},\"time\":`,
+	}
+	for jsonLog, expression := range logs {
+		var buf bytes.Buffer
+		err := jsonLog.MarshalJSONBuf(&buf)
+		require.NoError(t, err)
+		assert.Regexp(t, regexp.MustCompile(expression), buf.String())
+		assert.NoError(t, json.Unmarshal(buf.Bytes(), &map[string]interface{}{}))
+	}
+}
diff --git a/daemon/logger/jsonfilelog/jsonlog/time_marshalling.go b/daemon/logger/jsonfilelog/jsonlog/time_marshalling.go
new file mode 100644
index 0000000..5fd8023
--- /dev/null
+++ b/daemon/logger/jsonfilelog/jsonlog/time_marshalling.go
@@ -0,0 +1,20 @@
+package jsonlog
+
+import (
+	"time"
+
+	"github.com/pkg/errors"
+)
+
+const jsonFormat = `"` + time.RFC3339Nano + `"`
+
+// fastTimeMarshalJSON avoids one of the extra allocations that
+// time.MarshalJSON is making.
+func fastTimeMarshalJSON(t time.Time) (string, error) {
+	if y := t.Year(); y < 0 || y >= 10000 {
+		// RFC 3339 is clear that years are 4 digits exactly.
+		// See golang.org/issue/4556#c15 for more discussion.
+		return "", errors.New("time.MarshalJSON: year outside of range [0,9999]")
+	}
+	return t.Format(jsonFormat), nil
+}
diff --git a/daemon/logger/jsonfilelog/jsonlog/time_marshalling_test.go b/daemon/logger/jsonfilelog/jsonlog/time_marshalling_test.go
new file mode 100644
index 0000000..931a9d3
--- /dev/null
+++ b/daemon/logger/jsonfilelog/jsonlog/time_marshalling_test.go
@@ -0,0 +1,35 @@
+package jsonlog
+
+import (
+	"testing"
+	"time"
+
+	"github.com/docker/docker/internal/testutil"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestFastTimeMarshalJSONWithInvalidYear(t *testing.T) {
+	aTime := time.Date(-1, 1, 1, 0, 0, 0, 0, time.Local)
+	_, err := fastTimeMarshalJSON(aTime)
+	testutil.ErrorContains(t, err, "year outside of range")
+
+	anotherTime := time.Date(10000, 1, 1, 0, 0, 0, 0, time.Local)
+	_, err = fastTimeMarshalJSON(anotherTime)
+	testutil.ErrorContains(t, err, "year outside of range")
+}
+
+func TestFastTimeMarshalJSON(t *testing.T) {
+	aTime := time.Date(2015, 5, 29, 11, 1, 2, 3, time.UTC)
+	json, err := fastTimeMarshalJSON(aTime)
+	require.NoError(t, err)
+	assert.Equal(t, "\"2015-05-29T11:01:02.000000003Z\"", json)
+
+	location, err := time.LoadLocation("Europe/Paris")
+	require.NoError(t, err)
+
+	aTime = time.Date(2015, 5, 29, 11, 1, 2, 3, location)
+	json, err = fastTimeMarshalJSON(aTime)
+	require.NoError(t, err)
+	assert.Equal(t, "\"2015-05-29T11:01:02.000000003+02:00\"", json)
+}
diff --git a/daemon/logger/jsonfilelog/read.go b/daemon/logger/jsonfilelog/read.go
index db53fd5..2586c7d 100644
--- a/daemon/logger/jsonfilelog/read.go
+++ b/daemon/logger/jsonfilelog/read.go
@@ -11,14 +11,14 @@
 	"github.com/fsnotify/fsnotify"
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/backend"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog"
 	"github.com/docker/docker/daemon/logger/jsonfilelog/multireader"
 	"github.com/docker/docker/pkg/filenotify"
-	"github.com/docker/docker/pkg/jsonlog"
 	"github.com/docker/docker/pkg/tailfile"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 const maxJSONDecodeRetry = 20000
@@ -137,8 +137,7 @@
 }
 
 func tailFile(f io.ReadSeeker, logWatcher *logger.LogWatcher, tail int, since time.Time) {
-	var rdr io.Reader
-	rdr = f
+	rdr := io.Reader(f)
 	if tail > 0 {
 		ls, err := tailfile.TailFile(f, tail)
 		if err != nil {
@@ -148,9 +147,8 @@
 		rdr = bytes.NewBuffer(bytes.Join(ls, []byte("\n")))
 	}
 	dec := json.NewDecoder(rdr)
-	l := &jsonlog.JSONLog{}
 	for {
-		msg, err := decodeLogLine(dec, l)
+		msg, err := decodeLogLine(dec, &jsonlog.JSONLog{})
 		if err != nil {
 			if err != io.EOF {
 				logWatcher.Err <- err
diff --git a/daemon/logger/jsonfilelog/read_test.go b/daemon/logger/jsonfilelog/read_test.go
new file mode 100644
index 0000000..01a05c4
--- /dev/null
+++ b/daemon/logger/jsonfilelog/read_test.go
@@ -0,0 +1,64 @@
+package jsonfilelog
+
+import (
+	"bytes"
+	"testing"
+	"time"
+
+	"github.com/docker/docker/daemon/logger"
+	"github.com/gotestyourself/gotestyourself/fs"
+	"github.com/stretchr/testify/require"
+)
+
+func BenchmarkJSONFileLoggerReadLogs(b *testing.B) {
+	tmp := fs.NewDir(b, "bench-jsonfilelog")
+	defer tmp.Remove()
+
+	jsonlogger, err := New(logger.Info{
+		ContainerID: "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657",
+		LogPath:     tmp.Join("container.log"),
+		Config: map[string]string{
+			"labels": "first,second",
+		},
+		ContainerLabels: map[string]string{
+			"first":  "label_value",
+			"second": "label_foo",
+		},
+	})
+	require.NoError(b, err)
+	defer jsonlogger.Close()
+
+	msg := &logger.Message{
+		Line:      []byte("Line that thinks that it is log line from docker\n"),
+		Source:    "stderr",
+		Timestamp: time.Now().UTC(),
+	}
+
+	buf := bytes.NewBuffer(nil)
+	require.NoError(b, marshalMessage(msg, jsonlogger.(*JSONFileLogger).extra, buf))
+	b.SetBytes(int64(buf.Len()))
+
+	b.ResetTimer()
+
+	chError := make(chan error, b.N+1)
+	go func() {
+		for i := 0; i < b.N; i++ {
+			chError <- jsonlogger.Log(msg)
+		}
+		chError <- jsonlogger.Close()
+	}()
+
+	lw := jsonlogger.(*JSONFileLogger).ReadLogs(logger.ReadConfig{Follow: true})
+	watchClose := lw.WatchClose()
+	for {
+		select {
+		case <-lw.Msg:
+		case <-watchClose:
+			return
+		case err := <-chError:
+			if err != nil {
+				b.Fatal(err)
+			}
+		}
+	}
+}
diff --git a/daemon/logger/logentries/logentries.go b/daemon/logger/logentries/logentries.go
index a353d9d..e28707c 100644
--- a/daemon/logger/logentries/logentries.go
+++ b/daemon/logger/logentries/logentries.go
@@ -4,10 +4,12 @@
 
 import (
 	"fmt"
+	"strconv"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/bsphere/le_go"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 type logentries struct {
@@ -16,11 +18,13 @@
 	containerName string
 	writer        *le_go.Logger
 	extra         map[string]string
+	lineOnly      bool
 }
 
 const (
-	name  = "logentries"
-	token = "logentries-token"
+	name     = "logentries"
+	token    = "logentries-token"
+	lineonly = "line-only"
 )
 
 func init() {
@@ -38,32 +42,44 @@
 func New(info logger.Info) (logger.Logger, error) {
 	logrus.WithField("container", info.ContainerID).
 		WithField("token", info.Config[token]).
+		WithField("line-only", info.Config[lineonly]).
 		Debug("logging driver logentries configured")
 
 	log, err := le_go.Connect(info.Config[token])
 	if err != nil {
-		return nil, err
+		return nil, errors.Wrap(err, "error connecting to logentries")
+	}
+	var lineOnly bool
+	if lineOnly, err = strconv.ParseBool(info.Config[lineonly]); err != nil {
+		return nil, errors.Wrap(err, "error parsing lineonly option")
 	}
 	return &logentries{
 		containerID:   info.ContainerID,
 		containerName: info.ContainerName,
 		writer:        log,
+		lineOnly:      lineOnly,
 	}, nil
 }
 
 func (f *logentries) Log(msg *logger.Message) error {
-	data := map[string]string{
-		"container_id":   f.containerID,
-		"container_name": f.containerName,
-		"source":         msg.Source,
-		"log":            string(msg.Line),
+	if !f.lineOnly {
+		data := map[string]string{
+			"container_id":   f.containerID,
+			"container_name": f.containerName,
+			"source":         msg.Source,
+			"log":            string(msg.Line),
+		}
+		for k, v := range f.extra {
+			data[k] = v
+		}
+		ts := msg.Timestamp
+		logger.PutMessage(msg)
+		f.writer.Println(f.tag, ts, data)
+	} else {
+		line := msg.Line
+		logger.PutMessage(msg)
+		f.writer.Println(line)
 	}
-	for k, v := range f.extra {
-		data[k] = v
-	}
-	ts := msg.Timestamp
-	logger.PutMessage(msg)
-	f.writer.Println(f.tag, ts, data)
 	return nil
 }
 
diff --git a/daemon/logger/logger.go b/daemon/logger/logger.go
index 258a5dc..ee91b79 100644
--- a/daemon/logger/logger.go
+++ b/daemon/logger/logger.go
@@ -8,20 +8,23 @@
 package logger
 
 import (
-	"errors"
 	"sync"
 	"time"
 
 	"github.com/docker/docker/api/types/backend"
-	"github.com/docker/docker/pkg/jsonlog"
 )
 
-// ErrReadLogsNotSupported is returned when the logger does not support reading logs.
-var ErrReadLogsNotSupported = errors.New("configured logging driver does not support reading")
+// ErrReadLogsNotSupported is returned when the underlying log driver does not support reading
+type ErrReadLogsNotSupported struct{}
+
+func (ErrReadLogsNotSupported) Error() string {
+	return "configured logging driver does not support reading"
+}
+
+// NotImplemented makes this error implement the `NotImplemented` interface from api/errdefs
+func (ErrReadLogsNotSupported) NotImplemented() {}
 
 const (
-	// TimeFormat is the time format used for timestamps sent to log readers.
-	TimeFormat           = jsonlog.RFC3339NanoFixed
 	logWatcherBufferSize = 4096
 )
 
diff --git a/daemon/logger/loggerutils/log_tag.go b/daemon/logger/loggerutils/log_tag.go
index f801047..7c17090 100644
--- a/daemon/logger/loggerutils/log_tag.go
+++ b/daemon/logger/loggerutils/log_tag.go
@@ -4,7 +4,7 @@
 	"bytes"
 
 	"github.com/docker/docker/daemon/logger"
-	"github.com/docker/docker/pkg/templates"
+	"github.com/docker/docker/daemon/logger/templates"
 )
 
 // DefaultTemplate defines the defaults template logger should use.
diff --git a/daemon/logger/ring.go b/daemon/logger/ring.go
index 5c55955..c89897c 100644
--- a/daemon/logger/ring.go
+++ b/daemon/logger/ring.go
@@ -5,7 +5,7 @@
 	"sync"
 	"sync/atomic"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -202,7 +202,6 @@
 	r.closed = true
 	r.wait.Broadcast()
 	r.mu.Unlock()
-	return
 }
 
 // Drain drains all messages from the queue.
diff --git a/daemon/logger/splunk/splunk.go b/daemon/logger/splunk/splunk.go
index 233a2db..31a0487 100644
--- a/daemon/logger/splunk/splunk.go
+++ b/daemon/logger/splunk/splunk.go
@@ -15,13 +15,14 @@
 	"net/url"
 	"os"
 	"strconv"
+	"strings"
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/loggerutils"
 	"github.com/docker/docker/pkg/urlutil"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -203,7 +204,7 @@
 		}
 		gzipCompressionLevel = int(gzipCompressionLevel64)
 		if gzipCompressionLevel < gzip.DefaultCompression || gzipCompressionLevel > gzip.BestCompression {
-			err := fmt.Errorf("Not supported level '%s' for %s (supported values between %d and %d).",
+			err := fmt.Errorf("not supported level '%s' for %s (supported values between %d and %d)",
 				gzipCompressionLevelStr, splunkGzipCompressionLevelKey, gzip.DefaultCompression, gzip.BestCompression)
 			return nil, err
 		}
@@ -363,6 +364,11 @@
 }
 
 func (l *splunkLoggerRaw) Log(msg *logger.Message) error {
+	// empty or whitespace-only messages are not accepted by HEC
+	if strings.TrimSpace(string(msg.Line)) == "" {
+		return nil
+	}
+
 	message := l.createSplunkMessage(msg)
 
 	message.Event = string(append(l.prefix, msg.Line...))
diff --git a/daemon/logger/splunk/splunk_test.go b/daemon/logger/splunk/splunk_test.go
index cbe9a55..ebf835c 100644
--- a/daemon/logger/splunk/splunk_test.go
+++ b/daemon/logger/splunk/splunk_test.go
@@ -8,6 +8,7 @@
 	"time"
 
 	"github.com/docker/docker/daemon/logger"
+	"github.com/stretchr/testify/require"
 )
 
 // Validate options
@@ -125,7 +126,7 @@
 		splunkLoggerDriver.nullMessage.Source != "" ||
 		splunkLoggerDriver.nullMessage.SourceType != "" ||
 		splunkLoggerDriver.nullMessage.Index != "" ||
-		splunkLoggerDriver.gzipCompression != false ||
+		splunkLoggerDriver.gzipCompression ||
 		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
 		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
 		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
@@ -255,7 +256,7 @@
 		splunkLoggerDriver.nullMessage.Source != "mysource" ||
 		splunkLoggerDriver.nullMessage.SourceType != "mysourcetype" ||
 		splunkLoggerDriver.nullMessage.Index != "myindex" ||
-		splunkLoggerDriver.gzipCompression != true ||
+		!splunkLoggerDriver.gzipCompression ||
 		splunkLoggerDriver.gzipCompressionLevel != gzip.DefaultCompression ||
 		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
 		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
@@ -355,7 +356,7 @@
 		splunkLoggerDriver.nullMessage.Source != "" ||
 		splunkLoggerDriver.nullMessage.SourceType != "" ||
 		splunkLoggerDriver.nullMessage.Index != "" ||
-		splunkLoggerDriver.gzipCompression != true ||
+		!splunkLoggerDriver.gzipCompression ||
 		splunkLoggerDriver.gzipCompressionLevel != gzip.BestSpeed ||
 		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
 		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
@@ -448,14 +449,10 @@
 	}
 
 	hostname, err := info.Hostname()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	loggerDriver, err := New(info)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	if !hec.connectionVerified {
 		t.Fatal("By default connection should be verified")
@@ -472,7 +469,7 @@
 		splunkLoggerDriver.nullMessage.Source != "" ||
 		splunkLoggerDriver.nullMessage.SourceType != "" ||
 		splunkLoggerDriver.nullMessage.Index != "" ||
-		splunkLoggerDriver.gzipCompression != false ||
+		splunkLoggerDriver.gzipCompression ||
 		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
 		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
 		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
@@ -586,7 +583,7 @@
 		splunkLoggerDriver.nullMessage.Source != "" ||
 		splunkLoggerDriver.nullMessage.SourceType != "" ||
 		splunkLoggerDriver.nullMessage.Index != "" ||
-		splunkLoggerDriver.gzipCompression != false ||
+		splunkLoggerDriver.gzipCompression ||
 		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
 		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
 		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
@@ -698,7 +695,7 @@
 		splunkLoggerDriver.nullMessage.Source != "" ||
 		splunkLoggerDriver.nullMessage.SourceType != "" ||
 		splunkLoggerDriver.nullMessage.Index != "" ||
-		splunkLoggerDriver.gzipCompression != false ||
+		splunkLoggerDriver.gzipCompression ||
 		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
 		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
 		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
@@ -716,12 +713,19 @@
 	if err := loggerDriver.Log(&logger.Message{Line: []byte("notjson"), Source: "stdout", Timestamp: message2Time}); err != nil {
 		t.Fatal(err)
 	}
+	message3Time := time.Now()
+	if err := loggerDriver.Log(&logger.Message{Line: []byte(" "), Source: "stdout", Timestamp: message3Time}); err != nil {
+		t.Fatal(err)
+	}
 
 	err = loggerDriver.Close()
 	if err != nil {
 		t.Fatal(err)
 	}
 
+	// message3 would have an empty or whitespace only string in the "event" field
+	// both of which are not acceptable to HEC
+	// thus here we must expect 2 messages, not 3
 	if len(hec.messages) != 2 {
 		t.Fatal("Expected two messages")
 	}
diff --git a/daemon/logger/syslog/syslog.go b/daemon/logger/syslog/syslog.go
index 42855e1..b4cacd7 100644
--- a/daemon/logger/syslog/syslog.go
+++ b/daemon/logger/syslog/syslog.go
@@ -14,11 +14,11 @@
 
 	syslog "github.com/RackSec/srslog"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger/loggerutils"
 	"github.com/docker/docker/pkg/urlutil"
 	"github.com/docker/go-connections/tlsconfig"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/pkg/templates/templates.go b/daemon/logger/templates/templates.go
similarity index 65%
rename from pkg/templates/templates.go
rename to daemon/logger/templates/templates.go
index d2d7e0c..f632e6e 100644
--- a/pkg/templates/templates.go
+++ b/daemon/logger/templates/templates.go
@@ -27,34 +27,6 @@
 	"truncate": truncateWithLength,
 }
 
-// HeaderFunctions are used to created headers of a table.
-// This is a replacement of basicFunctions for header generation
-// because we want the header to remain intact.
-// Some functions like `split` are irrelevant so not added.
-var HeaderFunctions = template.FuncMap{
-	"json": func(v string) string {
-		return v
-	},
-	"title": func(v string) string {
-		return v
-	},
-	"lower": func(v string) string {
-		return v
-	},
-	"upper": func(v string) string {
-		return v
-	},
-	"truncate": func(v string, l int) string {
-		return v
-	},
-}
-
-// Parse creates a new anonymous template with the basic functions
-// and parses the given format.
-func Parse(format string) (*template.Template, error) {
-	return NewParse("", format)
-}
-
 // NewParse creates a new tagged template with the basic functions
 // and parses the given format.
 func NewParse(tag, format string) (*template.Template, error) {
diff --git a/daemon/logger/templates/templates_test.go b/daemon/logger/templates/templates_test.go
new file mode 100644
index 0000000..6205e1d
--- /dev/null
+++ b/daemon/logger/templates/templates_test.go
@@ -0,0 +1,18 @@
+package templates
+
+import (
+	"bytes"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestNewParse(t *testing.T) {
+	tm, err := NewParse("foo", "this is a {{ . }}")
+	assert.NoError(t, err)
+
+	var b bytes.Buffer
+	assert.NoError(t, tm.Execute(&b, "string"))
+	want := "this is a string"
+	assert.Equal(t, want, b.String())
+}
diff --git a/daemon/logs.go b/daemon/logs.go
index 96e1b8a..68c5e5a 100644
--- a/daemon/logs.go
+++ b/daemon/logs.go
@@ -7,13 +7,13 @@
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/backend"
 	containertypes "github.com/docker/docker/api/types/container"
 	timetypes "github.com/docker/docker/api/types/time"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerLogs copies the container's log channel to the channel provided in
@@ -22,7 +22,7 @@
 //
 // if it returns nil, the config channel will be active and return log
 // messages until it runs out or the context is canceled.
-func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, config *types.ContainerLogsOptions) (<-chan *backend.LogMessage, error) {
+func (daemon *Daemon) ContainerLogs(ctx context.Context, containerName string, config *types.ContainerLogsOptions) (<-chan *backend.LogMessage, bool, error) {
 	lg := logrus.WithFields(logrus.Fields{
 		"module":    "daemon",
 		"method":    "(*Daemon).ContainerLogs",
@@ -30,24 +30,24 @@
 	})
 
 	if !(config.ShowStdout || config.ShowStderr) {
-		return nil, errors.New("You must choose at least one stream")
+		return nil, false, validationError{errors.New("You must choose at least one stream")}
 	}
 	container, err := daemon.GetContainer(containerName)
 	if err != nil {
-		return nil, err
+		return nil, false, err
 	}
 
 	if container.RemovalInProgress || container.Dead {
-		return nil, errors.New("can not get logs from container which is dead or marked for removal")
+		return nil, false, stateConflictError{errors.New("can not get logs from container which is dead or marked for removal")}
 	}
 
 	if container.HostConfig.LogConfig.Type == "none" {
-		return nil, logger.ErrReadLogsNotSupported
+		return nil, false, logger.ErrReadLogsNotSupported{}
 	}
 
 	cLog, cLogCreated, err := daemon.getLogger(container)
 	if err != nil {
-		return nil, err
+		return nil, false, err
 	}
 	if cLogCreated {
 		defer func() {
@@ -59,7 +59,7 @@
 
 	logReader, ok := cLog.(logger.LogReader)
 	if !ok {
-		return nil, logger.ErrReadLogsNotSupported
+		return nil, false, logger.ErrReadLogsNotSupported{}
 	}
 
 	follow := config.Follow && !cLogCreated
@@ -72,7 +72,7 @@
 	if config.Since != "" {
 		s, n, err := timetypes.ParseTimestamps(config.Since, 0)
 		if err != nil {
-			return nil, err
+			return nil, false, err
 		}
 		since = time.Unix(s, n)
 	}
@@ -137,7 +137,7 @@
 			}
 		}
 	}()
-	return messageChan, nil
+	return messageChan, container.Config.Tty, nil
 }
 
 func (daemon *Daemon) getLogger(container *container.Container) (l logger.Logger, created bool, err error) {
diff --git a/daemon/metrics.go b/daemon/metrics.go
index bf9e49d..44228e7 100644
--- a/daemon/metrics.go
+++ b/daemon/metrics.go
@@ -4,19 +4,18 @@
 	"path/filepath"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/plugingetter"
-	"github.com/docker/go-metrics"
+	metrics "github.com/docker/go-metrics"
 	"github.com/pkg/errors"
 	"github.com/prometheus/client_golang/prometheus"
+	"github.com/sirupsen/logrus"
 )
 
 const metricsPluginType = "MetricsCollector"
 
 var (
 	containerActions          metrics.LabeledTimer
-	containerStates           metrics.LabeledGauge
 	imageActions              metrics.LabeledTimer
 	networkActions            metrics.LabeledTimer
 	engineInfo                metrics.LabeledGauge
@@ -170,5 +169,4 @@
 			logrus.WithError(err).WithField("name", p.Name()).WithField("socket", sockPath).Error("error unmounting metrics socket for plugin")
 		}
 	}
-	return
 }
diff --git a/daemon/metrics_unix.go b/daemon/metrics_unix.go
index 84166d1..6045939 100644
--- a/daemon/metrics_unix.go
+++ b/daemon/metrics_unix.go
@@ -8,12 +8,12 @@
 	"os"
 	"path/filepath"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugins"
 	metrics "github.com/docker/go-metrics"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/daemon/monitor.go b/daemon/monitor.go
index 5156d9a..3946e7a 100644
--- a/daemon/monitor.go
+++ b/daemon/monitor.go
@@ -7,11 +7,11 @@
 	"strconv"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/restartmanager"
+	"github.com/sirupsen/logrus"
 )
 
 func (daemon *Daemon) setStateCounter(c *container.Container) {
@@ -36,7 +36,7 @@
 	case libcontainerd.StateOOM:
 		// StateOOM is Linux specific and should never be hit on Windows
 		if runtime.GOOS == "windows" {
-			return errors.New("Received StateOOM from libcontainerd on Windows. This should never happen.")
+			return errors.New("received StateOOM from libcontainerd on Windows. This should never happen")
 		}
 		daemon.updateHealthMonitor(c)
 		if err := c.CheckpointTo(daemon.containersReplica); err != nil {
diff --git a/daemon/monitor_windows.go b/daemon/monitor_windows.go
index 9648b1b..15d656d 100644
--- a/daemon/monitor_windows.go
+++ b/daemon/monitor_windows.go
@@ -22,22 +22,17 @@
 			return err
 		}
 
-		newOpts := []libcontainerd.CreateOption{&libcontainerd.ServicingOption{
-			IsServicing: true,
-		}}
+		// Turn on servicing
+		spec.Windows.Servicing = true
 
 		copts, err := daemon.getLibcontainerdCreateOptions(container)
 		if err != nil {
 			return err
 		}
 
-		if copts != nil {
-			newOpts = append(newOpts, copts...)
-		}
-
 		// Create a new servicing container, which will start, complete the update, and merge back the
 		// results if it succeeded, all as part of the below function call.
-		if err := daemon.containerd.Create((container.ID + "_servicing"), "", "", *spec, container.InitializeStdio, newOpts...); err != nil {
+		if err := daemon.containerd.Create((container.ID + "_servicing"), "", "", *spec, container.InitializeStdio, copts...); err != nil {
 			container.SetExitCode(-1)
 			return fmt.Errorf("Post-run update servicing failed: %s", err)
 		}
diff --git a/daemon/names.go b/daemon/names.go
index 7cdabeb..712df9f 100644
--- a/daemon/names.go
+++ b/daemon/names.go
@@ -4,16 +4,17 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/daemon/names"
 	"github.com/docker/docker/pkg/namesgenerator"
 	"github.com/docker/docker/pkg/stringid"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 var (
-	validContainerNameChars   = api.RestrictedNameChars
-	validContainerNamePattern = api.RestrictedNamePattern
+	validContainerNameChars   = names.RestrictedNameChars
+	validContainerNamePattern = names.RestrictedNamePattern
 )
 
 func (daemon *Daemon) registerName(container *container.Container) error {
@@ -55,7 +56,7 @@
 
 func (daemon *Daemon) reserveName(id, name string) (string, error) {
 	if !validContainerNamePattern.MatchString(strings.TrimPrefix(name, "/")) {
-		return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
+		return "", validationError{errors.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)}
 	}
 	if name[0] != '/' {
 		name = "/" + name
@@ -68,9 +69,9 @@
 				logrus.Errorf("got unexpected error while looking up reserved name: %v", err)
 				return "", err
 			}
-			return "", fmt.Errorf("Conflict. The container name %q is already in use by container %q. You have to remove (or rename) that container to be able to reuse that name.", name, id)
+			return "", validationError{errors.Errorf("Conflict. The container name %q is already in use by container %q. You have to remove (or rename) that container to be able to reuse that name.", name, id)}
 		}
-		return "", fmt.Errorf("error reserving name: %q, error: %v", name, err)
+		return "", errors.Wrapf(err, "error reserving name: %q", name)
 	}
 	return name, nil
 }
diff --git a/api/names.go b/daemon/names/names.go
similarity index 96%
rename from api/names.go
rename to daemon/names/names.go
index f147d1f..26f6748 100644
--- a/api/names.go
+++ b/daemon/names/names.go
@@ -1,4 +1,4 @@
-package api
+package names
 
 import "regexp"
 
diff --git a/daemon/network.go b/daemon/network.go
index 366c2a5..bf8a2f5 100644
--- a/daemon/network.go
+++ b/daemon/network.go
@@ -8,8 +8,6 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
-	apierrors "github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/network"
 	clustertypes "github.com/docker/docker/daemon/cluster/provider"
@@ -21,6 +19,7 @@
 	"github.com/docker/libnetwork/ipamapi"
 	networktypes "github.com/docker/libnetwork/types"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -57,10 +56,10 @@
 	list := daemon.GetNetworksByID(partialID)
 
 	if len(list) == 0 {
-		return nil, libnetwork.ErrNoSuchNetwork(partialID)
+		return nil, errors.WithStack(networkNotFound(partialID))
 	}
 	if len(list) > 1 {
-		return nil, libnetwork.ErrInvalidID(partialID)
+		return nil, errors.WithStack(invalidIdentifier(partialID))
 	}
 	return list[0], nil
 }
@@ -116,6 +115,7 @@
 func (daemon *Daemon) startIngressWorker() {
 	ingressJobsChannel = make(chan *ingressJob, 100)
 	go func() {
+		// nolint: gosimple
 		for {
 			select {
 			case r := <-ingressJobsChannel:
@@ -182,27 +182,8 @@
 		logrus.Errorf("Failed getting ingress network by id after creating: %v", err)
 	}
 
-	sb, err := controller.NewSandbox("ingress-sbox", libnetwork.OptionIngress())
-	if err != nil {
-		if _, ok := err.(networktypes.ForbiddenError); !ok {
-			logrus.Errorf("Failed creating ingress sandbox: %v", err)
-		}
-		return
-	}
-
-	ep, err := n.CreateEndpoint("ingress-endpoint", libnetwork.CreateOptionIpam(ip, nil, nil, nil))
-	if err != nil {
-		logrus.Errorf("Failed creating ingress endpoint: %v", err)
-		return
-	}
-
-	if err := ep.Join(sb, nil); err != nil {
-		logrus.Errorf("Failed joining ingress sandbox to ingress endpoint: %v", err)
-		return
-	}
-
-	if err := sb.EnableService(); err != nil {
-		logrus.Errorf("Failed enabling service for ingress sandbox")
+	if err = daemon.createLoadBalancerSandbox("ingress", create.ID, ip, n, libnetwork.OptionIngress()); err != nil {
+		logrus.Errorf("Failed creating load balancer sandbox for ingress network: %v", err)
 	}
 }
 
@@ -233,7 +214,6 @@
 		logrus.Errorf("Failed to delete ingress network %s: %v", n.ID(), err)
 		return
 	}
-	return
 }
 
 // SetNetworkBootstrapKeys sets the bootstrap keys.
@@ -284,10 +264,38 @@
 	return resp, err
 }
 
+func (daemon *Daemon) createLoadBalancerSandbox(prefix, id string, ip net.IP, n libnetwork.Network, options ...libnetwork.SandboxOption) error {
+	c := daemon.netController
+	sandboxName := prefix + "-sbox"
+	sb, err := c.NewSandbox(sandboxName, options...)
+	if err != nil {
+		if _, ok := err.(networktypes.ForbiddenError); !ok {
+			return errors.Wrapf(err, "Failed creating %s sandbox", sandboxName)
+		}
+		return nil
+	}
+
+	endpointName := prefix + "-endpoint"
+	ep, err := n.CreateEndpoint(endpointName, libnetwork.CreateOptionIpam(ip, nil, nil, nil), libnetwork.CreateOptionLoadBalancer())
+	if err != nil {
+		return errors.Wrapf(err, "Failed creating %s in sandbox %s", endpointName, sandboxName)
+	}
+
+	if err := ep.Join(sb, nil); err != nil {
+		return errors.Wrapf(err, "Failed joining %s to sandbox %s", endpointName, sandboxName)
+	}
+
+	if err := sb.EnableService(); err != nil {
+		return errors.Wrapf(err, "Failed enabling service in %s sandbox", sandboxName)
+	}
+
+	return nil
+}
+
 func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string, agent bool) (*types.NetworkCreateResponse, error) {
 	if runconfig.IsPreDefinedNetwork(create.Name) && !agent {
 		err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
-		return nil, apierrors.NewRequestForbiddenError(err)
+		return nil, notAllowedError{err}
 	}
 
 	var warning string
@@ -349,6 +357,7 @@
 	n, err := c.NewNetwork(driver, create.Name, id, nwOptions...)
 	if err != nil {
 		if _, ok := err.(libnetwork.ErrDataStoreNotInitialized); ok {
+			// nolint: golint
 			return nil, errors.New("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
 		}
 		return nil, err
@@ -360,6 +369,18 @@
 	}
 	daemon.LogNetworkEvent(n, "create")
 
+	if agent && !n.Info().Ingress() && n.Type() == "overlay" {
+		nodeIP, exists := daemon.GetAttachmentStore().GetIPForNetwork(id)
+		if !exists {
+			return nil, fmt.Errorf("Failed to find a load balancer IP to use for network: %v", id)
+		}
+
+		if err := daemon.createLoadBalancerSandbox(create.Name, id, nodeIP, n); err != nil {
+			return nil, err
+		}
+
+	}
+
 	return &types.NetworkCreateResponse{
 		ID:      n.ID(),
 		Warning: warning,
@@ -496,6 +517,37 @@
 	return daemon.deleteNetwork(networkID, false)
 }
 
+func (daemon *Daemon) deleteLoadBalancerSandbox(n libnetwork.Network) {
+	controller := daemon.netController
+
+	//The only endpoint left should be the LB endpoint (nw.Name() + "-endpoint")
+	endpoints := n.Endpoints()
+	if len(endpoints) == 1 {
+		sandboxName := n.Name() + "-sbox"
+
+		info := endpoints[0].Info()
+		if info != nil {
+			sb := info.Sandbox()
+			if sb != nil {
+				if err := sb.DisableService(); err != nil {
+					logrus.Warnf("Failed to disable service on sandbox %s: %v", sandboxName, err)
+					//Ignore error and attempt to delete the load balancer endpoint
+				}
+			}
+		}
+
+		if err := endpoints[0].Delete(true); err != nil {
+			logrus.Warnf("Failed to delete endpoint %s (%s) in %s: %v", endpoints[0].Name(), endpoints[0].ID(), sandboxName, err)
+			//Ignore error and attempt to delete the sandbox.
+		}
+
+		if err := controller.SandboxDestroy(sandboxName); err != nil {
+			logrus.Warnf("Failed to delete %s sandbox: %v", sandboxName, err)
+			//Ignore error and attempt to delete the network.
+		}
+	}
+}
+
 func (daemon *Daemon) deleteNetwork(networkID string, dynamic bool) error {
 	nw, err := daemon.FindNetwork(networkID)
 	if err != nil {
@@ -504,7 +556,7 @@
 
 	if runconfig.IsPreDefinedNetwork(nw.Name()) && !dynamic {
 		err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name())
-		return apierrors.NewRequestForbiddenError(err)
+		return notAllowedError{err}
 	}
 
 	if dynamic && !nw.Info().Dynamic() {
@@ -514,7 +566,11 @@
 			return nil
 		}
 		err := fmt.Errorf("%s is not a dynamic network", nw.Name())
-		return apierrors.NewRequestForbiddenError(err)
+		return notAllowedError{err}
+	}
+
+	if !nw.Info().Ingress() && nw.Type() == "overlay" {
+		daemon.deleteLoadBalancerSandbox(nw)
 	}
 
 	if err := nw.Delete(); err != nil {
diff --git a/daemon/network/settings.go b/daemon/network/settings.go
index 8f6b7dd..d952b2b 100644
--- a/daemon/network/settings.go
+++ b/daemon/network/settings.go
@@ -1,9 +1,12 @@
 package network
 
 import (
+	"net"
+
 	networktypes "github.com/docker/docker/api/types/network"
 	clustertypes "github.com/docker/docker/daemon/cluster/provider"
 	"github.com/docker/go-connections/nat"
+	"github.com/pkg/errors"
 )
 
 // Settings stores configuration details about the daemon network config
@@ -31,3 +34,36 @@
 	*networktypes.EndpointSettings
 	IPAMOperational bool
 }
+
+// AttachmentStore stores the load balancer IP address for a network id.
+type AttachmentStore struct {
+	//key: networkd id
+	//value: load balancer ip address
+	networkToNodeLBIP map[string]net.IP
+}
+
+// ResetAttachments clears any exsiting load balancer IP to network mapping and
+// sets the mapping to the given attachments.
+func (store *AttachmentStore) ResetAttachments(attachments map[string]string) error {
+	store.ClearAttachments()
+	for nid, nodeIP := range attachments {
+		ip, _, err := net.ParseCIDR(nodeIP)
+		if err != nil {
+			store.networkToNodeLBIP = make(map[string]net.IP)
+			return errors.Wrapf(err, "Failed to parse load balancer address %s", nodeIP)
+		}
+		store.networkToNodeLBIP[nid] = ip
+	}
+	return nil
+}
+
+// ClearAttachments clears all the mappings of network to load balancer IP Address.
+func (store *AttachmentStore) ClearAttachments() {
+	store.networkToNodeLBIP = make(map[string]net.IP)
+}
+
+// GetIPForNetwork return the load balancer IP address for the given network.
+func (store *AttachmentStore) GetIPForNetwork(networkID string) (net.IP, bool) {
+	ip, exists := store.networkToNodeLBIP[networkID]
+	return ip, exists
+}
diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go
index 6d74301..0f8a392 100644
--- a/daemon/oci_linux.go
+++ b/daemon/oci_linux.go
@@ -11,7 +11,6 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/caps"
@@ -20,15 +19,16 @@
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/stringutils"
-	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/volume"
 	"github.com/opencontainers/runc/libcontainer/apparmor"
 	"github.com/opencontainers/runc/libcontainer/cgroups"
 	"github.com/opencontainers/runc/libcontainer/devices"
 	"github.com/opencontainers/runc/libcontainer/user"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 )
 
+// nolint: gosimple
 var (
 	deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$")
 )
@@ -73,7 +73,6 @@
 			ThrottleReadIOPSDevice:  readIOpsDevice,
 			ThrottleWriteIOPSDevice: writeIOpsDevice,
 		},
-		DisableOOMKiller: r.OomKillDisable,
 		Pids: &specs.LinuxPids{
 			Limit: r.PidsLimit,
 		},
@@ -157,14 +156,14 @@
 }
 
 func setRlimits(daemon *Daemon, s *specs.Spec, c *container.Container) error {
-	var rlimits []specs.LinuxRlimit
+	var rlimits []specs.POSIXRlimit
 
 	// We want to leave the original HostConfig alone so make a copy here
 	hostConfig := *c.HostConfig
 	// Merge with the daemon defaults
 	daemon.mergeUlimits(&hostConfig)
 	for _, ul := range hostConfig.Ulimits {
-		rlimits = append(rlimits, specs.LinuxRlimit{
+		rlimits = append(rlimits, specs.POSIXRlimit{
 			Type: "RLIMIT_" + strings.ToUpper(ul.Name),
 			Soft: uint64(ul.Soft),
 			Hard: uint64(ul.Hard),
@@ -187,7 +186,7 @@
 }
 
 func readUserFile(c *container.Container, p string) (io.ReadCloser, error) {
-	fp, err := symlink.FollowSymlinkInScope(filepath.Join(c.BaseFS, p), c.BaseFS)
+	fp, err := c.GetResourcePath(p)
 	if err != nil {
 		return nil, err
 	}
@@ -301,10 +300,13 @@
 		}
 		setNamespace(s, ns)
 	}
+
 	// ipc
-	if c.HostConfig.IpcMode.IsContainer() {
+	ipcMode := c.HostConfig.IpcMode
+	switch {
+	case ipcMode.IsContainer():
 		ns := specs.LinuxNamespace{Type: "ipc"}
-		ic, err := daemon.getIpcContainer(c)
+		ic, err := daemon.getIpcContainer(ipcMode.Container())
 		if err != nil {
 			return err
 		}
@@ -316,12 +318,19 @@
 			nsUser.Path = fmt.Sprintf("/proc/%d/ns/user", ic.State.GetPID())
 			setNamespace(s, nsUser)
 		}
-	} else if c.HostConfig.IpcMode.IsHost() {
+	case ipcMode.IsHost():
 		oci.RemoveNamespace(s, specs.LinuxNamespaceType("ipc"))
-	} else {
+	case ipcMode.IsEmpty():
+		// A container was created by an older version of the daemon.
+		// The default behavior used to be what is now called "shareable".
+		fallthrough
+	case ipcMode.IsPrivate(), ipcMode.IsShareable(), ipcMode.IsNone():
 		ns := specs.LinuxNamespace{Type: "ipc"}
 		setNamespace(s, ns)
+	default:
+		return fmt.Errorf("Invalid IPC mode: %v", ipcMode)
 	}
+
 	// pid
 	if c.HostConfig.PidMode.IsContainer() {
 		ns := specs.LinuxNamespace{Type: "pid"}
@@ -428,7 +437,7 @@
 	}
 
 	if !sharedMount {
-		return fmt.Errorf("Path %s is mounted on %s but it is not a shared mount.", path, sourceMount)
+		return fmt.Errorf("path %s is mounted on %s but it is not a shared mount", path, sourceMount)
 	}
 	return nil
 }
@@ -455,7 +464,7 @@
 	}
 
 	if !sharedMount && !slaveMount {
-		return fmt.Errorf("Path %s is mounted on %s but it is not a shared or slave mount.", path, sourceMount)
+		return fmt.Errorf("path %s is mounted on %s but it is not a shared or slave mount", path, sourceMount)
 	}
 	return nil
 }
@@ -486,10 +495,17 @@
 		userMounts[m.Destination] = struct{}{}
 	}
 
+	// Filter out mounts from spec
+	noIpc := c.HostConfig.IpcMode.IsNone()
 	// Filter out mounts that are overridden by user supplied mounts
 	var defaultMounts []specs.Mount
 	_, mountDev := userMounts["/dev"]
 	for _, m := range s.Mounts {
+		// filter out /dev/shm mount if case IpcMode is none
+		if noIpc && m.Destination == "/dev/shm" {
+			continue
+		}
+		// filter out mount overridden by a user supplied mount
 		if _, ok := userMounts[m.Destination]; !ok {
 			if mountDev && strings.HasPrefix(m.Destination, "/dev/") {
 				continue
@@ -502,13 +518,14 @@
 	for _, m := range mounts {
 		for _, cm := range s.Mounts {
 			if cm.Destination == m.Destination {
-				return fmt.Errorf("Duplicate mount point '%s'", m.Destination)
+				return duplicateMountPointError(m.Destination)
 			}
 		}
 
 		if m.Source == "tmpfs" {
 			data := m.Data
-			options := []string{"noexec", "nosuid", "nodev", string(volume.DefaultPropagationMode)}
+			parser := volume.NewParser("linux")
+			options := []string{"noexec", "nosuid", "nodev", string(parser.DefaultPropagationMode())}
 			if data != "" {
 				options = append(options, strings.Split(data, ",")...)
 			}
@@ -589,6 +606,14 @@
 		s.Linux.MaskedPaths = nil
 	}
 
+	// Set size for /dev/shm mount that comes from spec (IpcMode: private only)
+	for i, m := range s.Mounts {
+		if m.Destination == "/dev/shm" {
+			sizeOpt := "size=" + strconv.FormatInt(c.HostConfig.ShmSize, 10)
+			s.Mounts[i].Options = append(s.Mounts[i].Options, sizeOpt)
+		}
+	}
+
 	// TODO: until a kernel/mount solution exists for handling remount in a user namespace,
 	// we must clear the readonly flag for the cgroups mount (@mrunalp concurs)
 	if uidMap := daemon.idMappings.UIDs(); uidMap != nil || c.HostConfig.Privileged {
@@ -607,8 +632,8 @@
 	if err != nil {
 		return err
 	}
-	s.Root = specs.Root{
-		Path:     c.BaseFS,
+	s.Root = &specs.Root{
+		Path:     c.BaseFS.Path(),
 		Readonly: c.HostConfig.ReadonlyRootfs,
 	}
 	if err := c.SetupWorkingDirectory(daemon.idMappings.RootPair()); err != nil {
@@ -684,7 +709,6 @@
 	if err := setResources(&s, c.HostConfig.Resources); err != nil {
 		return nil, fmt.Errorf("linux runtime spec resources: %v", err)
 	}
-	s.Linux.Resources.OOMScoreAdj = &c.HostConfig.OomScoreAdj
 	s.Linux.Sysctl = c.HostConfig.Sysctls
 
 	p := s.Linux.CgroupsPath
@@ -745,7 +769,9 @@
 		return nil, err
 	}
 
-	ms = append(ms, c.IpcMounts()...)
+	if !c.HostConfig.IpcMode.IsPrivate() && !c.HostConfig.IpcMode.IsEmpty() {
+		ms = append(ms, c.IpcMounts()...)
+	}
 
 	tmpfsMounts, err := c.TmpfsMounts()
 	if err != nil {
@@ -806,9 +832,10 @@
 	}
 	s.Process.SelinuxLabel = c.GetProcessLabel()
 	s.Process.NoNewPrivileges = c.NoNewPrivileges
+	s.Process.OOMScoreAdj = &c.HostConfig.OomScoreAdj
 	s.Linux.MountLabel = c.MountLabel
 
-	return (*specs.Spec)(&s), nil
+	return &s, nil
 }
 
 func clearReadOnly(m *specs.Mount) {
diff --git a/daemon/oci_solaris.go b/daemon/oci_solaris.go
index 610efe1..45fa1e0 100644
--- a/daemon/oci_solaris.go
+++ b/daemon/oci_solaris.go
@@ -2,7 +2,6 @@
 
 import (
 	"fmt"
-	"path/filepath"
 	"sort"
 	"strconv"
 
@@ -127,7 +126,7 @@
 		return err
 	}
 	s.Root = specs.Root{
-		Path:     filepath.Dir(c.BaseFS),
+		Path:     c.BaseFS.Dir(c.BaseFS.Path()),
 		Readonly: c.HostConfig.ReadonlyRootfs,
 	}
 	if err := c.SetupWorkingDirectory(daemon.idMappings.RootPair()); err != nil {
diff --git a/daemon/oci_windows.go b/daemon/oci_windows.go
index 555a466..17b1040 100644
--- a/daemon/oci_windows.go
+++ b/daemon/oci_windows.go
@@ -1,13 +1,26 @@
 package daemon
 
 import (
+	"fmt"
+	"io/ioutil"
+	"path/filepath"
+	"runtime"
+	"strings"
+
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/layer"
 	"github.com/docker/docker/oci"
 	"github.com/docker/docker/pkg/sysinfo"
 	"github.com/docker/docker/pkg/system"
 	"github.com/opencontainers/runtime-spec/specs-go"
 	"golang.org/x/sys/windows"
+	"golang.org/x/sys/windows/registry"
+)
+
+const (
+	credentialSpecRegistryLocation = `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs`
+	credentialSpecFileLocation     = "CredentialSpecs"
 )
 
 func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
@@ -53,6 +66,10 @@
 		isHyperV = c.HostConfig.Isolation.IsHyperV()
 	}
 
+	if isHyperV {
+		s.Windows.HyperV = &specs.WindowsHyperV{}
+	}
+
 	// If the container has not been started, and has configs or secrets
 	// secrets, create symlinks to each config and secret. If it has been
 	// started before, the symlinks should have already been created. Also, it
@@ -92,6 +109,11 @@
 		if !mount.Writable {
 			m.Options = append(m.Options, "ro")
 		}
+		if img.OS != runtime.GOOS {
+			m.Type = "bind"
+			m.Options = append(m.Options, "rbind")
+			m.Options = append(m.Options, fmt.Sprintf("uvmpath=/tmp/gcs/%s/binds", c.ID))
+		}
 		s.Mounts = append(s.Mounts, m)
 	}
 
@@ -105,13 +127,93 @@
 	s.Process.Env = c.CreateDaemonEnvironment(c.Config.Tty, linkedEnv)
 	if c.Config.Tty {
 		s.Process.Terminal = c.Config.Tty
-		s.Process.ConsoleSize.Height = c.HostConfig.ConsoleSize[0]
-		s.Process.ConsoleSize.Width = c.HostConfig.ConsoleSize[1]
+		s.Process.ConsoleSize = &specs.Box{
+			Height: c.HostConfig.ConsoleSize[0],
+			Width:  c.HostConfig.ConsoleSize[1],
+		}
 	}
 	s.Process.User.Username = c.Config.User
 
+	// Get the layer path for each layer.
+	max := len(img.RootFS.DiffIDs)
+	for i := 1; i <= max; i++ {
+		img.RootFS.DiffIDs = img.RootFS.DiffIDs[:i]
+		layerPath, err := layer.GetLayerPath(daemon.stores[c.Platform].layerStore, img.RootFS.ChainID())
+		if err != nil {
+			return nil, fmt.Errorf("failed to get layer path from graphdriver %s for ImageID %s - %s", daemon.stores[c.Platform].layerStore, img.RootFS.ChainID(), err)
+		}
+		// Reverse order, expecting parent most first
+		s.Windows.LayerFolders = append([]string{layerPath}, s.Windows.LayerFolders...)
+	}
+	m, err := c.RWLayer.Metadata()
+	if err != nil {
+		return nil, fmt.Errorf("failed to get layer metadata - %s", err)
+	}
+	s.Windows.LayerFolders = append(s.Windows.LayerFolders, m["dir"])
+
+	dnsSearch := daemon.getDNSSearchSettings(c)
+
+	// Get endpoints for the libnetwork allocated networks to the container
+	var epList []string
+	AllowUnqualifiedDNSQuery := false
+	gwHNSID := ""
+	if c.NetworkSettings != nil {
+		for n := range c.NetworkSettings.Networks {
+			sn, err := daemon.FindNetwork(n)
+			if err != nil {
+				continue
+			}
+
+			ep, err := c.GetEndpointInNetwork(sn)
+			if err != nil {
+				continue
+			}
+
+			data, err := ep.DriverInfo()
+			if err != nil {
+				continue
+			}
+
+			if data["GW_INFO"] != nil {
+				gwInfo := data["GW_INFO"].(map[string]interface{})
+				if gwInfo["hnsid"] != nil {
+					gwHNSID = gwInfo["hnsid"].(string)
+				}
+			}
+
+			if data["hnsid"] != nil {
+				epList = append(epList, data["hnsid"].(string))
+			}
+
+			if data["AllowUnqualifiedDNSQuery"] != nil {
+				AllowUnqualifiedDNSQuery = true
+			}
+		}
+	}
+
+	var networkSharedContainerID string
+	if c.HostConfig.NetworkMode.IsContainer() {
+		networkSharedContainerID = c.NetworkSharedContainerID
+		for _, ep := range c.SharedEndpointList {
+			epList = append(epList, ep)
+		}
+	}
+
+	if gwHNSID != "" {
+		epList = append(epList, gwHNSID)
+	}
+
+	s.Windows.Network = &specs.WindowsNetwork{
+		AllowUnqualifiedDNSQuery:   AllowUnqualifiedDNSQuery,
+		DNSSearchList:              dnsSearch,
+		EndpointList:               epList,
+		NetworkSharedContainerName: networkSharedContainerID,
+	}
+
 	if img.OS == "windows" {
-		daemon.createSpecWindowsFields(c, &s, isHyperV)
+		if err := daemon.createSpecWindowsFields(c, &s, isHyperV); err != nil {
+			return nil, err
+		}
 	} else {
 		// TODO @jhowardmsft LCOW Support. Modify this check when running in dual-mode
 		if system.LCOWSupported() && img.OS == "linux" {
@@ -123,7 +225,7 @@
 }
 
 // Sets the Windows-specific fields of the OCI spec
-func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.Spec, isHyperV bool) {
+func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.Spec, isHyperV bool) error {
 	if len(s.Process.Cwd) == 0 {
 		// We default to C:\ to workaround the oddity of the case that the
 		// default directory for cmd running as LocalSystem (or
@@ -137,9 +239,15 @@
 
 	s.Root.Readonly = false // Windows does not support a read-only root filesystem
 	if !isHyperV {
-		s.Root.Path = c.BaseFS // This is not set for Hyper-V containers
+		s.Root.Path = c.BaseFS.Path() // This is not set for Hyper-V containers
+		if !strings.HasSuffix(s.Root.Path, `\`) {
+			s.Root.Path = s.Root.Path + `\` // Ensure a correctly formatted volume GUID path \\?\Volume{GUID}\
+		}
 	}
 
+	// First boot optimization
+	s.Windows.IgnoreFlushesDuringBoot = !c.HasBeenStartedBefore
+
 	// In s.Windows.Resources
 	cpuShares := uint16(c.HostConfig.CPUShares)
 	cpuMaximum := uint16(c.HostConfig.CPUPercent) * 100
@@ -179,6 +287,54 @@
 			Iops: &c.HostConfig.IOMaximumIOps,
 		},
 	}
+
+	// Read and add credentials from the security options if a credential spec has been provided.
+	if c.HostConfig.SecurityOpt != nil {
+		cs := ""
+		for _, sOpt := range c.HostConfig.SecurityOpt {
+			sOpt = strings.ToLower(sOpt)
+			if !strings.Contains(sOpt, "=") {
+				return fmt.Errorf("invalid security option: no equals sign in supplied value %s", sOpt)
+			}
+			var splitsOpt []string
+			splitsOpt = strings.SplitN(sOpt, "=", 2)
+			if len(splitsOpt) != 2 {
+				return fmt.Errorf("invalid security option: %s", sOpt)
+			}
+			if splitsOpt[0] != "credentialspec" {
+				return fmt.Errorf("security option not supported: %s", splitsOpt[0])
+			}
+
+			var (
+				match   bool
+				csValue string
+				err     error
+			)
+			if match, csValue = getCredentialSpec("file://", splitsOpt[1]); match {
+				if csValue == "" {
+					return fmt.Errorf("no value supplied for file:// credential spec security option")
+				}
+				if cs, err = readCredentialSpecFile(c.ID, daemon.root, filepath.Clean(csValue)); err != nil {
+					return err
+				}
+			} else if match, csValue = getCredentialSpec("registry://", splitsOpt[1]); match {
+				if csValue == "" {
+					return fmt.Errorf("no value supplied for registry:// credential spec security option")
+				}
+				if cs, err = readCredentialSpecRegistry(c.ID, csValue); err != nil {
+					return err
+				}
+			} else {
+				return fmt.Errorf("invalid credential spec security option - value must be prefixed file:// or registry:// followed by a value")
+			}
+		}
+		s.Windows.CredentialSpec = cs
+	}
+
+	// Assume we are not starting a container for a servicing operation
+	s.Windows.Servicing = false
+
+	return nil
 }
 
 // Sets the Linux-specific fields of the OCI spec
@@ -205,3 +361,52 @@
 func (daemon *Daemon) mergeUlimits(c *containertypes.HostConfig) {
 	return
 }
+
+// getCredentialSpec is a helper function to get the value of a credential spec supplied
+// on the CLI, stripping the prefix
+func getCredentialSpec(prefix, value string) (bool, string) {
+	if strings.HasPrefix(value, prefix) {
+		return true, strings.TrimPrefix(value, prefix)
+	}
+	return false, ""
+}
+
+// readCredentialSpecRegistry is a helper function to read a credential spec from
+// the registry. If not found, we return an empty string and warn in the log.
+// This allows for staging on machines which do not have the necessary components.
+func readCredentialSpecRegistry(id, name string) (string, error) {
+	var (
+		k   registry.Key
+		err error
+		val string
+	)
+	if k, err = registry.OpenKey(registry.LOCAL_MACHINE, credentialSpecRegistryLocation, registry.QUERY_VALUE); err != nil {
+		return "", fmt.Errorf("failed handling spec %q for container %s - %s could not be opened", name, id, credentialSpecRegistryLocation)
+	}
+	if val, _, err = k.GetStringValue(name); err != nil {
+		if err == registry.ErrNotExist {
+			return "", fmt.Errorf("credential spec %q for container %s as it was not found", name, id)
+		}
+		return "", fmt.Errorf("error %v reading credential spec %q from registry for container %s", err, name, id)
+	}
+	return val, nil
+}
+
+// readCredentialSpecFile is a helper function to read a credential spec from
+// a file. If not found, we return an empty string and warn in the log.
+// This allows for staging on machines which do not have the necessary components.
+func readCredentialSpecFile(id, root, location string) (string, error) {
+	if filepath.IsAbs(location) {
+		return "", fmt.Errorf("invalid credential spec - file:// path cannot be absolute")
+	}
+	base := filepath.Join(root, credentialSpecFileLocation)
+	full := filepath.Join(base, location)
+	if !strings.HasPrefix(full, base) {
+		return "", fmt.Errorf("invalid credential spec - file:// path must be under %s", base)
+	}
+	bcontents, err := ioutil.ReadFile(full)
+	if err != nil {
+		return "", fmt.Errorf("credential spec '%s' for container %s as the file could not be read: %q", full, id, err)
+	}
+	return string(bcontents[:]), nil
+}
diff --git a/daemon/pause.go b/daemon/pause.go
index dbfafbc..3fecea5 100644
--- a/daemon/pause.go
+++ b/daemon/pause.go
@@ -28,7 +28,7 @@
 
 	// We cannot Pause the container which is not running
 	if !container.Running {
-		return errNotRunning{container.ID}
+		return errNotRunning(container.ID)
 	}
 
 	// We cannot Pause the container which is already paused
diff --git a/daemon/prune.go b/daemon/prune.go
index 9f8a545..837cb83 100644
--- a/daemon/prune.go
+++ b/daemon/prune.go
@@ -7,7 +7,6 @@
 	"sync/atomic"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
@@ -20,6 +19,7 @@
 	"github.com/docker/docker/volume"
 	"github.com/docker/libnetwork"
 	digest "github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -182,11 +182,11 @@
 	rep := &types.ImagesPruneReport{}
 
 	danglingOnly := true
-	if pruneFilters.Include("dangling") {
+	if pruneFilters.Contains("dangling") {
 		if pruneFilters.ExactMatch("dangling", "false") || pruneFilters.ExactMatch("dangling", "0") {
 			danglingOnly = false
 		} else if !pruneFilters.ExactMatch("dangling", "true") && !pruneFilters.ExactMatch("dangling", "1") {
-			return nil, fmt.Errorf("Invalid filter 'dangling=%s'", pruneFilters.Get("dangling"))
+			return nil, invalidFilter{"dangling", pruneFilters.Get("dangling")}
 		}
 	}
 
@@ -221,7 +221,7 @@
 			return nil, ctx.Err()
 		default:
 			dgst := digest.Digest(id)
-			if len(daemon.stores[platform].referenceStore.References(dgst)) == 0 && len(daemon.stores[platform].imageStore.Children(id)) != 0 {
+			if len(daemon.referenceStore.References(dgst)) == 0 && len(daemon.stores[platform].imageStore.Children(id)) != 0 {
 				continue
 			}
 			if !until.IsZero() && img.Created.After(until) {
@@ -252,7 +252,7 @@
 		}
 
 		deletedImages := []types.ImageDeleteResponseItem{}
-		refs := daemon.stores[platform].referenceStore.References(dgst)
+		refs := daemon.referenceStore.References(dgst)
 		if len(refs) > 0 {
 			shouldDelete := !danglingOnly
 			if !shouldDelete {
@@ -440,7 +440,7 @@
 
 func getUntilFromPruneFilters(pruneFilters filters.Args) (time.Time, error) {
 	until := time.Time{}
-	if !pruneFilters.Include("until") {
+	if !pruneFilters.Contains("until") {
 		return until, nil
 	}
 	untilFilters := pruneFilters.Get("until")
@@ -464,8 +464,8 @@
 		return false
 	}
 	// By default MatchKVList will return true if field (like 'label!') does not exist
-	// So we have to add additional Include("label!") check
-	if pruneFilters.Include("label!") {
+	// So we have to add additional Contains("label!") check
+	if pruneFilters.Contains("label!") {
 		if pruneFilters.MatchKVList("label!", labels) {
 			return false
 		}
diff --git a/daemon/reload.go b/daemon/reload.go
index 0200bcf..a6674ec 100644
--- a/daemon/reload.go
+++ b/daemon/reload.go
@@ -4,10 +4,10 @@
 	"encoding/json"
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/daemon/discovery"
 	"github.com/docker/docker/libcontainerd"
+	"github.com/sirupsen/logrus"
 )
 
 // Reload reads configuration changes and modifies the
@@ -37,7 +37,9 @@
 		}
 	}()
 
-	daemon.reloadPlatform(conf, attributes)
+	if err := daemon.reloadPlatform(conf, attributes); err != nil {
+		return err
+	}
 	daemon.reloadDebug(conf, attributes)
 	daemon.reloadMaxConcurrentDownloadsAndUploads(conf, attributes)
 	daemon.reloadShutdownTimeout(conf, attributes)
diff --git a/daemon/reload_test.go b/daemon/reload_test.go
index bf11b6b..3ff6b57 100644
--- a/daemon/reload_test.go
+++ b/daemon/reload_test.go
@@ -12,6 +12,7 @@
 	"github.com/docker/docker/pkg/discovery"
 	_ "github.com/docker/docker/pkg/discovery/memory"
 	"github.com/docker/docker/registry"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestDaemonReloadLabels(t *testing.T) {
@@ -46,8 +47,9 @@
 		configStore: &config.Config{},
 	}
 
+	var err error
 	// Initialize daemon with some registries.
-	daemon.RegistryService = registry.NewService(registry.ServiceOptions{
+	daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{
 		AllowNondistributableArtifacts: []string{
 			"127.0.0.0/8",
 			"10.10.1.11:5000",
@@ -56,6 +58,9 @@
 			"docker2.com", // This will be removed during reload.
 		},
 	})
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	registries := []string{
 		"127.0.0.0/8",
@@ -85,20 +90,17 @@
 	for _, value := range serviceConfig.AllowNondistributableArtifactsCIDRs {
 		actual = append(actual, value.String())
 	}
-	for _, value := range serviceConfig.AllowNondistributableArtifactsHostnames {
-		actual = append(actual, value)
-	}
+	actual = append(actual, serviceConfig.AllowNondistributableArtifactsHostnames...)
 
 	sort.Strings(registries)
 	sort.Strings(actual)
-	if !reflect.DeepEqual(registries, actual) {
-		t.Fatalf("expected %v, got %v\n", registries, actual)
-	}
+	assert.Equal(t, registries, actual)
 }
 
 func TestDaemonReloadMirrors(t *testing.T) {
 	daemon := &Daemon{}
-	daemon.RegistryService = registry.NewService(registry.ServiceOptions{
+	var err error
+	daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{
 		InsecureRegistries: []string{},
 		Mirrors: []string{
 			"https://mirror.test1.com",
@@ -106,6 +108,9 @@
 			"https://mirror.test3.com", // this will be removed when reloading
 		},
 	})
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	daemon.configStore = &config.Config{}
 
@@ -191,8 +196,9 @@
 
 func TestDaemonReloadInsecureRegistries(t *testing.T) {
 	daemon := &Daemon{}
+	var err error
 	// initialize daemon with existing insecure registries: "127.0.0.0/8", "10.10.1.11:5000", "10.10.1.22:5000"
-	daemon.RegistryService = registry.NewService(registry.ServiceOptions{
+	daemon.RegistryService, err = registry.NewService(registry.ServiceOptions{
 		InsecureRegistries: []string{
 			"127.0.0.0/8",
 			"10.10.1.11:5000",
@@ -201,6 +207,9 @@
 			"docker2.com", // this will be removed when reloading
 		},
 	})
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	daemon.configStore = &config.Config{}
 
diff --git a/daemon/rename.go b/daemon/rename.go
index 686fbd3..26ee9be 100644
--- a/daemon/rename.go
+++ b/daemon/rename.go
@@ -1,13 +1,12 @@
 package daemon
 
 import (
-	"errors"
-	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	dockercontainer "github.com/docker/docker/container"
 	"github.com/docker/libnetwork"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerRename changes the name of a container, using the oldName
@@ -20,7 +19,7 @@
 	)
 
 	if oldName == "" || newName == "" {
-		return errors.New("Neither old nor new names may be empty")
+		return validationError{errors.New("Neither old nor new names may be empty")}
 	}
 
 	if newName[0] != '/' {
@@ -39,19 +38,19 @@
 	oldIsAnonymousEndpoint := container.NetworkSettings.IsAnonymousEndpoint
 
 	if oldName == newName {
-		return errors.New("Renaming a container with the same name as its current name")
+		return validationError{errors.New("Renaming a container with the same name as its current name")}
 	}
 
 	links := map[string]*dockercontainer.Container{}
 	for k, v := range daemon.linkIndex.children(container) {
 		if !strings.HasPrefix(k, oldName) {
-			return fmt.Errorf("Linked container %s does not match parent %s", k, oldName)
+			return validationError{errors.Errorf("Linked container %s does not match parent %s", k, oldName)}
 		}
 		links[strings.TrimPrefix(k, oldName)] = v
 	}
 
 	if newName, err = daemon.reserveName(container.ID, newName); err != nil {
-		return fmt.Errorf("Error when allocating new name: %v", err)
+		return errors.Wrap(err, "Error when allocating new name")
 	}
 
 	for k, v := range links {
diff --git a/daemon/resize.go b/daemon/resize.go
index 7473538..0923d0f 100644
--- a/daemon/resize.go
+++ b/daemon/resize.go
@@ -15,7 +15,7 @@
 	}
 
 	if !container.IsRunning() {
-		return errNotRunning{container.ID}
+		return errNotRunning(container.ID)
 	}
 
 	if err = daemon.containerd.Resize(container.ID, libcontainerd.InitFriendlyName, width, height); err == nil {
diff --git a/daemon/restart.go b/daemon/restart.go
index 9f2ef56..e030cfa 100644
--- a/daemon/restart.go
+++ b/daemon/restart.go
@@ -3,8 +3,8 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerRestart stops and starts a container. It attempts to
diff --git a/daemon/search.go b/daemon/search.go
index 5d2ac5d..25744cb 100644
--- a/daemon/search.go
+++ b/daemon/search.go
@@ -1,7 +1,6 @@
 package daemon
 
 import (
-	"fmt"
 	"strconv"
 
 	"golang.org/x/net/context"
@@ -24,7 +23,7 @@
 	authConfig *types.AuthConfig,
 	headers map[string][]string) (*registrytypes.SearchResults, error) {
 
-	searchFilters, err := filters.FromParam(filtersArgs)
+	searchFilters, err := filters.FromJSON(filtersArgs)
 	if err != nil {
 		return nil, err
 	}
@@ -34,26 +33,26 @@
 
 	var isAutomated, isOfficial bool
 	var hasStarFilter = 0
-	if searchFilters.Include("is-automated") {
+	if searchFilters.Contains("is-automated") {
 		if searchFilters.UniqueExactMatch("is-automated", "true") {
 			isAutomated = true
 		} else if !searchFilters.UniqueExactMatch("is-automated", "false") {
-			return nil, fmt.Errorf("Invalid filter 'is-automated=%s'", searchFilters.Get("is-automated"))
+			return nil, invalidFilter{"is-automated", searchFilters.Get("is-automated")}
 		}
 	}
-	if searchFilters.Include("is-official") {
+	if searchFilters.Contains("is-official") {
 		if searchFilters.UniqueExactMatch("is-official", "true") {
 			isOfficial = true
 		} else if !searchFilters.UniqueExactMatch("is-official", "false") {
-			return nil, fmt.Errorf("Invalid filter 'is-official=%s'", searchFilters.Get("is-official"))
+			return nil, invalidFilter{"is-official", searchFilters.Get("is-official")}
 		}
 	}
-	if searchFilters.Include("stars") {
+	if searchFilters.Contains("stars") {
 		hasStars := searchFilters.Get("stars")
 		for _, hasStar := range hasStars {
 			iHasStar, err := strconv.Atoi(hasStar)
 			if err != nil {
-				return nil, fmt.Errorf("Invalid filter 'stars=%s'", hasStar)
+				return nil, invalidFilter{"stars", hasStar}
 			}
 			if iHasStar > hasStarFilter {
 				hasStarFilter = iHasStar
@@ -68,17 +67,17 @@
 
 	filteredResults := []registrytypes.SearchResult{}
 	for _, result := range unfilteredResult.Results {
-		if searchFilters.Include("is-automated") {
+		if searchFilters.Contains("is-automated") {
 			if isAutomated != result.IsAutomated {
 				continue
 			}
 		}
-		if searchFilters.Include("is-official") {
+		if searchFilters.Contains("is-official") {
 			if isOfficial != result.IsOfficial {
 				continue
 			}
 		}
-		if searchFilters.Include("stars") {
+		if searchFilters.Contains("stars") {
 			if result.StarCount < hasStarFilter {
 				continue
 			}
diff --git a/daemon/seccomp_linux.go b/daemon/seccomp_linux.go
index 472e313..3fce213 100644
--- a/daemon/seccomp_linux.go
+++ b/daemon/seccomp_linux.go
@@ -5,10 +5,10 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/profiles/seccomp"
 	"github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 )
 
 var supportsSeccomp = true
diff --git a/daemon/secrets.go b/daemon/secrets.go
index 90fa99e..214391f 100644
--- a/daemon/secrets.go
+++ b/daemon/secrets.go
@@ -1,8 +1,8 @@
 package daemon
 
 import (
-	"github.com/Sirupsen/logrus"
 	swarmtypes "github.com/docker/docker/api/types/swarm"
+	"github.com/sirupsen/logrus"
 )
 
 // SetContainerSecretReferences sets the container secret references needed
diff --git a/daemon/start.go b/daemon/start.go
index 8d93851..de32a64 100644
--- a/daemon/start.go
+++ b/daemon/start.go
@@ -1,26 +1,20 @@
 package daemon
 
 import (
-	"fmt"
-	"net/http"
 	"runtime"
-	"strings"
-	"syscall"
 	"time"
 
-	"google.golang.org/grpc"
-
-	"github.com/Sirupsen/logrus"
-	apierrors "github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerStart starts a container.
 func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error {
 	if checkpoint != "" && !daemon.HasExperimental() {
-		return apierrors.NewBadRequestError(fmt.Errorf("checkpoint is only supported in experimental mode"))
+		return validationError{errors.New("checkpoint is only supported in experimental mode")}
 	}
 
 	container, err := daemon.GetContainer(name)
@@ -28,13 +22,26 @@
 		return err
 	}
 
-	if container.IsPaused() {
-		return fmt.Errorf("Cannot start a paused container, try unpause instead.")
+	validateState := func() error {
+		container.Lock()
+		defer container.Unlock()
+
+		if container.Paused {
+			return stateConflictError{errors.New("cannot start a paused container, try unpause instead")}
+		}
+
+		if container.Running {
+			return containerNotModifiedError{running: true}
+		}
+
+		if container.RemovalInProgress || container.Dead {
+			return stateConflictError{errors.New("container is marked for removal and cannot be started")}
+		}
+		return nil
 	}
 
-	if container.IsRunning() {
-		err := fmt.Errorf("Container already started")
-		return apierrors.NewErrorWithStatusCode(err, http.StatusNotModified)
+	if err := validateState(); err != nil {
+		return err
 	}
 
 	// Windows does not have the backwards compatibility issue here.
@@ -45,13 +52,13 @@
 			logrus.Warn("DEPRECATED: Setting host configuration options when the container starts is deprecated and has been removed in Docker 1.12")
 			oldNetworkMode := container.HostConfig.NetworkMode
 			if err := daemon.setSecurityOptions(container, hostConfig); err != nil {
-				return err
+				return validationError{err}
 			}
 			if err := daemon.mergeAndVerifyLogConfig(&hostConfig.LogConfig); err != nil {
-				return err
+				return validationError{err}
 			}
 			if err := daemon.setHostConfig(container, hostConfig); err != nil {
-				return err
+				return validationError{err}
 			}
 			newNetworkMode := container.HostConfig.NetworkMode
 			if string(oldNetworkMode) != string(newNetworkMode) {
@@ -59,31 +66,34 @@
 				// old networks. It is a deprecated feature and has been removed in Docker 1.12
 				container.NetworkSettings.Networks = nil
 				if err := container.CheckpointTo(daemon.containersReplica); err != nil {
-					return err
+					return systemError{err}
 				}
 			}
 			container.InitDNSHostConfig()
 		}
 	} else {
 		if hostConfig != nil {
-			return fmt.Errorf("Supplying a hostconfig on start is not supported. It should be supplied on create")
+			return validationError{errors.New("Supplying a hostconfig on start is not supported. It should be supplied on create")}
 		}
 	}
 
 	// check if hostConfig is in line with the current system settings.
 	// It may happen cgroups are umounted or the like.
-	if _, err = daemon.verifyContainerSettings(container.HostConfig, nil, false); err != nil {
-		return err
+	if _, err = daemon.verifyContainerSettings(container.Platform, container.HostConfig, nil, false); err != nil {
+		return validationError{err}
 	}
 	// Adapt for old containers in case we have updates in this function and
 	// old containers never have chance to call the new function in create stage.
 	if hostConfig != nil {
 		if err := daemon.adaptContainerSettings(container.HostConfig, false); err != nil {
-			return err
+			return validationError{err}
 		}
 	}
 
-	return daemon.containerStart(container, checkpoint, checkpointDir, true)
+	if err := daemon.containerStart(container, checkpoint, checkpointDir, true); err != nil {
+		return err
+	}
+	return nil
 }
 
 // containerStart prepares the container to run by setting up everything the
@@ -100,7 +110,7 @@
 	}
 
 	if container.RemovalInProgress || container.Dead {
-		return fmt.Errorf("Container is marked for removal and cannot be started.")
+		return stateConflictError{errors.New("container is marked for removal and cannot be started")}
 	}
 
 	// if we encounter an error during start we need to ensure that any other
@@ -139,7 +149,7 @@
 
 	spec, err := daemon.createSpec(container)
 	if err != nil {
-		return err
+		return systemError{err}
 	}
 
 	createOptions, err := daemon.getLibcontainerdCreateOptions(container)
@@ -160,32 +170,8 @@
 	}
 
 	if err := daemon.containerd.Create(container.ID, checkpoint, checkpointDir, *spec, container.InitializeStdio, createOptions...); err != nil {
-		errDesc := grpc.ErrorDesc(err)
-		contains := func(s1, s2 string) bool {
-			return strings.Contains(strings.ToLower(s1), s2)
-		}
-		logrus.Errorf("Create container failed with error: %s", errDesc)
-		// if we receive an internal error from the initial start of a container then lets
-		// return it instead of entering the restart loop
-		// set to 127 for container cmd not found/does not exist)
-		if contains(errDesc, container.Path) &&
-			(contains(errDesc, "executable file not found") ||
-				contains(errDesc, "no such file or directory") ||
-				contains(errDesc, "system cannot find the file specified")) {
-			container.SetExitCode(127)
-		}
-		// set to 126 for container cmd can't be invoked errors
-		if contains(errDesc, syscall.EACCES.Error()) {
-			container.SetExitCode(126)
-		}
+		return translateContainerdStartErr(container.Path, container.SetExitCode, err)
 
-		// attempted to mount a file onto a directory, or a directory onto a file, maybe from user specified bind mounts
-		if contains(errDesc, syscall.ENOTDIR.Error()) {
-			errDesc += ": Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type"
-			container.SetExitCode(127)
-		}
-
-		return fmt.Errorf("%s", errDesc)
 	}
 
 	containerActions.WithValues("start").UpdateSince(start)
@@ -198,7 +184,9 @@
 func (daemon *Daemon) Cleanup(container *container.Container) {
 	daemon.releaseNetwork(container)
 
-	container.UnmountIpcMounts(detachMounted)
+	if err := container.UnmountIpcMount(detachMounted); err != nil {
+		logrus.Warnf("%s cleanup: failed to unmount IPC: %s", container.ID, err)
+	}
 
 	if err := daemon.conditionalUnmountOnCleanup(container); err != nil {
 		// FIXME: remove once reference counting for graphdrivers has been refactored
@@ -216,7 +204,7 @@
 		daemon.unregisterExecCommand(container, eConfig)
 	}
 
-	if container.BaseFS != "" {
+	if container.BaseFS != nil && container.BaseFS.Path() != "" {
 		if err := container.UnmountVolumes(daemon.LogVolumeEvent); err != nil {
 			logrus.Warnf("%s cleanup: Failed to umount volumes: %v", container.ID, err)
 		}
diff --git a/daemon/start_unix.go b/daemon/start_unix.go
index 12ecdab..87ab085 100644
--- a/daemon/start_unix.go
+++ b/daemon/start_unix.go
@@ -3,10 +3,9 @@
 package daemon
 
 import (
-	"fmt"
-
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/libcontainerd"
+	"github.com/pkg/errors"
 )
 
 // getLibcontainerdCreateOptions callers must hold a lock on the container
@@ -21,7 +20,7 @@
 
 	rt := daemon.configStore.GetRuntime(container.HostConfig.Runtime)
 	if rt == nil {
-		return nil, fmt.Errorf("no such runtime '%s'", container.HostConfig.Runtime)
+		return nil, validationError{errors.Errorf("no such runtime '%s'", container.HostConfig.Runtime)}
 	}
 	if UsingSystemd(daemon.configStore) {
 		rt.Args = append(rt.Args, "--systemd-cgroup=true")
diff --git a/daemon/start_windows.go b/daemon/start_windows.go
index 74129bd..9082a93 100644
--- a/daemon/start_windows.go
+++ b/daemon/start_windows.go
@@ -1,214 +1,43 @@
 package daemon
 
 import (
-	"fmt"
-	"io/ioutil"
-	"path/filepath"
-	"strings"
-
+	"github.com/Microsoft/opengcs/client"
 	"github.com/docker/docker/container"
-	"github.com/docker/docker/layer"
 	"github.com/docker/docker/libcontainerd"
-	"golang.org/x/sys/windows/registry"
-)
-
-const (
-	credentialSpecRegistryLocation = `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\Containers\CredentialSpecs`
-	credentialSpecFileLocation     = "CredentialSpecs"
 )
 
 func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Container) ([]libcontainerd.CreateOption, error) {
 	createOptions := []libcontainerd.CreateOption{}
 
-	// Are we going to run as a Hyper-V container?
-	hvOpts := &libcontainerd.HyperVIsolationOption{}
-	if container.HostConfig.Isolation.IsDefault() {
-		// Container is set to use the default, so take the default from the daemon configuration
-		hvOpts.IsHyperV = daemon.defaultIsolation.IsHyperV()
-	} else {
-		// Container is requesting an isolation mode. Honour it.
-		hvOpts.IsHyperV = container.HostConfig.Isolation.IsHyperV()
-	}
-
-	dnsSearch := daemon.getDNSSearchSettings(container)
-
-	// Generate the layer folder of the layer options
-	layerOpts := &libcontainerd.LayerOption{}
-	m, err := container.RWLayer.Metadata()
-	if err != nil {
-		return nil, fmt.Errorf("failed to get layer metadata - %s", err)
-	}
-	layerOpts.LayerFolderPath = m["dir"]
-
-	// Generate the layer paths of the layer options
-	img, err := daemon.stores[container.Platform].imageStore.Get(container.ImageID)
-	if err != nil {
-		return nil, fmt.Errorf("failed to graph.Get on ImageID %s - %s", container.ImageID, err)
-	}
-	// Get the layer path for each layer.
-	max := len(img.RootFS.DiffIDs)
-	for i := 1; i <= max; i++ {
-		img.RootFS.DiffIDs = img.RootFS.DiffIDs[:i]
-		layerPath, err := layer.GetLayerPath(daemon.stores[container.Platform].layerStore, img.RootFS.ChainID())
-		if err != nil {
-			return nil, fmt.Errorf("failed to get layer path from graphdriver %s for ImageID %s - %s", daemon.stores[container.Platform].layerStore, img.RootFS.ChainID(), err)
+	// LCOW options.
+	if container.Platform == "linux" {
+		config := &client.Config{}
+		if err := config.GenerateDefault(daemon.configStore.GraphOptions); err != nil {
+			return nil, err
 		}
-		// Reverse order, expecting parent most first
-		layerOpts.LayerPaths = append([]string{layerPath}, layerOpts.LayerPaths...)
-	}
-
-	// Get endpoints for the libnetwork allocated networks to the container
-	var epList []string
-	AllowUnqualifiedDNSQuery := false
-	gwHNSID := ""
-	if container.NetworkSettings != nil {
-		for n := range container.NetworkSettings.Networks {
-			sn, err := daemon.FindNetwork(n)
-			if err != nil {
-				continue
-			}
-
-			ep, err := container.GetEndpointInNetwork(sn)
-			if err != nil {
-				continue
-			}
-
-			data, err := ep.DriverInfo()
-			if err != nil {
-				continue
-			}
-
-			if data["GW_INFO"] != nil {
-				gwInfo := data["GW_INFO"].(map[string]interface{})
-				if gwInfo["hnsid"] != nil {
-					gwHNSID = gwInfo["hnsid"].(string)
-				}
-			}
-
-			if data["hnsid"] != nil {
-				epList = append(epList, data["hnsid"].(string))
-			}
-
-			if data["AllowUnqualifiedDNSQuery"] != nil {
-				AllowUnqualifiedDNSQuery = true
+		// Override from user-supplied options.
+		for k, v := range container.HostConfig.StorageOpt {
+			switch k {
+			case "lcow.kirdpath":
+				config.KirdPath = v
+			case "lcow.kernel":
+				config.KernelFile = v
+			case "lcow.initrd":
+				config.InitrdFile = v
+			case "lcow.vhdx":
+				config.Vhdx = v
+			case "lcow.bootparameters":
+				config.BootParameters = v
 			}
 		}
-	}
-
-	if gwHNSID != "" {
-		epList = append(epList, gwHNSID)
-	}
-
-	// Read and add credentials from the security options if a credential spec has been provided.
-	if container.HostConfig.SecurityOpt != nil {
-		for _, sOpt := range container.HostConfig.SecurityOpt {
-			sOpt = strings.ToLower(sOpt)
-			if !strings.Contains(sOpt, "=") {
-				return nil, fmt.Errorf("invalid security option: no equals sign in supplied value %s", sOpt)
-			}
-			var splitsOpt []string
-			splitsOpt = strings.SplitN(sOpt, "=", 2)
-			if len(splitsOpt) != 2 {
-				return nil, fmt.Errorf("invalid security option: %s", sOpt)
-			}
-			if splitsOpt[0] != "credentialspec" {
-				return nil, fmt.Errorf("security option not supported: %s", splitsOpt[0])
-			}
-
-			credentialsOpts := &libcontainerd.CredentialsOption{}
-			var (
-				match   bool
-				csValue string
-				err     error
-			)
-			if match, csValue = getCredentialSpec("file://", splitsOpt[1]); match {
-				if csValue == "" {
-					return nil, fmt.Errorf("no value supplied for file:// credential spec security option")
-				}
-				if credentialsOpts.Credentials, err = readCredentialSpecFile(container.ID, daemon.root, filepath.Clean(csValue)); err != nil {
-					return nil, err
-				}
-			} else if match, csValue = getCredentialSpec("registry://", splitsOpt[1]); match {
-				if csValue == "" {
-					return nil, fmt.Errorf("no value supplied for registry:// credential spec security option")
-				}
-				if credentialsOpts.Credentials, err = readCredentialSpecRegistry(container.ID, csValue); err != nil {
-					return nil, err
-				}
-			} else {
-				return nil, fmt.Errorf("invalid credential spec security option - value must be prefixed file:// or registry:// followed by a value")
-			}
-			createOptions = append(createOptions, credentialsOpts)
+		if err := config.Validate(); err != nil {
+			return nil, err
 		}
-	}
-
-	// Now add the remaining options.
-	createOptions = append(createOptions, &libcontainerd.FlushOption{IgnoreFlushesDuringBoot: !container.HasBeenStartedBefore})
-	createOptions = append(createOptions, hvOpts)
-	createOptions = append(createOptions, layerOpts)
-
-	var networkSharedContainerID string
-	if container.HostConfig.NetworkMode.IsContainer() {
-		networkSharedContainerID = container.NetworkSharedContainerID
-		for _, ep := range container.SharedEndpointList {
-			epList = append(epList, ep)
+		lcowOpts := &libcontainerd.LCOWOption{
+			Config: config,
 		}
+		createOptions = append(createOptions, lcowOpts)
 	}
 
-	createOptions = append(createOptions, &libcontainerd.NetworkEndpointsOption{
-		Endpoints:                epList,
-		AllowUnqualifiedDNSQuery: AllowUnqualifiedDNSQuery,
-		DNSSearchList:            dnsSearch,
-		NetworkSharedContainerID: networkSharedContainerID,
-	})
 	return createOptions, nil
 }
-
-// getCredentialSpec is a helper function to get the value of a credential spec supplied
-// on the CLI, stripping the prefix
-func getCredentialSpec(prefix, value string) (bool, string) {
-	if strings.HasPrefix(value, prefix) {
-		return true, strings.TrimPrefix(value, prefix)
-	}
-	return false, ""
-}
-
-// readCredentialSpecRegistry is a helper function to read a credential spec from
-// the registry. If not found, we return an empty string and warn in the log.
-// This allows for staging on machines which do not have the necessary components.
-func readCredentialSpecRegistry(id, name string) (string, error) {
-	var (
-		k   registry.Key
-		err error
-		val string
-	)
-	if k, err = registry.OpenKey(registry.LOCAL_MACHINE, credentialSpecRegistryLocation, registry.QUERY_VALUE); err != nil {
-		return "", fmt.Errorf("failed handling spec %q for container %s - %s could not be opened", name, id, credentialSpecRegistryLocation)
-	}
-	if val, _, err = k.GetStringValue(name); err != nil {
-		if err == registry.ErrNotExist {
-			return "", fmt.Errorf("credential spec %q for container %s as it was not found", name, id)
-		}
-		return "", fmt.Errorf("error %v reading credential spec %q from registry for container %s", err, name, id)
-	}
-	return val, nil
-}
-
-// readCredentialSpecFile is a helper function to read a credential spec from
-// a file. If not found, we return an empty string and warn in the log.
-// This allows for staging on machines which do not have the necessary components.
-func readCredentialSpecFile(id, root, location string) (string, error) {
-	if filepath.IsAbs(location) {
-		return "", fmt.Errorf("invalid credential spec - file:// path cannot be absolute")
-	}
-	base := filepath.Join(root, credentialSpecFileLocation)
-	full := filepath.Join(base, location)
-	if !strings.HasPrefix(full, base) {
-		return "", fmt.Errorf("invalid credential spec - file:// path must be under %s", base)
-	}
-	bcontents, err := ioutil.ReadFile(full)
-	if err != nil {
-		return "", fmt.Errorf("credential spec '%s' for container %s as the file could not be read: %q", full, id, err)
-	}
-	return string(bcontents[:]), nil
-}
diff --git a/daemon/stats/collector.go b/daemon/stats/collector.go
index 0520efa..c930bc7 100644
--- a/daemon/stats/collector.go
+++ b/daemon/stats/collector.go
@@ -5,10 +5,10 @@
 import (
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/pkg/pubsub"
+	"github.com/sirupsen/logrus"
 )
 
 // Collect registers the container with the collector and adds it to
@@ -113,10 +113,10 @@
 
 type notRunningErr interface {
 	error
-	ContainerIsRunning() bool
+	Conflict()
 }
 
 type notFoundErr interface {
 	error
-	ContainerNotFound() bool
+	NotFound()
 }
diff --git a/daemon/stats_unix.go b/daemon/stats_unix.go
index d875607..4831b84 100644
--- a/daemon/stats_unix.go
+++ b/daemon/stats_unix.go
@@ -3,10 +3,9 @@
 package daemon
 
 import (
-	"fmt"
-
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/container"
+	"github.com/pkg/errors"
 )
 
 // Resolve Network SandboxID in case the container reuse another container's network stack
@@ -16,7 +15,7 @@
 		containerID := curr.HostConfig.NetworkMode.ConnectedContainer()
 		connected, err := daemon.GetContainer(containerID)
 		if err != nil {
-			return "", fmt.Errorf("Could not get container for %s", containerID)
+			return "", errors.Wrapf(err, "Could not get container for %s", containerID)
 		}
 		curr = connected
 	}
diff --git a/daemon/stop.go b/daemon/stop.go
index 6a4776d..7eadba7 100644
--- a/daemon/stop.go
+++ b/daemon/stop.go
@@ -2,13 +2,11 @@
 
 import (
 	"context"
-	"fmt"
-	"net/http"
 	"time"
 
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api/errors"
 	containerpkg "github.com/docker/docker/container"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerStop looks for the given container and terminates it,
@@ -23,15 +21,14 @@
 		return err
 	}
 	if !container.IsRunning() {
-		err := fmt.Errorf("Container %s is already stopped", name)
-		return errors.NewErrorWithStatusCode(err, http.StatusNotModified)
+		return containerNotModifiedError{running: false}
 	}
 	if seconds == nil {
 		stopTimeout := container.StopTimeout()
 		seconds = &stopTimeout
 	}
 	if err := daemon.containerStop(container, *seconds); err != nil {
-		return fmt.Errorf("Cannot stop container %s: %v", name, err)
+		return errors.Wrapf(systemError{err}, "cannot stop container: %s", name)
 	}
 	return nil
 }
@@ -81,7 +78,7 @@
 		// 3. If it doesn't, then send SIGKILL
 		if err := daemon.Kill(container); err != nil {
 			// Wait without a timeout, ignore result.
-			_ = <-container.Wait(context.Background(), containerpkg.WaitConditionNotRunning)
+			<-container.Wait(context.Background(), containerpkg.WaitConditionNotRunning)
 			logrus.Warn(err) // Don't return error because we only care that container is stopped, not what function stopped it
 		}
 	}
diff --git a/api/fixtures/keyfile b/daemon/testdata/keyfile
similarity index 100%
rename from api/fixtures/keyfile
rename to daemon/testdata/keyfile
diff --git a/daemon/top_unix.go b/daemon/top_unix.go
index 4d94d4a..22e88b7 100644
--- a/daemon/top_unix.go
+++ b/daemon/top_unix.go
@@ -16,6 +16,7 @@
 	// NOTE: \\s does not detect unicode whitespaces.
 	// So we use fieldsASCII instead of strings.Fields in parsePSOutput.
 	// See https://github.com/docker/docker/pull/24358
+	// nolint: gosimple
 	re := regexp.MustCompile("\\s+([^\\s]*)=\\s*(PID[^\\s]*)")
 	for _, group := range re.FindAllStringSubmatch(psArgs, -1) {
 		if len(group) >= 3 {
@@ -130,7 +131,7 @@
 	}
 
 	if !container.IsRunning() {
-		return nil, errNotRunning{container.ID}
+		return nil, errNotRunning(container.ID)
 	}
 
 	if container.IsRestarting() {
diff --git a/daemon/trustkey.go b/daemon/trustkey.go
new file mode 100644
index 0000000..cb33146
--- /dev/null
+++ b/daemon/trustkey.go
@@ -0,0 +1,57 @@
+package daemon
+
+import (
+	"encoding/json"
+	"encoding/pem"
+	"fmt"
+	"os"
+	"path/filepath"
+
+	"github.com/docker/docker/pkg/ioutils"
+	"github.com/docker/docker/pkg/system"
+	"github.com/docker/libtrust"
+)
+
+// LoadOrCreateTrustKey attempts to load the libtrust key at the given path,
+// otherwise generates a new one
+// TODO: this should use more of libtrust.LoadOrCreateTrustKey which may need
+// a refactor or this function to be moved into libtrust
+func loadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
+	err := system.MkdirAll(filepath.Dir(trustKeyPath), 0700, "")
+	if err != nil {
+		return nil, err
+	}
+	trustKey, err := libtrust.LoadKeyFile(trustKeyPath)
+	if err == libtrust.ErrKeyFileDoesNotExist {
+		trustKey, err = libtrust.GenerateECP256PrivateKey()
+		if err != nil {
+			return nil, fmt.Errorf("Error generating key: %s", err)
+		}
+		encodedKey, err := serializePrivateKey(trustKey, filepath.Ext(trustKeyPath))
+		if err != nil {
+			return nil, fmt.Errorf("Error serializing key: %s", err)
+		}
+		if err := ioutils.AtomicWriteFile(trustKeyPath, encodedKey, os.FileMode(0600)); err != nil {
+			return nil, fmt.Errorf("Error saving key file: %s", err)
+		}
+	} else if err != nil {
+		return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
+	}
+	return trustKey, nil
+}
+
+func serializePrivateKey(key libtrust.PrivateKey, ext string) (encoded []byte, err error) {
+	if ext == ".json" || ext == ".jwk" {
+		encoded, err = json.Marshal(key)
+		if err != nil {
+			return nil, fmt.Errorf("unable to encode private key JWK: %s", err)
+		}
+	} else {
+		pemBlock, err := key.PEMBlock()
+		if err != nil {
+			return nil, fmt.Errorf("unable to encode private key PEM: %s", err)
+		}
+		encoded = pem.EncodeToMemory(pemBlock)
+	}
+	return
+}
diff --git a/daemon/trustkey_test.go b/daemon/trustkey_test.go
new file mode 100644
index 0000000..2ade2aa
--- /dev/null
+++ b/daemon/trustkey_test.go
@@ -0,0 +1,72 @@
+package daemon
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+
+	"github.com/docker/docker/internal/testutil"
+	"github.com/gotestyourself/gotestyourself/fs"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+// LoadOrCreateTrustKey
+func TestLoadOrCreateTrustKeyInvalidKeyFile(t *testing.T) {
+	tmpKeyFolderPath, err := ioutil.TempDir("", "api-trustkey-test")
+	require.NoError(t, err)
+	defer os.RemoveAll(tmpKeyFolderPath)
+
+	tmpKeyFile, err := ioutil.TempFile(tmpKeyFolderPath, "keyfile")
+	require.NoError(t, err)
+
+	_, err = loadOrCreateTrustKey(tmpKeyFile.Name())
+	testutil.ErrorContains(t, err, "Error loading key file")
+}
+
+func TestLoadOrCreateTrustKeyCreateKeyWhenFileDoesNotExist(t *testing.T) {
+	tmpKeyFolderPath := fs.NewDir(t, "api-trustkey-test")
+	defer tmpKeyFolderPath.Remove()
+
+	// Without the need to create the folder hierarchy
+	tmpKeyFile := tmpKeyFolderPath.Join("keyfile")
+
+	key, err := loadOrCreateTrustKey(tmpKeyFile)
+	require.NoError(t, err)
+	assert.NotNil(t, key)
+
+	_, err = os.Stat(tmpKeyFile)
+	require.NoError(t, err, "key file doesn't exist")
+}
+
+func TestLoadOrCreateTrustKeyCreateKeyWhenDirectoryDoesNotExist(t *testing.T) {
+	tmpKeyFolderPath := fs.NewDir(t, "api-trustkey-test")
+	defer tmpKeyFolderPath.Remove()
+	tmpKeyFile := tmpKeyFolderPath.Join("folder/hierarchy/keyfile")
+
+	key, err := loadOrCreateTrustKey(tmpKeyFile)
+	require.NoError(t, err)
+	assert.NotNil(t, key)
+
+	_, err = os.Stat(tmpKeyFile)
+	require.NoError(t, err, "key file doesn't exist")
+}
+
+func TestLoadOrCreateTrustKeyCreateKeyNoPath(t *testing.T) {
+	defer os.Remove("keyfile")
+	key, err := loadOrCreateTrustKey("keyfile")
+	require.NoError(t, err)
+	assert.NotNil(t, key)
+
+	_, err = os.Stat("keyfile")
+	require.NoError(t, err, "key file doesn't exist")
+}
+
+func TestLoadOrCreateTrustKeyLoadValidKey(t *testing.T) {
+	tmpKeyFile := filepath.Join("testdata", "keyfile")
+	key, err := loadOrCreateTrustKey(tmpKeyFile)
+	require.NoError(t, err)
+	expected := "AWX2:I27X:WQFX:IOMK:CNAK:O7PW:VYNB:ZLKC:CVAE:YJP2:SI4A:XXAY"
+	assert.Contains(t, key.String(), expected)
+}
diff --git a/daemon/update.go b/daemon/update.go
index a65cbd5..42d732f 100644
--- a/daemon/update.go
+++ b/daemon/update.go
@@ -4,17 +4,23 @@
 	"fmt"
 
 	"github.com/docker/docker/api/types/container"
+	"github.com/pkg/errors"
 )
 
 // ContainerUpdate updates configuration of the container
 func (daemon *Daemon) ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error) {
 	var warnings []string
 
-	warnings, err := daemon.verifyContainerSettings(hostConfig, nil, true)
+	c, err := daemon.GetContainer(name)
 	if err != nil {
 		return container.ContainerUpdateOKBody{Warnings: warnings}, err
 	}
 
+	warnings, err = daemon.verifyContainerSettings(c.Platform, hostConfig, nil, true)
+	if err != nil {
+		return container.ContainerUpdateOKBody{Warnings: warnings}, validationError{err}
+	}
+
 	if err := daemon.update(name, hostConfig); err != nil {
 		return container.ContainerUpdateOKBody{Warnings: warnings}, err
 	}
@@ -44,7 +50,7 @@
 	}()
 
 	if container.RemovalInProgress || container.Dead {
-		return errCannotUpdate(container.ID, fmt.Errorf("Container is marked for removal and cannot be \"update\"."))
+		return errCannotUpdate(container.ID, fmt.Errorf("container is marked for removal and cannot be \"update\""))
 	}
 
 	container.Lock()
@@ -72,7 +78,8 @@
 	if container.IsRunning() && !container.IsRestarting() {
 		if err := daemon.containerd.UpdateResources(container.ID, toContainerdResources(hostConfig.Resources)); err != nil {
 			restoreConfig = true
-			return errCannotUpdate(container.ID, err)
+			// TODO: it would be nice if containerd responded with better errors here so we can classify this better.
+			return errCannotUpdate(container.ID, systemError{err})
 		}
 	}
 
@@ -82,5 +89,5 @@
 }
 
 func errCannotUpdate(containerID string, err error) error {
-	return fmt.Errorf("Cannot update container %s: %v", containerID, err)
+	return errors.Wrap(err, "Cannot update container "+containerID)
 }
diff --git a/daemon/volumes.go b/daemon/volumes.go
index 6f24f05..d5d31b2 100644
--- a/daemon/volumes.go
+++ b/daemon/volumes.go
@@ -1,7 +1,6 @@
 package daemon
 
 import (
-	"errors"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -9,14 +8,14 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
-	dockererrors "github.com/docker/docker/api/errors"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	mounttypes "github.com/docker/docker/api/types/mount"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/volume"
 	"github.com/docker/docker/volume/drivers"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -76,6 +75,7 @@
 func (daemon *Daemon) registerMountPoints(container *container.Container, hostConfig *containertypes.HostConfig) (retErr error) {
 	binds := map[string]bool{}
 	mountPoints := map[string]*volume.MountPoint{}
+	parser := volume.NewParser(container.Platform)
 	defer func() {
 		// clean up the container mountpoints once return with error
 		if retErr != nil {
@@ -104,7 +104,7 @@
 
 	// 2. Read volumes from other containers.
 	for _, v := range hostConfig.VolumesFrom {
-		containerID, mode, err := volume.ParseVolumesFrom(v)
+		containerID, mode, err := parser.ParseVolumesFrom(v)
 		if err != nil {
 			return err
 		}
@@ -119,7 +119,7 @@
 				Type:        m.Type,
 				Name:        m.Name,
 				Source:      m.Source,
-				RW:          m.RW && volume.ReadWrite(mode),
+				RW:          m.RW && parser.ReadWrite(mode),
 				Driver:      m.Driver,
 				Destination: m.Destination,
 				Propagation: m.Propagation,
@@ -141,7 +141,7 @@
 
 	// 3. Read bind mounts
 	for _, b := range hostConfig.Binds {
-		bind, err := volume.ParseMountRaw(b, hostConfig.VolumeDriver)
+		bind, err := parser.ParseMountRaw(b, hostConfig.VolumeDriver)
 		if err != nil {
 			return err
 		}
@@ -149,7 +149,7 @@
 		// #10618
 		_, tmpfsExists := hostConfig.Tmpfs[bind.Destination]
 		if binds[bind.Destination] || tmpfsExists {
-			return fmt.Errorf("Duplicate mount point '%s'", bind.Destination)
+			return duplicateMountPointError(bind.Destination)
 		}
 
 		if bind.Type == mounttypes.TypeVolume {
@@ -173,13 +173,13 @@
 	}
 
 	for _, cfg := range hostConfig.Mounts {
-		mp, err := volume.ParseMountSpec(cfg)
+		mp, err := parser.ParseMountSpec(cfg)
 		if err != nil {
-			return dockererrors.NewBadRequestError(err)
+			return validationError{err}
 		}
 
 		if binds[mp.Destination] {
-			return fmt.Errorf("Duplicate mount point '%s'", cfg.Target)
+			return duplicateMountPointError(cfg.Target)
 		}
 
 		if mp.Type == mounttypes.TypeVolume {
@@ -207,6 +207,9 @@
 			}); ok {
 				mp.Source = cv.CachedPath()
 			}
+			if mp.Driver == volume.DefaultDriverName {
+				setBindModeIfNull(mp)
+			}
 		}
 
 		binds[mp.Destination] = true
@@ -218,7 +221,7 @@
 
 	// 4. Cleanup old volumes that are about to be reassigned.
 	for _, m := range mountPoints {
-		if m.BackwardsCompatible() {
+		if parser.IsBackwardCompatible(m) {
 			if mp, exists := container.MountPoints[m.Destination]; exists && mp.Volume != nil {
 				daemon.volumes.Dereference(mp.Volume, container.ID)
 			}
@@ -253,6 +256,8 @@
 	container.Lock()
 	defer container.Unlock()
 
+	parser := volume.NewParser(container.Platform)
+
 	maybeUpdate := make(map[string]bool)
 	for _, mp := range container.MountPoints {
 		if mp.Spec.Source != "" && mp.Type != "" {
@@ -271,7 +276,7 @@
 
 	binds := make(map[string]*volume.MountPoint, len(container.HostConfig.Binds))
 	for _, rawSpec := range container.HostConfig.Binds {
-		mp, err := volume.ParseMountRaw(rawSpec, container.HostConfig.VolumeDriver)
+		mp, err := parser.ParseMountRaw(rawSpec, container.HostConfig.VolumeDriver)
 		if err != nil {
 			logrus.WithError(err).Error("Got unexpected error while re-parsing raw volume spec during spec backport")
 			continue
@@ -281,7 +286,7 @@
 
 	volumesFrom := make(map[string]volume.MountPoint)
 	for _, fromSpec := range container.HostConfig.VolumesFrom {
-		from, _, err := volume.ParseVolumesFrom(fromSpec)
+		from, _, err := parser.ParseVolumesFrom(fromSpec)
 		if err != nil {
 			logrus.WithError(err).WithField("id", container.ID).Error("Error reading volumes-from spec during mount spec backport")
 			continue
diff --git a/daemon/volumes_unit_test.go b/daemon/volumes_unit_test.go
index 450d17f..3f57f0c 100644
--- a/daemon/volumes_unit_test.go
+++ b/daemon/volumes_unit_test.go
@@ -1,6 +1,7 @@
 package daemon
 
 import (
+	"runtime"
 	"testing"
 
 	"github.com/docker/docker/volume"
@@ -20,8 +21,10 @@
 		{"foobar:baz", "", "", true},
 	}
 
+	parser := volume.NewParser(runtime.GOOS)
+
 	for _, c := range cases {
-		id, mode, err := volume.ParseVolumesFrom(c.spec)
+		id, mode, err := parser.ParseVolumesFrom(c.spec)
 		if c.fail {
 			if err == nil {
 				t.Fatalf("Expected error, was nil, for spec %s\n", c.spec)
diff --git a/distribution/errors.go b/distribution/errors.go
index f453c01..dd6ff0a 100644
--- a/distribution/errors.go
+++ b/distribution/errors.go
@@ -1,11 +1,11 @@
 package distribution
 
 import (
+	"fmt"
 	"net/url"
 	"strings"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/distribution/registry/api/errcode"
@@ -13,7 +13,7 @@
 	"github.com/docker/distribution/registry/client"
 	"github.com/docker/distribution/registry/client/auth"
 	"github.com/docker/docker/distribution/xfer"
-	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // ErrNoSupport is an error type used for errors indicating that an operation
@@ -60,6 +60,45 @@
 	return false
 }
 
+type notFoundError struct {
+	cause errcode.Error
+	ref   reference.Named
+}
+
+func (e notFoundError) Error() string {
+	switch e.cause.Code {
+	case errcode.ErrorCodeDenied:
+		// ErrorCodeDenied is used when access to the repository was denied
+		return fmt.Sprintf("pull access denied for %s, repository does not exist or may require 'docker login'", reference.FamiliarName(e.ref))
+	case v2.ErrorCodeManifestUnknown:
+		return fmt.Sprintf("manifest for %s not found", reference.FamiliarString(e.ref))
+	case v2.ErrorCodeNameUnknown:
+		return fmt.Sprintf("repository %s not found", reference.FamiliarName(e.ref))
+	}
+	// Shouldn't get here, but this is better than returning an empty string
+	return e.cause.Message
+}
+
+func (e notFoundError) NotFound() {}
+
+func (e notFoundError) Cause() error {
+	return e.cause
+}
+
+type unknownError struct {
+	cause error
+}
+
+func (e unknownError) Error() string {
+	return e.cause.Error()
+}
+
+func (e unknownError) Cause() error {
+	return e.cause
+}
+
+func (e unknownError) Unknown() {}
+
 // TranslatePullError is used to convert an error from a registry pull
 // operation to an error representing the entire pull operation. Any error
 // information which is not used by the returned error gets output to
@@ -74,25 +113,15 @@
 			return TranslatePullError(v[0], ref)
 		}
 	case errcode.Error:
-		var newErr error
 		switch v.Code {
-		case errcode.ErrorCodeDenied:
-			// ErrorCodeDenied is used when access to the repository was denied
-			newErr = errors.Errorf("pull access denied for %s, repository does not exist or may require 'docker login'", reference.FamiliarName(ref))
-		case v2.ErrorCodeManifestUnknown:
-			newErr = errors.Errorf("manifest for %s not found", reference.FamiliarString(ref))
-		case v2.ErrorCodeNameUnknown:
-			newErr = errors.Errorf("repository %s not found", reference.FamiliarName(ref))
-		}
-		if newErr != nil {
-			logrus.Infof("Translating %q to %q", err, newErr)
-			return newErr
+		case errcode.ErrorCodeDenied, v2.ErrorCodeManifestUnknown, v2.ErrorCodeNameUnknown:
+			return notFoundError{v, ref}
 		}
 	case xfer.DoNotRetry:
 		return TranslatePullError(v.Err, ref)
 	}
 
-	return err
+	return unknownError{err}
 }
 
 // continueOnError returns true if we should fallback to the next endpoint
@@ -157,3 +186,30 @@
 	// add them to the switch above.
 	return err
 }
+
+type invalidManifestClassError struct {
+	mediaType string
+	class     string
+}
+
+func (e invalidManifestClassError) Error() string {
+	return fmt.Sprintf("Encountered remote %q(%s) when fetching", e.mediaType, e.class)
+}
+
+func (e invalidManifestClassError) InvalidParameter() {}
+
+type invalidManifestFormatError struct{}
+
+func (invalidManifestFormatError) Error() string {
+	return "unsupported manifest format"
+}
+
+func (invalidManifestFormatError) InvalidParameter() {}
+
+type reservedNameError string
+
+func (e reservedNameError) Error() string {
+	return "'" + string(e) + "' is a reserved name"
+}
+
+func (e reservedNameError) Forbidden() {}
diff --git a/distribution/metadata/v2_metadata_service.go b/distribution/metadata/v2_metadata_service.go
index 7524f63..af599be 100644
--- a/distribution/metadata/v2_metadata_service.go
+++ b/distribution/metadata/v2_metadata_service.go
@@ -84,7 +84,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return []byte(digest.FromBytes([]byte(buf))), nil
+	return []byte(digest.FromBytes(buf)), nil
 }
 
 // authConfigKeyInput is a reduced AuthConfig structure holding just relevant credential data eligible for
diff --git a/distribution/pull.go b/distribution/pull.go
index c5bdbd6..68144df 100644
--- a/distribution/pull.go
+++ b/distribution/pull.go
@@ -3,7 +3,6 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/distribution/metadata"
@@ -11,6 +10,8 @@
 	refstore "github.com/docker/docker/reference"
 	"github.com/docker/docker/registry"
 	"github.com/opencontainers/go-digest"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -173,7 +174,7 @@
 // ValidateRepoName validates the name of a repository.
 func ValidateRepoName(name reference.Named) error {
 	if reference.FamiliarName(name) == api.NoBaseImageSpecifier {
-		return fmt.Errorf("'%s' is a reserved name", api.NoBaseImageSpecifier)
+		return errors.WithStack(reservedNameError(api.NoBaseImageSpecifier))
 	}
 	return nil
 }
diff --git a/distribution/pull_v1.go b/distribution/pull_v1.go
index 7151a75..19a8792 100644
--- a/distribution/pull_v1.go
+++ b/distribution/pull_v1.go
@@ -11,7 +11,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/distribution/registry/client/transport"
 	"github.com/docker/docker/distribution/metadata"
@@ -24,6 +23,7 @@
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/registry"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -52,11 +52,7 @@
 		registry.DockerHeaders(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)...,
 	)
 	client := registry.HTTPClient(tr)
-	v1Endpoint, err := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)
-	if err != nil {
-		logrus.Debugf("Could not get v1 endpoint: %v", err)
-		return fallbackError{err: err}
-	}
+	v1Endpoint := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)
 	p.session, err = registry.NewSession(client, p.config.AuthConfig, v1Endpoint)
 	if err != nil {
 		// TODO(dmcgowan): Check if should fallback
diff --git a/distribution/pull_v2.go b/distribution/pull_v2.go
index 50257f5..39bf782 100644
--- a/distribution/pull_v2.go
+++ b/distribution/pull_v2.go
@@ -2,7 +2,6 @@
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -10,7 +9,6 @@
 	"os"
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/manifest/manifestlist"
 	"github.com/docker/distribution/manifest/schema1"
@@ -30,7 +28,9 @@
 	"github.com/docker/docker/pkg/system"
 	refstore "github.com/docker/docker/reference"
 	"github.com/docker/docker/registry"
-	"github.com/opencontainers/go-digest"
+	digest "github.com/opencontainers/go-digest"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -368,7 +368,7 @@
 			if configClass == "" {
 				configClass = "unknown"
 			}
-			return false, fmt.Errorf("Encountered remote %q(%s) when fetching", m.Manifest.Config.MediaType, configClass)
+			return false, invalidManifestClassError{m.Manifest.Config.MediaType, configClass}
 		}
 	}
 
@@ -404,7 +404,7 @@
 			return false, err
 		}
 	default:
-		return false, errors.New("unsupported manifest format")
+		return false, invalidManifestFormatError{}
 	}
 
 	progress.Message(p.config.ProgressOutput, "", "Digest: "+manifestDigest.String())
@@ -435,7 +435,7 @@
 	return true, nil
 }
 
-func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Named, unverifiedManifest *schema1.SignedManifest) (id digest.Digest, manifestDigest digest.Digest, err error) {
+func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unverifiedManifest *schema1.SignedManifest) (id digest.Digest, manifestDigest digest.Digest, err error) {
 	var verifiedManifest *schema1.Manifest
 	verifiedManifest, err = verifySchema1Manifest(unverifiedManifest, ref)
 	if err != nil {
@@ -709,11 +709,16 @@
 
 	logrus.Debugf("%s resolved to a manifestList object with %d entries; looking for a os/arch match", ref, len(mfstList.Manifests))
 	var manifestDigest digest.Digest
+	// TODO @jhowardmsft LCOW Support: Need to remove the hard coding in LCOW mode.
+	lookingForOS := runtime.GOOS
+	if system.LCOWSupported() {
+		lookingForOS = "linux"
+	}
 	for _, manifestDescriptor := range mfstList.Manifests {
 		// TODO(aaronl): The manifest list spec supports optional
 		// "features" and "variant" fields. These are not yet used.
 		// Once they are, their values should be interpreted here.
-		if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == runtime.GOOS {
+		if manifestDescriptor.Platform.Architecture == runtime.GOARCH && manifestDescriptor.Platform.OS == lookingForOS {
 			manifestDigest = manifestDescriptor.Digest
 			logrus.Debugf("found match for %s/%s with media type %s, digest %s", runtime.GOOS, runtime.GOARCH, manifestDescriptor.MediaType, manifestDigest.String())
 			break
@@ -838,7 +843,7 @@
 	return err
 }
 
-func verifySchema1Manifest(signedManifest *schema1.SignedManifest, ref reference.Named) (m *schema1.Manifest, err error) {
+func verifySchema1Manifest(signedManifest *schema1.SignedManifest, ref reference.Reference) (m *schema1.Manifest, err error) {
 	// If pull by digest, then verify the manifest digest. NOTE: It is
 	// important to do this first, before any other content validation. If the
 	// digest cannot be verified, don't even bother with those other things.
@@ -908,7 +913,7 @@
 			m.FSLayers = append(m.FSLayers[:i], m.FSLayers[i+1:]...)
 			m.History = append(m.History[:i], m.History[i+1:]...)
 		} else if imgs[i].Parent != imgs[i+1].ID {
-			return fmt.Errorf("Invalid parent ID. Expected %v, got %v.", imgs[i+1].ID, imgs[i].Parent)
+			return fmt.Errorf("invalid parent ID. Expected %v, got %v", imgs[i+1].ID, imgs[i].Parent)
 		}
 	}
 
diff --git a/distribution/pull_v2_test.go b/distribution/pull_v2_test.go
index df93c1e..7355fb9 100644
--- a/distribution/pull_v2_test.go
+++ b/distribution/pull_v2_test.go
@@ -10,6 +10,7 @@
 
 	"github.com/docker/distribution/manifest/schema1"
 	"github.com/docker/distribution/reference"
+	"github.com/docker/docker/internal/testutil"
 	"github.com/opencontainers/go-digest"
 )
 
@@ -102,9 +103,8 @@
 		},
 	}
 
-	if err := fixManifestLayers(&duplicateLayerManifest); err == nil || !strings.Contains(err.Error(), "Invalid parent ID.") {
-		t.Fatalf("expected an invalid parent ID error from fixManifestLayers")
-	}
+	err := fixManifestLayers(&duplicateLayerManifest)
+	testutil.ErrorContains(t, err, "invalid parent ID")
 }
 
 // TestValidateManifest verifies the validateManifest function
diff --git a/distribution/pull_v2_windows.go b/distribution/pull_v2_windows.go
index 543ecc1..e10070d 100644
--- a/distribution/pull_v2_windows.go
+++ b/distribution/pull_v2_windows.go
@@ -6,11 +6,11 @@
 	"net/http"
 	"os"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/context"
 	"github.com/docker/distribution/manifest/schema2"
 	"github.com/docker/distribution/registry/client/transport"
+	"github.com/sirupsen/logrus"
 )
 
 var _ distribution.Describable = &v2LayerDescriptor{}
diff --git a/distribution/push.go b/distribution/push.go
index 395e4d1..869a53e 100644
--- a/distribution/push.go
+++ b/distribution/push.go
@@ -6,11 +6,11 @@
 	"fmt"
 	"io"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/distribution/metadata"
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/registry"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -69,7 +69,7 @@
 		return err
 	}
 
-	progress.Messagef(imagePushConfig.ProgressOutput, "", "The push refers to a repository [%s]", repoInfo.Name.Name())
+	progress.Messagef(imagePushConfig.ProgressOutput, "", "The push refers to repository [%s]", repoInfo.Name.Name())
 
 	associations := imagePushConfig.ReferenceStore.ReferencesByName(repoInfo.Name)
 	if len(associations) == 0 {
diff --git a/distribution/push_v1.go b/distribution/push_v1.go
index 431faaf..6cc4f15 100644
--- a/distribution/push_v1.go
+++ b/distribution/push_v1.go
@@ -4,7 +4,6 @@
 	"fmt"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/distribution/registry/client/transport"
 	"github.com/docker/docker/distribution/metadata"
@@ -17,6 +16,7 @@
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/registry"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -41,11 +41,7 @@
 		registry.DockerHeaders(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)...,
 	)
 	client := registry.HTTPClient(tr)
-	v1Endpoint, err := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)
-	if err != nil {
-		logrus.Debugf("Could not get v1 endpoint: %v", err)
-		return fallbackError{err: err}
-	}
+	v1Endpoint := p.endpoint.ToV1Endpoint(dockerversion.DockerUserAgent(ctx), p.config.MetaHeaders)
 	p.session, err = registry.NewSession(client, p.config.AuthConfig, v1Endpoint)
 	if err != nil {
 		// TODO(dmcgowan): Check if should fallback
diff --git a/distribution/push_v2.go b/distribution/push_v2.go
index ffc7d68..1dfa881 100644
--- a/distribution/push_v2.go
+++ b/distribution/push_v2.go
@@ -11,7 +11,6 @@
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/manifest/schema1"
 	"github.com/docker/distribution/manifest/schema2"
@@ -25,7 +24,8 @@
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/registry"
-	"github.com/opencontainers/go-digest"
+	digest "github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -395,12 +395,7 @@
 	defer layerUpload.Close()
 
 	// upload the blob
-	desc, err := pd.uploadUsingSession(ctx, progressOutput, diffID, layerUpload)
-	if err != nil {
-		return desc, err
-	}
-
-	return desc, nil
+	return pd.uploadUsingSession(ctx, progressOutput, diffID, layerUpload)
 }
 
 func (pd *v2PushDescriptor) SetRemoteDescriptor(descriptor distribution.Descriptor) {
@@ -651,6 +646,7 @@
 }
 func (bla byLikeness) Len() int { return len(bla.arr) }
 
+// nolint: interfacer
 func sortV2MetadataByLikenessAndAge(repoInfo reference.Named, hmacKey []byte, marr []metadata.V2Metadata) {
 	// reverse the metadata array to shift the newest entries to the beginning
 	for i := 0; i < len(marr)/2; i++ {
diff --git a/distribution/registry_unit_test.go b/distribution/registry_unit_test.go
index 910061f..9653f29 100644
--- a/distribution/registry_unit_test.go
+++ b/distribution/registry_unit_test.go
@@ -1,23 +1,17 @@
 package distribution
 
 import (
-	"fmt"
-	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
-	"os"
-	"runtime"
 	"strings"
 	"testing"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
 	registrytypes "github.com/docker/docker/api/types/registry"
-	"github.com/docker/docker/pkg/archive"
-	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/registry"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -42,12 +36,6 @@
 }
 
 func testTokenPassThru(t *testing.T, ts *httptest.Server) {
-	tmp, err := testDirectory("")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmp)
-
 	uri, err := url.Parse(ts.URL)
 	if err != nil {
 		t.Fatalf("could not parse url from test server: %v", err)
@@ -137,36 +125,3 @@
 		t.Fatal("Redirect should not forward Authorization header to another host")
 	}
 }
-
-// testDirectory creates a new temporary directory and returns its path.
-// The contents of directory at path `templateDir` is copied into the
-// new directory.
-func testDirectory(templateDir string) (dir string, err error) {
-	testID := stringid.GenerateNonCryptoID()[:4]
-	prefix := fmt.Sprintf("docker-test%s-%s-", testID, getCallerName(2))
-	if prefix == "" {
-		prefix = "docker-test-"
-	}
-	dir, err = ioutil.TempDir("", prefix)
-	if err = os.Remove(dir); err != nil {
-		return
-	}
-	if templateDir != "" {
-		if err = archive.NewDefaultArchiver().CopyWithTar(templateDir, dir); err != nil {
-			return
-		}
-	}
-	return
-}
-
-// getCallerName introspects the call stack and returns the name of the
-// function `depth` levels down in the stack.
-func getCallerName(depth int) string {
-	// Use the caller function name as a prefix.
-	// This helps trace temp directories back to their test.
-	pc, _, _, _ := runtime.Caller(depth + 1)
-	callerLongName := runtime.FuncForPC(pc).Name()
-	parts := strings.Split(callerLongName, ".")
-	callerShortName := parts[len(parts)-1]
-	return callerShortName
-}
diff --git a/distribution/utils/progress.go b/distribution/utils/progress.go
index cc3632a..96380fd 100644
--- a/distribution/utils/progress.go
+++ b/distribution/utils/progress.go
@@ -6,9 +6,9 @@
 	"os"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/streamformatter"
+	"github.com/sirupsen/logrus"
 )
 
 // WriteDistributionProgress is a helper for writing progress from chan to JSON
diff --git a/distribution/xfer/download.go b/distribution/xfer/download.go
index 6769ee1..6ee0aa5 100644
--- a/distribution/xfer/download.go
+++ b/distribution/xfer/download.go
@@ -7,13 +7,13 @@
 	"runtime"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/progress"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/distribution/xfer/upload.go b/distribution/xfer/upload.go
index 58422e5..3310a3c 100644
--- a/distribution/xfer/upload.go
+++ b/distribution/xfer/upload.go
@@ -4,10 +4,10 @@
 	"errors"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/progress"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/docs/api/v1.18.md b/docs/api/v1.18.md
index 3c82371..973dca9 100644
--- a/docs/api/v1.18.md
+++ b/docs/api/v1.18.md
@@ -232,11 +232,11 @@
 -   **ExposedPorts** - An object mapping ports to an empty object in the form of:
       `"ExposedPorts": { "<port>/<tcp|udp>: {}" }`
 -   **HostConfig**
-    -   **Binds** – A list of bind-mounts for this container. Each item is a string in one of these forms:
+    -   **Binds** – A list of bind mounts for this container. Each item is a string in one of these forms:
            + `host-src:container-dest` to bind-mount a host path into the
              container. Both `host-src`, and `container-dest` must be an
              _absolute_ path.
-           + `host-src:container-dest:ro` to make the bind-mount read-only
+           + `host-src:container-dest:ro` to make the bind mount read-only
              inside the container. Both `host-src`, and `container-dest` must be
              an _absolute_ path.
     -   **Links** - A list of links for the container. Each link entry should be
diff --git a/docs/api/v1.19.md b/docs/api/v1.19.md
index bd5f09f..3bcf766 100644
--- a/docs/api/v1.19.md
+++ b/docs/api/v1.19.md
@@ -239,11 +239,11 @@
 -   **ExposedPorts** - An object mapping ports to an empty object in the form of:
       `"ExposedPorts": { "<port>/<tcp|udp>: {}" }`
 -   **HostConfig**
-    -   **Binds** – A list of bind-mounts for this container. Each item is a string in one of these forms:
+    -   **Binds** – A list of bind mounts for this container. Each item is a string in one of these forms:
            + `host-src:container-dest` to bind-mount a host path into the
              container. Both `host-src`, and `container-dest` must be an
              _absolute_ path.
-           + `host-src:container-dest:ro` to make the bind-mount read-only
+           + `host-src:container-dest:ro` to make the bind mount read-only
              inside the container. Both `host-src`, and `container-dest` must be
              an _absolute_ path.
     -   **Links** - A list of links for the container. Each link entry should be
diff --git a/docs/api/v1.20.md b/docs/api/v1.20.md
index a7fc999..e5b8f32 100644
--- a/docs/api/v1.20.md
+++ b/docs/api/v1.20.md
@@ -239,11 +239,11 @@
 -   **ExposedPorts** - An object mapping ports to an empty object in the form of:
       `"ExposedPorts": { "<port>/<tcp|udp>: {}" }`
 -   **HostConfig**
-    -   **Binds** – A list of bind-mounts for this container. Each item is a string in one of these forms:
+    -   **Binds** – A list of bind mounts for this container. Each item is a string in one of these forms:
            + `host-src:container-dest` to bind-mount a host path into the
              container. Both `host-src`, and `container-dest` must be an
              _absolute_ path.
-           + `host-src:container-dest:ro` to make the bind-mount read-only
+           + `host-src:container-dest:ro` to make the bind mount read-only
              inside the container. Both `host-src`, and `container-dest` must be
              an _absolute_ path.
     -   **Links** - A list of links for the container. Each link entry should be
diff --git a/docs/api/v1.21.md b/docs/api/v1.21.md
index 1d42fd0..f1863b8 100644
--- a/docs/api/v1.21.md
+++ b/docs/api/v1.21.md
@@ -255,7 +255,7 @@
            + `host-src:container-dest` to bind-mount a host path into the
              container. Both `host-src`, and `container-dest` must be an
              _absolute_ path.
-           + `host-src:container-dest:ro` to make the bind-mount read-only
+           + `host-src:container-dest:ro` to make the bind mount read-only
              inside the container. Both `host-src`, and `container-dest` must be
              an _absolute_ path.
            + `volume-name:container-dest` to bind-mount a volume managed by a
diff --git a/docs/api/v1.22.md b/docs/api/v1.22.md
index 9bf64b7..473ffd3 100644
--- a/docs/api/v1.22.md
+++ b/docs/api/v1.22.md
@@ -357,7 +357,7 @@
            + `host-src:container-dest` to bind-mount a host path into the
              container. Both `host-src`, and `container-dest` must be an
              _absolute_ path.
-           + `host-src:container-dest:ro` to make the bind-mount read-only
+           + `host-src:container-dest:ro` to make the bind mount read-only
              inside the container. Both `host-src`, and `container-dest` must be
              an _absolute_ path.
            + `volume-name:container-dest` to bind-mount a volume managed by a
diff --git a/docs/api/v1.23.md b/docs/api/v1.23.md
index 508a721..c040d24 100644
--- a/docs/api/v1.23.md
+++ b/docs/api/v1.23.md
@@ -382,7 +382,7 @@
            + `host-src:container-dest` to bind-mount a host path into the
              container. Both `host-src`, and `container-dest` must be an
              _absolute_ path.
-           + `host-src:container-dest:ro` to make the bind-mount read-only
+           + `host-src:container-dest:ro` to make the bind mount read-only
              inside the container. Both `host-src`, and `container-dest` must be
              an _absolute_ path.
            + `volume-name:container-dest` to bind-mount a volume managed by a
diff --git a/docs/api/v1.24.md b/docs/api/v1.24.md
index d07ea84..29fed46 100644
--- a/docs/api/v1.24.md
+++ b/docs/api/v1.24.md
@@ -414,7 +414,7 @@
            + `host-src:container-dest` to bind-mount a host path into the
              container. Both `host-src`, and `container-dest` must be an
              _absolute_ path.
-           + `host-src:container-dest:ro` to make the bind-mount read-only
+           + `host-src:container-dest:ro` to make the bind mount read-only
              inside the container. Both `host-src`, and `container-dest` must be
              an _absolute_ path.
            + `volume-name:container-dest` to bind-mount a volume managed by a
diff --git a/docs/api/version-history.md b/docs/api/version-history.md
index e5d9d8d..d6d611f 100644
--- a/docs/api/version-history.md
+++ b/docs/api/version-history.md
@@ -13,12 +13,39 @@
      will be rejected.
 -->
 
+## v1.34 API changes
+
+[Docker Engine API v1.34](https://docs.docker.com/engine/api/v1.34/) documentation
+
+## v1.33 API changes
+
+[Docker Engine API v1.33](https://docs.docker.com/engine/api/v1.33/) documentation
+
+* `GET /events` now supports filtering 4 more kinds of events: `config`, `node`,
+`secret` and `service`. 
+
+## v1.32 API changes
+
+[Docker Engine API v1.32](https://docs.docker.com/engine/api/v1.32/) documentation
+
+* `POST /containers/create` now accepts additional values for the
+  `HostConfig.IpcMode` property. New values are `private`, `shareable`,
+  and `none`.
+
 ## v1.31 API changes
 
 [Docker Engine API v1.31](https://docs.docker.com/engine/api/v1.31/) documentation
 
 * `DELETE /secrets/(name)` now returns status code 404 instead of 500 when the secret does not exist.
 * `POST /secrets/create` now returns status code 409 instead of 500 when creating an already existing secret.
+* `POST /secrets/create` now accepts a `Driver` struct, allowing the
+  `Name` and driver-specific `Options` to be passed to store a secrets
+  in an external secrets store. The `Driver` property can be omitted
+  if the default (internal) secrets store is used.
+* `GET /secrets/(id)` and `GET /secrets` now return a `Driver` struct,
+  containing the `Name` and driver-specific `Options` of the external
+  secrets store used to store the secret. The `Driver` property is
+  omitted if no external store is used.
 * `POST /secrets/(name)/update` now returns status code 400 instead of 500 when updating a secret's content which is not the labels.
 * `POST /nodes/(name)/update` now returns status code 400 instead of 500 when demoting last node fails.
 * `GET /networks/(id or name)` now takes an optional query parameter `scope` that will filter the network based on the scope (`local`, `swarm`, or `global`).
@@ -54,8 +81,8 @@
 * `POST /containers/(name)/wait` now accepts a `condition` query parameter to indicate which state change condition to wait for. Also, response headers are now returned immediately to acknowledge that the server has registered a wait callback for the client.
 * `POST /swarm/init` now accepts a `DataPathAddr` property to set the IP-address or network interface to use for data traffic
 * `POST /swarm/join` now accepts a `DataPathAddr` property to set the IP-address or network interface to use for data traffic
-* `GET /events` now supports service, node and secret events which are emmited when users create, update and remove service, node and secret 
-* `GET /events` now supports network remove event which is emmitted when users remove a swarm scoped network
+* `GET /events` now supports service, node and secret events which are emitted when users create, update and remove service, node and secret 
+* `GET /events` now supports network remove event which is emitted when users remove a swarm scoped network
 * `GET /events` now supports a filter type `scope` in which supported value could be swarm and local
 
 ## v1.29 API changes
diff --git a/hack/README.md b/hack/README.md
index 802395d..9e588db 100644
--- a/hack/README.md
+++ b/hack/README.md
@@ -37,14 +37,14 @@
 - Referenced via `make test` when running tests on a local machine,
 or directly referenced when running tests inside a Docker development container.  
 - When running on a local machine, `make test` to run all tests found in
-`test`, `test-unit`, `test-integration-cli`, and `test-docker-py` on
+`test`, `test-unit`, `test-integration`, and `test-docker-py` on
 your local machine. The default timeout is set in `make.sh` to 60 minutes
 (`${TIMEOUT:=60m}`), since it currently takes up to an hour to run
 all of the tests.
 - When running inside a Docker development container, `hack/make.sh` does
 not have a single target that runs all the tests. You need to provide a
 single command line with multiple targets that performs the same thing.
-An example referenced from [Run targets inside a development container](https://docs.docker.com/opensource/project/test-and-docs/#run-targets-inside-a-development-container): `root@5f8630b873fe:/go/src/github.com/moby/moby# hack/make.sh dynbinary binary cross test-unit test-integration-cli test-docker-py`
+An example referenced from [Run targets inside a development container](https://docs.docker.com/opensource/project/test-and-docs/#run-targets-inside-a-development-container): `root@5f8630b873fe:/go/src/github.com/moby/moby# hack/make.sh dynbinary binary cross test-unit test-integration test-docker-py`
 - For more information related to testing outside the scope of this README,
 refer to
 [Run tests and test documentation](https://docs.docker.com/opensource/project/test-and-docs/)
diff --git a/hack/ci/arm b/hack/ci/arm
new file mode 100755
index 0000000..e60332a
--- /dev/null
+++ b/hack/ci/arm
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+# Entrypoint for jenkins arm CI build
+set -eu -o pipefail
+
+hack/test/unit
+
+hack/make.sh \
+	binary-daemon \
+	dynbinary \
+	test-integration
diff --git a/hack/ci/experimental b/hack/ci/experimental
new file mode 100755
index 0000000..9ccbc84
--- /dev/null
+++ b/hack/ci/experimental
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# Entrypoint for jenkins experimental CI
+set -eu -o pipefail
+
+export DOCKER_EXPERIMENTAL=y
+
+hack/make.sh \
+	binary-daemon \
+	test-integration
diff --git a/hack/ci/janky b/hack/ci/janky
new file mode 100755
index 0000000..fe04908
--- /dev/null
+++ b/hack/ci/janky
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+# Entrypoint for jenkins janky CI build
+set -eu -o pipefail
+
+hack/validate/default
+hack/test/unit
+
+hack/make.sh \
+	binary-daemon \
+	dynbinary \
+	test-integration \
+	test-docker-py \
+	cross
diff --git a/hack/ci/powerpc b/hack/ci/powerpc
new file mode 100755
index 0000000..c36cf37
--- /dev/null
+++ b/hack/ci/powerpc
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# Entrypoint for jenkins powerpc CI build
+set -eu -o pipefail
+
+hack/test/unit
+hack/make.sh dynbinary test-integration
diff --git a/hack/ci/z b/hack/ci/z
new file mode 100755
index 0000000..5ba868e
--- /dev/null
+++ b/hack/ci/z
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# Entrypoint for jenkins s390x (z) CI build
+set -eu -o pipefail
+
+hack/test/unit
+hack/make.sh dynbinary test-integration
diff --git a/hack/dockerfile/binaries-commits b/hack/dockerfile/binaries-commits
index 84c5c0f..182da73 100644
--- a/hack/dockerfile/binaries-commits
+++ b/hack/dockerfile/binaries-commits
@@ -3,12 +3,11 @@
 TOMLV_COMMIT=9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
 
 # When updating RUNC_COMMIT, also update runc in vendor.conf accordingly
-RUNC_COMMIT=2d41c047c83e09a6d61d464906feb2a2f3c52aa4
-CONTAINERD_COMMIT=3addd840653146c90a254301d6c3a663c7fd6429
+RUNC_COMMIT=0351df1c5a66838d0c392b4ac4cf9450de844e2d
+CONTAINERD_COMMIT=06b9cb35161009dcb7123345749fef02f7cea8e0
 TINI_COMMIT=949e6facb77383876aeff8a6944dde66b3089574
 LIBNETWORK_COMMIT=7b2b1feb1de4817d522cc372af149ff48d25028e
-VNDR_COMMIT=9909bb2b8a0b7ea464527b376dc50389c90df587
+VNDR_COMMIT=a6e196d8b4b0cbbdc29aebdb20c59ac6926bb384
 
-# CLI
-DOCKERCLI_REPO=https://github.com/docker/cli
-DOCKERCLI_COMMIT=3dfb8343b139d6342acfd9975d7f1068b5b1c3d3
+# Linting
+GOMETALINTER_COMMIT=bfcc1d6942136fd86eb6f1a6fb328de8398fbd80
diff --git a/hack/dockerfile/install-binaries.sh b/hack/dockerfile/install-binaries.sh
index 370ec7c..4debd3a 100755
--- a/hack/dockerfile/install-binaries.sh
+++ b/hack/dockerfile/install-binaries.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
 set -e
 set -x
 
@@ -20,7 +20,7 @@
 
 install_runc() {
 	echo "Install runc version $RUNC_COMMIT"
-	git clone https://github.com/docker/runc.git "$GOPATH/src/github.com/opencontainers/runc"
+	git clone https://github.com/opencontainers/runc.git "$GOPATH/src/github.com/opencontainers/runc"
 	cd "$GOPATH/src/github.com/opencontainers/runc"
 	git checkout -q "$RUNC_COMMIT"
 	make BUILDTAGS="$RUNC_BUILDTAGS" $1
@@ -47,13 +47,43 @@
 }
 
 install_dockercli() {
-	echo "Install docker/cli version $DOCKERCLI_COMMIT"
-	git clone "$DOCKERCLI_REPO" "$GOPATH/src/github.com/docker/cli"
-	cd "$GOPATH/src/github.com/docker/cli"
-	git checkout -q "$DOCKERCLI_COMMIT"
+	DOCKERCLI_CHANNEL=${DOCKERCLI_CHANNEL:-edge}
+	DOCKERCLI_VERSION=${DOCKERCLI_VERSION:-17.06.0-ce}
+	echo "Install docker/cli version $DOCKERCLI_VERSION from $DOCKERCLI_CHANNEL"
+
+	arch=$(uname -m)
+	# No official release of these platforms
+	if [[ "$arch" != "x86_64" ]] && [[ "$arch" != "s390x" ]]; then
+		build_dockercli
+		return
+	fi
+
+	url=https://download.docker.com/linux/static
+	curl -Ls $url/$DOCKERCLI_CHANNEL/$arch/docker-$DOCKERCLI_VERSION.tgz | \
+	tar -xz docker/docker
+	mv docker/docker /usr/local/bin/
+	rmdir docker
+}
+
+build_dockercli() {
+	DOCKERCLI_VERSION=${DOCKERCLI_VERSION:-17.06.0-ce}
+	git clone https://github.com/docker/docker-ce "$GOPATH/tmp/docker-ce"
+	cd "$GOPATH/tmp/docker-ce"
+	git checkout -q "v$DOCKERCLI_VERSION"
+	mkdir -p "$GOPATH/src/github.com/docker"
+	mv components/cli "$GOPATH/src/github.com/docker/cli"
 	go build -o /usr/local/bin/docker github.com/docker/cli/cmd/docker
 }
 
+install_gometalinter() {
+	echo "Installing gometalinter version $GOMETALINTER_COMMIT"
+	go get -d github.com/alecthomas/gometalinter
+	cd "$GOPATH/src/github.com/alecthomas/gometalinter"
+	git checkout -q "$GOMETALINTER_COMMIT"
+	go build -o /usr/local/bin/gometalinter github.com/alecthomas/gometalinter
+	GOBIN=/usr/local/bin gometalinter --install
+}
+
 for prog in "$@"
 do
 	case $prog in
@@ -80,6 +110,10 @@
 			install_containerd
 			;;
 
+		gometalinter)
+			install_gometalinter
+			;;
+
 		tini)
 			echo "Install tini version $TINI_COMMIT"
 			git clone https://github.com/krallin/tini.git "$GOPATH/tini"
@@ -114,7 +148,7 @@
 			;;
 
 		*)
-			echo echo "Usage: $0 [tomlv|runc|runc-dynamic|containerd|containerd-dynamic|tini|proxy|proxy-dynamic|vndr|dockercli]"
+			echo echo "Usage: $0 [tomlv|runc|runc-dynamic|containerd|containerd-dynamic|tini|proxy|proxy-dynamic|vndr|dockercli|gometalinter]"
 			exit 1
 
 	esac
diff --git a/hack/integration-cli-on-swarm/agent/master/call.go b/hack/integration-cli-on-swarm/agent/master/call.go
index 858c2c0..dab9c67 100644
--- a/hack/integration-cli-on-swarm/agent/master/call.go
+++ b/hack/integration-cli-on-swarm/agent/master/call.go
@@ -73,14 +73,14 @@
 				}
 				log.Printf("Finished chunk %d [%d/%d] with %d test filters in %s, code=%d.",
 					chunkID, passed+failed, len(testChunks), len(tests),
-					time.Now().Sub(chunkBegin), result.Code)
+					time.Since(chunkBegin), result.Code)
 			}
 		}(chunkID, tests)
 	}
 	wg.Wait()
 	// TODO: print actual tests rather than chunks
 	log.Printf("Executed %d chunks in %s. PASS: %d, FAIL: %d.",
-		len(testChunks), time.Now().Sub(begin), passed, failed)
+		len(testChunks), time.Since(begin), passed, failed)
 	if failed > 0 {
 		return fmt.Errorf("%d chunks failed", failed)
 	}
@@ -103,7 +103,7 @@
 
 func executeTestChunkWithRetry(funkerName string, args types.Args) (types.Result, error) {
 	begin := time.Now()
-	for i := 0; time.Now().Sub(begin) < funkerRetryTimeout; i++ {
+	for i := 0; time.Since(begin) < funkerRetryTimeout; i++ {
 		result, err := executeTestChunk(funkerName, args)
 		if err == nil {
 			log.Printf("executeTestChunk(%q, %d) returned code %d in trial %d", funkerName, args.ChunkID, result.Code, i)
diff --git a/hack/integration-cli-on-swarm/agent/worker/worker.go b/hack/integration-cli-on-swarm/agent/worker/worker.go
index 36ab368..ea8bb3f 100644
--- a/hack/integration-cli-on-swarm/agent/worker/worker.go
+++ b/hack/integration-cli-on-swarm/agent/worker/worker.go
@@ -58,7 +58,7 @@
 				RawLog:  rawLog,
 			}
 		}
-		elapsed := time.Now().Sub(begin)
+		elapsed := time.Since(begin)
 		log.Printf("Finished chunk %d, code=%d, elapsed=%v", args.ChunkID, code, elapsed)
 		return types.Result{
 			ChunkID: args.ChunkID,
diff --git a/hack/integration-cli-on-swarm/host/host.go b/hack/integration-cli-on-swarm/host/host.go
index 6823a76..fdc2a83 100644
--- a/hack/integration-cli-on-swarm/host/host.go
+++ b/hack/integration-cli-on-swarm/host/host.go
@@ -10,11 +10,11 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/client"
 	"github.com/docker/docker/pkg/stdcopy"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/hack/make.ps1 b/hack/make.ps1
index ac3e369..73c9577 100644
--- a/hack/make.ps1
+++ b/hack/make.ps1
@@ -88,6 +88,7 @@
 )
 
 $ErrorActionPreference = "Stop"
+$ProgressPreference = "SilentlyContinue"
 $pushed=$False  # To restore the directory if we have temporarily pushed to one.
 
 # Utility function to get the commit ID of the repository
@@ -318,7 +319,7 @@
     $pkgList = $pkgList | Select-String -Pattern "github.com/docker/docker"
     $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/vendor"
     $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/man"
-    $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/integration-cli"
+    $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/docker/integration"
     $pkgList = $pkgList -replace "`r`n", " "
     $goTestCommand = "go test" + $raceParm + " -cover -ldflags -w -tags """ + "autogen daemon" + """ -a """ + "-test.timeout=10m" + """ $pkgList"
     Invoke-Expression $goTestCommand
@@ -398,39 +399,29 @@
         # Perform the actual build
         if ($Daemon) { Execute-Build "daemon" "daemon" "dockerd" }
         if ($Client) {
-            # Get the repo and commit of the client to build.
-            "hack\dockerfile\binaries-commits" | ForEach-Object {
-                $dockerCliRepo = ((Get-Content $_ | Select-String "DOCKERCLI_REPO") -split "=")[1]
-                $dockerCliCommit = ((Get-Content $_ | Select-String "DOCKERCLI_COMMIT") -split "=")[1]
-            }
+            # Get the Docker channel and version from the environment, or use the defaults.
+            if (-not ($channel = $env:DOCKERCLI_CHANNEL)) { $channel = "edge" }
+            if (-not ($version = $env:DOCKERCLI_VERSION)) { $version = "17.06.0-ce" }
 
-            # Build from a temporary directory.
-            $tempLocation = "$env:TEMP\$(New-Guid)"
-            New-Item -ItemType Directory $tempLocation | Out-Null
-
-            # Temporarily override GOPATH, then clone, checkout, and build.
-            $saveGOPATH = $env:GOPATH
+            # Download the zip file and extract the client executable.
+            Write-Host "INFO: Downloading docker/cli version $version from $channel..."
+            $url = "https://download.docker.com/win/static/$channel/x86_64/docker-$version.zip"
+            Invoke-WebRequest $url -OutFile "docker.zip"
             Try {
-                $env:GOPATH = $tempLocation
-                $dockerCliRoot = "$env:GOPATH\src\github.com\docker\cli"
-                Write-Host "INFO: Cloning client repository..."
-                Invoke-Expression "git clone -q $dockerCliRepo $dockerCliRoot"
-                if ($LASTEXITCODE -ne 0) { Throw "Failed to clone client repository $dockerCliRepo" }
-                Invoke-Expression "git -C $dockerCliRoot  checkout -q $dockerCliCommit"
-                if ($LASTEXITCODE -ne 0) { Throw "Failed to checkout client commit $dockerCliCommit" }
-                Write-Host "INFO: Building client..."
-                Push-Location "$dockerCliRoot\cmd\docker"; $global:pushed=$True
-                Invoke-Expression "go build -o $root\bundles\docker.exe"
-                if ($LASTEXITCODE -ne 0) { Throw "Failed to compile client" }
-                Pop-Location; $global:pushed=$False
-            }
-            Catch [Exception] {
-                Throw $_
+                Add-Type -AssemblyName System.IO.Compression.FileSystem
+                $zip = [System.IO.Compression.ZipFile]::OpenRead("$PWD\docker.zip")
+                Try {
+                    if (-not ($entry = $zip.Entries | Where-Object { $_.Name -eq "docker.exe" })) {
+                        Throw "Cannot find docker.exe in $url"
+                    }
+                    [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, "$PWD\bundles\docker.exe", $true)
+                }
+                Finally {
+                    $zip.Dispose()
+                }
             }
             Finally {
-                # Always restore GOPATH and remove the temporary directory.
-                $env:GOPATH = $saveGOPATH
-                Remove-Item -Force -Recurse $tempLocation
+                Remove-Item -Force "docker.zip"
             }
         }
     }
diff --git a/hack/make.sh b/hack/make.sh
index e625b86..bc18c06 100755
--- a/hack/make.sh
+++ b/hack/make.sh
@@ -59,19 +59,17 @@
 	binary-daemon
 	dynbinary
 
-	test-unit
-	test-integration-cli
+	test-integration
 	test-docker-py
 
 	cross
-	tgz
 )
 
-VERSION=$(< ./VERSION)
+VERSION=${VERSION:-$(< ./VERSION)}
 ! BUILDTIME=$(date -u -d "@${SOURCE_DATE_EPOCH:-$(date +%s)}" --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')
 if [ "$DOCKER_GITCOMMIT" ]; then
 	GITCOMMIT="$DOCKER_GITCOMMIT"
-elif command -v git &> /dev/null && [ -d .git ] && git rev-parse &> /dev/null; then
+elif command -v git &> /dev/null && [ -e .git ] && git rev-parse &> /dev/null; then
 	GITCOMMIT=$(git rev-parse --short HEAD)
 	if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
 		GITCOMMIT="$GITCOMMIT-unsupported"
@@ -130,7 +128,7 @@
 # functionality.
 if \
 	command -v gcc &> /dev/null \
-	&& ! ( echo -e  '#include <libdevmapper.h>\nint main() { dm_task_deferred_remove(NULL); }'| gcc -xc - -o /dev/null -ldevmapper &> /dev/null ) \
+	&& ! ( echo -e  '#include <libdevmapper.h>\nint main() { dm_task_deferred_remove(NULL); }'| gcc -xc - -o /dev/null $(pkg-config --libs devmapper) &> /dev/null ) \
 ; then
 	DOCKER_BUILDTAGS+=' libdm_no_deferred_remove'
 fi
@@ -190,20 +188,18 @@
 }
 
 main() {
-	# We want this to fail if the bundles already exist and cannot be removed.
-	# This is to avoid mixing bundles from different versions of the code.
-	mkdir -p bundles
-	if [ -e "bundles/$VERSION" ] && [ -z "$KEEPBUNDLE" ]; then
-		echo "bundles/$VERSION already exists. Removing."
-		rm -fr "bundles/$VERSION" && mkdir "bundles/$VERSION" || exit 1
+	if [ -z "${KEEPBUNDLE-}" ]; then
+		echo "Removing bundles/"
+		rm -rf "bundles/*"
 		echo
 	fi
+	mkdir -p bundles
 
+	# Windows and symlinks don't get along well
 	if [ "$(go env GOHOSTOS)" != 'windows' ]; then
-		# Windows and symlinks don't get along well
-
 		rm -f bundles/latest
-		ln -s "$VERSION" bundles/latest
+		# preserve latest symlink for backward compatibility
+		ln -sf . bundles/latest
 	fi
 
 	if [ $# -lt 1 ]; then
@@ -212,7 +208,7 @@
 		bundles=($@)
 	fi
 	for bundle in ${bundles[@]}; do
-		export DEST="bundles/$VERSION/$(basename "$bundle")"
+		export DEST="bundles/$(basename "$bundle")"
 		# Cygdrive paths don't play well with go build -o.
 		if [[ "$(uname -s)" == CYGWIN* ]]; then
 			export DEST="$(cygpath -mw "$DEST")"
diff --git a/hack/make/.ensure-emptyfs b/hack/make/.ensure-emptyfs
index 7b00b9d..898cc22 100644
--- a/hack/make/.ensure-emptyfs
+++ b/hack/make/.ensure-emptyfs
@@ -1,23 +1,23 @@
 #!/usr/bin/env bash
 set -e
 
-if ! docker inspect -t image emptyfs &> /dev/null; then
-	# let's build a "docker save" tarball for "emptyfs"
+if ! docker image inspect emptyfs > /dev/null; then
+	# build a "docker save" tarball for "emptyfs"
 	# see https://github.com/docker/docker/pull/5262
 	# and also https://github.com/docker/docker/issues/4242
 	dir="$DEST/emptyfs"
-	mkdir -p "$dir"
+	uuid=511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
+	mkdir -p "$dir/$uuid"
 	(
-		cd "$dir"
-		echo '{"emptyfs":{"latest":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"}}' > repositories
-		mkdir -p 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
-		(
-			cd 511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158
-			echo '{"id":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158","comment":"Imported from -","created":"2013-06-13T14:03:50.821769-07:00","container_config":{"Hostname":"","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":null},"docker_version":"0.4.0","architecture":"x86_64","Size":0}' > json
-			echo '1.0' > VERSION
-			tar -cf layer.tar --files-from /dev/null
-		)
+		echo '{"emptyfs":{"latest":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"}}' > "$dir/repositories"
+		cd "$dir/$uuid"
+		echo '{"id":"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158","comment":"Imported from -","created":"2013-06-13T14:03:50.821769-07:00","container_config":{"Hostname":"","Domainname":"","User":"","Memory":0,"MemorySwap":0,"CpuShares":0,"AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"PortSpecs":null,"ExposedPorts":null,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"NetworkDisabled":false,"OnBuild":null},"docker_version":"0.4.0","architecture":"x86_64","Size":0}' > json
+		echo '1.0' > VERSION
+		tar -cf layer.tar --files-from /dev/null
 	)
-	( set -x; tar -cC "$dir" . | docker load )
+	(
+		[ -n "$TESTDEBUG" ] && set -x
+		tar -cC "$dir" . | docker load
+	)
 	rm -rf "$dir"
 fi
diff --git a/hack/make/.integration-daemon-setup b/hack/make/.integration-daemon-setup
index 5134e4c..c130e23 100644
--- a/hack/make/.integration-daemon-setup
+++ b/hack/make/.integration-daemon-setup
@@ -1,7 +1,7 @@
 #!/usr/bin/env bash
 set -e
 
-bundle .detect-daemon-osarch
+source "$MAKEDIR/.detect-daemon-osarch"
 if [ "$DOCKER_ENGINE_GOOS" != "windows" ]; then
 	bundle .ensure-emptyfs
 fi
diff --git a/hack/make/.integration-daemon-start b/hack/make/.integration-daemon-start
index dafd053..7314f71 100644
--- a/hack/make/.integration-daemon-start
+++ b/hack/make/.integration-daemon-start
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-# see test-integration-cli for example usage of this script
+# see test-integration for example usage of this script
 
 base="$ABS_DEST/.."
 export PATH="$base/binary-daemon:$base/dynbinary-daemon:$PATH"
@@ -21,8 +21,6 @@
 	false
 fi
 
-export DOCKER_CLI_VERSION=$(${TEST_CLIENT_BINARY} --version | awk '{ gsub(",", " "); print $3 }')
-
 # This is a temporary hack for split-binary mode. It can be removed once
 # https://github.com/docker/docker/pull/22134 is merged into docker master
 if [ "$(go env GOOS)" = 'windows' ]; then
@@ -76,24 +74,26 @@
 		# see https://github.com/docker/libcontainer/blob/master/apparmor/apparmor.go#L16
 		export container=""
 		(
-			set -x
+			[ -n "$TESTDEBUG" ] && set -x
 			/etc/init.d/apparmor start
 		)
 	fi
 
-	export DOCKER_HOST="unix://$(cd "$DEST" && pwd)/docker.sock" # "pwd" tricks to make sure $DEST is an absolute path, not a relative one
-	( set -x; exec \
-		dockerd --debug \
-		--host "$DOCKER_HOST" \
-		--storage-driver "$DOCKER_GRAPHDRIVER" \
-		--pidfile "$DEST/docker.pid" \
-		--userland-proxy="$DOCKER_USERLANDPROXY" \
-		$storage_params \
-		$extra_params \
-			&> "$DEST/docker.log"
+	# "pwd" tricks to make sure $DEST is an absolute path, not a relative one
+	export DOCKER_HOST="unix://$(cd "$DEST" && pwd)/docker.sock"
+	(
+		echo "Starting dockerd"
+		[ -n "$TESTDEBUG" ] && set -x
+		exec \
+			dockerd --debug \
+			--host "$DOCKER_HOST" \
+			--storage-driver "$DOCKER_GRAPHDRIVER" \
+			--pidfile "$DEST/docker.pid" \
+			--userland-proxy="$DOCKER_USERLANDPROXY" \
+			$storage_params \
+			$extra_params \
+				&> "$DEST/docker.log"
 	) &
-	# make sure that if the script exits unexpectedly, we stop this daemon we just started
-	trap 'bundle .integration-daemon-stop' EXIT
 else
 	export DOCKER_HOST="$DOCKER_TEST_HOST"
 fi
diff --git a/hack/make/.integration-daemon-stop b/hack/make/.integration-daemon-stop
index 591a8d6..c1d43e1 100644
--- a/hack/make/.integration-daemon-stop
+++ b/hack/make/.integration-daemon-stop
@@ -1,11 +1,12 @@
 #!/usr/bin/env bash
 
 if [ ! "$(go env GOOS)" = 'windows' ]; then
-	trap - EXIT # reset EXIT trap applied in .integration-daemon-start
-
 	for pidFile in $(find "$DEST" -name docker.pid); do
-		pid=$(set -x; cat "$pidFile")
-		( set -x; kill "$pid" )
+		pid=$([ -n "$TESTDEBUG" ] && set -x; cat "$pidFile")
+		(
+			[ -n "$TESTDEBUG" ] && set -x
+			kill "$pid"
+		)
 		if ! wait "$pid"; then
 			echo >&2 "warning: PID $pid from $pidFile had a nonzero exit code"
 		fi
@@ -15,7 +16,7 @@
 		# Stop apparmor if it is enabled
 		if [ -e "/sys/module/apparmor/parameters/enabled" ] && [ "$(cat /sys/module/apparmor/parameters/enabled)" == "Y" ]; then
 			(
-				set -x
+				[ -n "$TESTDEBUG" ] && set -x
 				/etc/init.d/apparmor stop
 			)
 		fi
diff --git a/hack/make/.integration-test-helpers b/hack/make/.integration-test-helpers
index 4ff9677..e3cb7d8 100644
--- a/hack/make/.integration-test-helpers
+++ b/hack/make/.integration-test-helpers
@@ -1,66 +1,86 @@
 #!/usr/bin/env bash
-
-: ${TEST_REPEAT:=0}
-
-bundle_test_integration_cli() {
-	TESTFLAGS="$TESTFLAGS -check.v -check.timeout=${TIMEOUT} -test.timeout=360m"
-	go_test_dir integration-cli $DOCKER_INTEGRATION_TESTS_VERIFIED
-}
-
-# If $TESTFLAGS is set in the environment, it is passed as extra arguments to 'go test'.
-# You can use this to select certain tests to run, e.g.
-#
-#     TESTFLAGS='-test.run ^TestBuild$' ./hack/make.sh test-unit
 #
 # For integration-cli test, we use [gocheck](https://labix.org/gocheck), if you want
 # to run certain tests on your local host, you should run with command:
 #
-#     TESTFLAGS='-check.f DockerSuite.TestBuild*' ./hack/make.sh binary test-integration-cli
+#     TESTFLAGS='-check.f DockerSuite.TestBuild*' ./hack/make.sh binary test-integration
 #
-go_test_dir() {
-	dir=$1
-	precompiled=$2
-	testbinary="$ABS_DEST/test.main"
-	testcover=()
-	testcoverprofile=()
+
+source "$SCRIPTDIR/make/.go-autogen"
+
+# Set defaults
+: ${TEST_REPEAT:=1}
+: ${TESTFLAGS:=}
+: ${TESTDEBUG:=}
+
+integration_api_dirs=${TEST_INTEGRATION_DIR:-"$(
+	find ./integration -type d |
+	grep -vE '^(./integration$|./integration/util)')"}
+
+run_test_integration() {
+	[[ "$TESTFLAGS" != *-check.f* ]] && run_test_integration_suites
+	run_test_integration_legacy_suites
+}
+
+run_test_integration_suites() {
+	local flags="-test.v -test.timeout=${TIMEOUT} $TESTFLAGS"
+	for dir in $integration_api_dirs; do
+		if ! (
+			cd $dir
+			echo "Running $PWD"
+			test_env ./test.main $flags
+		); then exit 1; fi
+	done
+}
+
+run_test_integration_legacy_suites() {
 	(
-		set -e
-		mkdir -p "$DEST/coverprofiles"
-		export DEST="$ABS_DEST" # in a subshell this is safe -- our integration-cli tests need DEST, and "cd" screws it up
-		if [ -z $precompiled ]; then
-			ensure_test_dir $1 $testbinary
-		fi
-		cd "$dir"
-		i=0
-		while ((++i)); do
-			test_env "$testbinary" $TESTFLAGS
-			if [ $i -gt "$TEST_REPEAT" ]; then
-				break
-			fi
-			echo "Repeating test ($i)"
-		done
+		flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS"
+		cd integration-cli
+		echo "Running $PWD"
+		test_env ./test.main $flags
 	)
 }
 
-ensure_test_dir() {
-	(
-		# make sure a test dir will compile
-		dir="$1"
-		out="$2"
-		echo Building test dir: "$dir"
-		set -xe
-		cd "$dir"
-		go test -c -o "$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}"
-	)
+build_test_suite_binaries() {
+	if [ ${DOCKER_INTEGRATION_TESTS_VERIFIED-} ]; then
+		echo "Skipping building test binaries; as DOCKER_INTEGRATION_TESTS_VERIFIED is set"
+		return
+	fi
+	build_test_suite_binary ./integration-cli "test.main"
+	for dir in $integration_api_dirs; do
+		build_test_suite_binary "$dir" "test.main"
+	done
 }
 
+# Build a binary for a test suite package
+build_test_suite_binary() {
+	local dir="$1"
+	local out="$2"
+	echo Building test suite binary "$dir/$out"
+	go test -c -o "$dir/$out" -ldflags "$LDFLAGS" "${BUILDFLAGS[@]}" "$dir"
+}
+
+cleanup_test_suite_binaries() {
+	[ -n "$TESTDEBUG" ] && return
+	echo "Removing test suite binaries"
+	find integration* -name test.main | xargs -r rm
+}
+
+repeat() {
+	for i in $(seq 1 $TEST_REPEAT); do
+		echo "Running integration-test (iteration $i)"
+		$@
+	done
+}
+
+# use "env -i" to tightly control the environment variables that bleed into the tests
 test_env() {
 	(
-		set -xe
-		# use "env -i" to tightly control the environment variables that bleed into the tests
+		set -e
+		[ -n "$TESTDEBUG" ] && set -x
 		env -i \
-			DEST="$DEST" \
-			DOCKER_CLI_VERSION="$DOCKER_CLI_VERSION" \
+			DEST="$ABS_DEST" \
 			DOCKER_API_VERSION="$DOCKER_API_VERSION" \
 			DOCKER_INTEGRATION_DAEMON_DEST="$DOCKER_INTEGRATION_DAEMON_DEST" \
 			DOCKER_TLS_VERIFY="$DOCKER_TEST_TLS_VERIFY" \
@@ -82,3 +102,19 @@
 			"$@"
 	)
 }
+   
+
+error_on_leaked_containerd_shims() {
+	if [ "$(go env GOOS)" == 'windows' ]; then
+		return
+	fi
+
+	leftovers=$(ps -ax -o pid,cmd |
+	            awk '$2 == "docker-containerd-shim" && $4 ~ /.*\/bundles\/.*\/test-integration/ { print $1 }')
+	if [ -n "$leftovers" ]; then
+		ps aux
+		kill -9 $leftovers 2> /dev/null
+		echo "!!!! WARNING you have left over shim(s), Cleanup your test !!!!"
+		exit 1
+	fi
+}
diff --git a/hack/make/build-integration-test-binary b/hack/make/build-integration-test-binary
old mode 100644
new mode 100755
index a842e8c..ad3e8c2
--- a/hack/make/build-integration-test-binary
+++ b/hack/make/build-integration-test-binary
@@ -1,13 +1,8 @@
 #!/usr/bin/env bash
+# required by `make build-integration-cli-on-swarm`
 set -e
 
-rm -rf "$DEST"
-DEST="$ABS_DEST/../test-integration-cli"
+source "${MAKEDIR}/.go-autogen"
+source hack/make/.integration-test-helpers
 
-source "$SCRIPTDIR/make/.go-autogen"
-
-if [ -z $DOCKER_INTEGRATION_TESTS_VERIFIED ]; then
-	source ${MAKEDIR}/.integration-test-helpers
-	ensure_test_dir integration-cli "$DEST/test.main"
-	export DOCKER_INTEGRATION_TESTS_VERIFIED=1
-fi
+build_test_suite_binaries
diff --git a/hack/make/test-integration b/hack/make/test-integration
new file mode 100755
index 0000000..0100ac9
--- /dev/null
+++ b/hack/make/test-integration
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+set -e -o pipefail
+
+source "${MAKEDIR}/.go-autogen"
+source hack/make/.integration-test-helpers
+
+(
+	build_test_suite_binaries
+	bundle .integration-daemon-start
+	bundle .integration-daemon-setup
+
+	local testexit=0
+	( repeat run_test_integration ) || testexit=$?
+
+	# Always run cleanup, even if the subshell fails
+	bundle .integration-daemon-stop
+	cleanup_test_suite_binaries
+	error_on_leaked_containerd_shims
+
+	exit $testexit
+
+) 2>&1 | tee -a "$DEST/test.log"
diff --git a/hack/make/test-integration-cli b/hack/make/test-integration-cli
index 61e2f7a..4cc79d0 100755
--- a/hack/make/test-integration-cli
+++ b/hack/make/test-integration-cli
@@ -1,29 +1,6 @@
 #!/usr/bin/env bash
 set -e
+echo "WARNING: test-integration-cli is DEREPCATED. Use test-integration." >&2
 
-source "${MAKEDIR}/.go-autogen"
-source hack/make/.integration-test-helpers
-
-# subshell so that we can export PATH without breaking other things
-(
-	bundle .integration-daemon-start
-
-	bundle .integration-daemon-setup
-
-	bundle_test_integration_cli
-
-	bundle .integration-daemon-stop
-
-	if [ "$(go env GOOS)" != 'windows' ]
-	then
-		leftovers=$(ps -ax -o pid,cmd | awk '$2 == "docker-containerd-shim" && $4 ~ /.*\/bundles\/.*\/test-integration-cli/ { print $1 }')
-		if [ -n "$leftovers" ]
-		then
-			ps aux
-			kill -9 $leftovers 2> /dev/null
-			echo "!!!! WARNING you have left over shim(s), Cleanup your test !!!!"
-			exit 1
-		fi
-	fi
-
-) 2>&1 | tee -a "$DEST/test.log"
+# TODO: remove this and exit 1 once CI has changed to use test-integration
+bundle test-integration
diff --git a/hack/make/test-integration-shell b/hack/make/test-integration-shell
index 2201f5e..bcfa468 100644
--- a/hack/make/test-integration-shell
+++ b/hack/make/test-integration-shell
@@ -5,3 +5,5 @@
 
 export ABS_DEST
 bash +e
+
+bundle .integration-daemon-stop
diff --git a/hack/make/test-unit b/hack/make/test-unit
deleted file mode 100644
index d985a6e..0000000
--- a/hack/make/test-unit
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-echo "DEPRECATED: use hack/test/unit instead of hack/make.sh test-unit" >&2
-
-$SCRIPTDIR/test/unit 2>&1 | tee -a "$DEST/test.log"
diff --git a/hack/make/tgz b/hack/make/tgz
deleted file mode 100644
index 1fd37b6..0000000
--- a/hack/make/tgz
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env bash
-echo "tgz is deprecated"
diff --git a/hack/release.sh b/hack/release.sh
index 5d73630..04f15be 100755
--- a/hack/release.sh
+++ b/hack/release.sh
@@ -57,7 +57,7 @@
 	RELEASE_BUNDLES=(
 		test-unit
 		"${RELEASE_BUNDLES[@]}"
-		test-integration-cli
+		test-integration
 	)
 fi
 
diff --git a/hack/test/e2e-run.sh b/hack/test/e2e-run.sh
new file mode 100755
index 0000000..bfcc03f
--- /dev/null
+++ b/hack/test/e2e-run.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+set -e
+
+TESTFLAGS=${TESTFLAGS:-""}
+# Currently only DockerSuite and DockerNetworkSuite have been adapted for E2E testing
+TESTFLAGS_LEGACY=${TESTFLAGS_LEGACY:-""}
+TIMEOUT=${TIMEOUT:-60m}
+
+SCRIPTDIR="$(dirname ${BASH_SOURCE[0]})"
+
+export DOCKER_ENGINE_GOARCH=${DOCKER_ENGINE_GOARCH:-amd64}
+
+run_test_integration() {
+  run_test_integration_suites
+  run_test_integration_legacy_suites
+}
+
+run_test_integration_suites() {
+  local flags="-test.v -test.timeout=${TIMEOUT} $TESTFLAGS"
+  for dir in /tests/integration/*; do
+    if ! (
+      cd $dir
+      echo "Running $PWD"
+      ./test.main $flags
+    ); then exit 1; fi
+  done
+}
+
+run_test_integration_legacy_suites() {
+  (
+    flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS_LEGACY"
+    cd /tests/integration-cli
+    echo "Running $PWD"
+    ./test.main $flags
+  )
+}
+
+bash $SCRIPTDIR/ensure-emptyfs.sh
+
+echo "Run integration tests"
+run_test_integration
diff --git a/hack/test/unit b/hack/test/unit
index 0018e88..2b07089 100755
--- a/hack/test/unit
+++ b/hack/test/unit
@@ -16,7 +16,7 @@
 BUILDFLAGS=( -tags "netgo seccomp libdm_no_deferred_remove" )
 TESTDIRS="${TESTDIRS:-"./..."}"
 
-exclude_paths="/vendor/|/integration-cli"
+exclude_paths="/vendor/|/integration"
 if [ "$(go env GOHOSTOS)" = 'solaris' ]; then
 	exclude_paths="$exclude_paths|/daemon/graphdriver"
 fi
diff --git a/hack/validate/default b/hack/validate/default
index e243f43..8ec9788 100755
--- a/hack/validate/default
+++ b/hack/validate/default
@@ -6,13 +6,12 @@
 
 . $SCRIPTDIR/dco
 . $SCRIPTDIR/default-seccomp
-. $SCRIPTDIR/gofmt
-. $SCRIPTDIR/lint
+. $SCRIPTDIR/gometalinter
 . $SCRIPTDIR/pkg-imports
 . $SCRIPTDIR/swagger
 . $SCRIPTDIR/swagger-gen
 . $SCRIPTDIR/test-imports
 . $SCRIPTDIR/toml
-. $SCRIPTDIR/vet
 . $SCRIPTDIR/changelog-well-formed
 . $SCRIPTDIR/changelog-date-descending
+. $SCRIPTDIR/deprecate-integration-cli
diff --git a/hack/validate/deprecate-integration-cli b/hack/validate/deprecate-integration-cli
new file mode 100755
index 0000000..da6f831
--- /dev/null
+++ b/hack/validate/deprecate-integration-cli
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# Check that no new tests are being added to integration-cli
+
+export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source "${SCRIPTDIR}/.validate"
+
+new_tests=$(
+    validate_diff --diff-filter=ACMR --unified=0 -- 'integration-cli/*_cli_*.go' |
+    grep -E '^\+func (.*) Test' || true
+)
+
+if [ -z "$new_tests" ]; then
+	echo 'Congratulations!  No new tests added to integration-cli.'
+    exit
+fi
+
+echo "The following new tests were added to integration-cli:"
+echo
+echo "$new_tests"
+echo
+echo "integration-cli is deprecated. Please add an API integration test to"
+echo "./integration/COMPONENT/. See ./TESTING.md for more details."
+echo
+
+exit 1
diff --git a/hack/validate/gofmt b/hack/validate/gofmt
deleted file mode 100755
index 38027a9..0000000
--- a/hack/validate/gofmt
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-
-export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "${SCRIPTDIR}/.validate"
-
-IFS=$'\n'
-files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' |
-	grep -v '^vendor/' |
-	grep -v '\.pb\.go$' || true) )
-unset IFS
-
-badFiles=()
-for f in "${files[@]}"; do
-	# we use "git show" here to validate that what's committed is formatted
-	if [ "$(git show "$VALIDATE_HEAD:$f" | gofmt -s -l)" ]; then
-		badFiles+=( "$f" )
-	fi
-done
-
-if [ ${#badFiles[@]} -eq 0 ]; then
-	echo 'Congratulations!  All Go source files are properly formatted.'
-else
-	{
-		echo "These files are not properly gofmt'd:"
-		for f in "${badFiles[@]}"; do
-			echo " - $f"
-		done
-		echo
-		echo 'Please reformat the above files using "gofmt -s -w" and commit the result.'
-		echo
-	} >&2
-	false
-fi
diff --git a/hack/validate/gometalinter b/hack/validate/gometalinter
new file mode 100755
index 0000000..ae411e8
--- /dev/null
+++ b/hack/validate/gometalinter
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+set -e -o pipefail
+
+SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+# CI platforms differ, so per-platform GOMETALINTER_OPTS can be set
+# from a platform-specific Dockerfile, otherwise let's just set
+# (somewhat pessimistic) default of 10 minutes.
+gometalinter \
+	${GOMETALINTER_OPTS:--deadine 10m} \
+	--config $SCRIPTDIR/gometalinter.json ./...
diff --git a/hack/validate/gometalinter.json b/hack/validate/gometalinter.json
new file mode 100644
index 0000000..8e8da10
--- /dev/null
+++ b/hack/validate/gometalinter.json
@@ -0,0 +1,26 @@
+{
+  "Vendor": true,
+  "EnableGC": true,
+  "Sort": ["linter", "severity", "path"],
+  "Exclude": [
+    ".*\\.pb\\.go",
+    "dockerversion/version_autogen.go",
+    "api/types/container/container_.*",
+    "integration-cli/"
+  ],
+  "Skip": ["integration-cli/"],
+
+  "Enable": [
+    "deadcode",
+    "gofmt",
+    "goimports",
+    "golint",
+    "gosimple",
+    "ineffassign",
+    "interfacer",
+    "unconvert",
+    "vet"
+  ],
+
+  "LineLength": 200
+}
diff --git a/hack/validate/lint b/hack/validate/lint
deleted file mode 100755
index 341490a..0000000
--- a/hack/validate/lint
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-
-export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "${SCRIPTDIR}/.validate"
-
-IFS=$'\n'
-files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^vendor/' | grep -v '^api/types/container/' | grep -v '\.pb\.go$'  || true) )
-unset IFS
-
-errors=()
-for f in "${files[@]}"; do
-	failedLint=$(golint "$f")
-	if [ "$failedLint" ]; then
-		errors+=( "$failedLint" )
-	fi
-done
-
-if [ ${#errors[@]} -eq 0 ]; then
-	echo 'Congratulations!  All Go source files have been linted.'
-else
-	{
-		echo "Errors from golint:"
-		for err in "${errors[@]}"; do
-			echo "$err"
-		done
-		echo
-		echo 'Please fix the above errors. You can test via "golint" and commit the result.'
-		echo
-	} >&2
-	false
-fi
diff --git a/hack/validate/vet b/hack/validate/vet
deleted file mode 100755
index 95dc7a7..0000000
--- a/hack/validate/vet
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env bash
-
-export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "${SCRIPTDIR}/.validate"
-
-IFS=$'\n'
-files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^vendor/' | grep -v '^api/types/container/' || true) )
-unset IFS
-
-errors=()
-for f in "${files[@]}"; do
-	failedVet=$(go vet "$f")
-	if [ "$failedVet" ]; then
-		errors+=( "$failedVet" )
-	fi
-done
-
-
-if [ ${#errors[@]} -eq 0 ]; then
-	echo 'Congratulations!  All Go source files have been vetted.'
-else
-	{
-		echo "Errors from go vet:"
-		for err in "${errors[@]}"; do
-			echo " - $err"
-		done
-		echo
-		echo 'Please fix the above errors. You can test via "go vet" and commit the result.'
-		echo
-	} >&2
-	false
-fi
diff --git a/image/fs.go b/image/fs.go
index 10f6dab..92cdb26 100644
--- a/image/fs.go
+++ b/image/fs.go
@@ -7,10 +7,10 @@
 	"path/filepath"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // DigestWalkFunc is function called by StoreBackend.Walk
diff --git a/image/fs_test.go b/image/fs_test.go
index 5f2437c..2672524 100644
--- a/image/fs_test.go
+++ b/image/fs_test.go
@@ -1,7 +1,6 @@
 package image
 
 import (
-	"bytes"
 	"crypto/rand"
 	"crypto/sha256"
 	"encoding/hex"
@@ -11,8 +10,8 @@
 	"path/filepath"
 	"testing"
 
-	"github.com/docker/docker/pkg/testutil"
-	"github.com/opencontainers/go-digest"
+	"github.com/docker/docker/internal/testutil"
+	digest "github.com/opencontainers/go-digest"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -112,9 +111,7 @@
 		actual, err := store.GetMetadata(tc.id, tc.key)
 		assert.NoError(t, err)
 
-		if bytes.Compare(actual, tc.value) != 0 {
-			t.Fatalf("Metadata expected %q, got %q", tc.value, actual)
-		}
+		assert.Equal(t, tc.value, actual)
 	}
 
 	_, err = store.GetMetadata(id2, "tkey2")
@@ -183,9 +180,7 @@
 	for _, tc := range tcases {
 		data, err := store.Get(tc.expected)
 		assert.NoError(t, err)
-		if bytes.Compare(data, tc.input) != 0 {
-			t.Fatalf("expected data %q, got %q", tc.input, data)
-		}
+		assert.Equal(t, tc.input, data)
 	}
 }
 
diff --git a/image/image_test.go b/image/image_test.go
index e04587e..899666a 100644
--- a/image/image_test.go
+++ b/image/image_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"encoding/json"
+	"runtime"
 	"sort"
 	"strings"
 	"testing"
@@ -54,6 +55,39 @@
 	}
 }
 
+func TestImage(t *testing.T) {
+	cid := "50a16564e727"
+	config := &container.Config{
+		Hostname:   "hostname",
+		Domainname: "domain",
+		User:       "root",
+	}
+	platform := runtime.GOOS
+
+	img := &Image{
+		V1Image: V1Image{
+			Config: config,
+		},
+		computedID: ID(cid),
+	}
+
+	assert.Equal(t, cid, img.ImageID())
+	assert.Equal(t, cid, img.ID().String())
+	assert.Equal(t, platform, img.Platform())
+	assert.Equal(t, config, img.RunConfig())
+}
+
+func TestImagePlatformNotEmpty(t *testing.T) {
+	platform := "platform"
+	img := &Image{
+		V1Image: V1Image{
+			OS: platform,
+		},
+		OSVersion: "osversion",
+	}
+	assert.Equal(t, platform, img.Platform())
+}
+
 func TestNewChildImageFromImageWithRootFS(t *testing.T) {
 	rootFS := NewRootFS()
 	rootFS.Append(layer.DiffID("ba5e"))
diff --git a/image/rootfs.go b/image/rootfs.go
index 5a9020f..fb5f674 100644
--- a/image/rootfs.go
+++ b/image/rootfs.go
@@ -3,8 +3,8 @@
 import (
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/layer"
+	"github.com/sirupsen/logrus"
 )
 
 // TypeLayers is used for RootFS.Type for filesystems organized into layers.
diff --git a/image/store.go b/image/store.go
index c85f8d6..17769f4 100644
--- a/image/store.go
+++ b/image/store.go
@@ -7,12 +7,12 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/digestset"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/system"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // Store is an interface for creating and accessing images
@@ -180,13 +180,21 @@
 	return imageID, nil
 }
 
+type imageNotFoundError string
+
+func (e imageNotFoundError) Error() string {
+	return "No such image: " + string(e)
+}
+
+func (imageNotFoundError) NotFound() {}
+
 func (is *store) Search(term string) (ID, error) {
 	dgst, err := is.digestSet.Lookup(term)
 	if err != nil {
 		if err == digestset.ErrDigestNotFound {
-			err = fmt.Errorf("No such image: %s", term)
+			err = imageNotFoundError(term)
 		}
-		return "", err
+		return "", errors.WithStack(err)
 	}
 	return IDFromDigest(dgst), nil
 }
diff --git a/image/store_test.go b/image/store_test.go
index fc6d461..23a60a9 100644
--- a/image/store_test.go
+++ b/image/store_test.go
@@ -4,8 +4,8 @@
 	"runtime"
 	"testing"
 
+	"github.com/docker/docker/internal/testutil"
 	"github.com/docker/docker/layer"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/opencontainers/go-digest"
 	"github.com/stretchr/testify/assert"
 )
@@ -41,10 +41,10 @@
 	assert.Equal(t, "abc", img1.Comment)
 	assert.Equal(t, "def", img2.Comment)
 
-	p, err := is.GetParent(ID(id1))
+	_, err = is.GetParent(ID(id1))
 	testutil.ErrorContains(t, err, "failed to read metadata")
 
-	p, err = is.GetParent(ID(id2))
+	p, err := is.GetParent(ID(id2))
 	assert.NoError(t, err)
 	assert.Equal(t, ID(id1), p)
 
diff --git a/image/tarexport/load.go b/image/tarexport/load.go
index af8cefc..8bb1ac1 100644
--- a/image/tarexport/load.go
+++ b/image/tarexport/load.go
@@ -11,7 +11,6 @@
 	"reflect"
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/image"
@@ -24,7 +23,8 @@
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/symlink"
 	"github.com/docker/docker/pkg/system"
-	"github.com/opencontainers/go-digest"
+	digest "github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 )
 
 func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
@@ -82,8 +82,7 @@
 		if err := checkCompatibleOS(img.OS); err != nil {
 			return err
 		}
-		var rootFS image.RootFS
-		rootFS = *img.RootFS
+		rootFS := *img.RootFS
 		rootFS.DiffIDs = nil
 
 		if expected, actual := len(m.Layers), len(img.RootFS.DiffIDs); expected != actual {
@@ -212,15 +211,12 @@
 	return l.ls.Register(inflatedLayerData, rootFS.ChainID(), platform)
 }
 
-func (l *tarexporter) setLoadedTag(ref reference.NamedTagged, imgID digest.Digest, outStream io.Writer) error {
+func (l *tarexporter) setLoadedTag(ref reference.Named, imgID digest.Digest, outStream io.Writer) error {
 	if prevID, err := l.rs.Get(ref); err == nil && prevID != imgID {
 		fmt.Fprintf(outStream, "The image %s already exists, renaming the old one with ID %s to empty string\n", reference.FamiliarString(ref), string(prevID)) // todo: this message is wrong in case of multiple tags
 	}
 
-	if err := l.rs.AddTag(ref, imgID, true); err != nil {
-		return err
-	}
-	return nil
+	return l.rs.AddTag(ref, imgID, true)
 }
 
 func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer, progressOutput progress.Output) error {
diff --git a/image/v1/imagev1.go b/image/v1/imagev1.go
index 0e8a23c..697d59e 100644
--- a/image/v1/imagev1.go
+++ b/image/v1/imagev1.go
@@ -5,12 +5,12 @@
 	"reflect"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 )
 
 // noFallbackMinVersion is the minimum version for which v1compatibility
diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go
index f05b650..2e57e00 100644
--- a/integration-cli/check_test.go
+++ b/integration-cli/check_test.go
@@ -2,12 +2,12 @@
 
 import (
 	"fmt"
+	"io/ioutil"
 	"net/http/httptest"
 	"os"
-	"os/exec"
 	"path"
 	"path/filepath"
-	"strings"
+	"strconv"
 	"sync"
 	"syscall"
 	"testing"
@@ -22,6 +22,7 @@
 	"github.com/docker/docker/integration-cli/environment"
 	"github.com/docker/docker/integration-cli/fixtures/plugin"
 	"github.com/docker/docker/integration-cli/registry"
+	ienv "github.com/docker/docker/internal/test/environment"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/go-check/check"
 	"golang.org/x/net/context"
@@ -59,30 +60,14 @@
 
 func TestMain(m *testing.M) {
 	dockerBinary = testEnv.DockerBinary()
-
-	if testEnv.LocalDaemon() {
-		fmt.Println("INFO: Testing against a local daemon")
-	} else {
-		fmt.Println("INFO: Testing against a remote daemon")
-	}
-	exitCode := m.Run()
-	os.Exit(exitCode)
+	testEnv.Print()
+	os.Exit(m.Run())
 }
 
 func Test(t *testing.T) {
-	cli.EnsureTestEnvIsLoaded(t)
-	fakestorage.EnsureTestEnvIsLoaded(t)
-	cmd := exec.Command(dockerBinary, "images", "-f", "dangling=false", "--format", "{{.Repository}}:{{.Tag}}")
-	cmd.Env = appendBaseEnv(true)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		panic(fmt.Errorf("err=%v\nout=%s\n", err, out))
-	}
-	images := strings.Split(strings.TrimSpace(string(out)), "\n")
-	testEnv.ProtectImage(t, images...)
-	if testEnv.DaemonPlatform() == "linux" {
-		ensureFrozenImagesLinux(t)
-	}
+	cli.SetTestEnvironment(testEnv)
+	fakestorage.SetTestEnvironment(&testEnv.Execution)
+	ienv.ProtectAll(t, &testEnv.Execution)
 	check.TestingT(t)
 }
 
@@ -94,13 +79,28 @@
 }
 
 func (s *DockerSuite) OnTimeout(c *check.C) {
-	if testEnv.DaemonPID() > 0 && testEnv.LocalDaemon() {
-		daemon.SignalDaemonDump(testEnv.DaemonPID())
+	if !testEnv.IsLocalDaemon() {
+		return
+	}
+	path := filepath.Join(os.Getenv("DEST"), "docker.pid")
+	b, err := ioutil.ReadFile(path)
+	if err != nil {
+		c.Fatalf("Failed to get daemon PID from %s\n", path)
+	}
+
+	rawPid, err := strconv.ParseInt(string(b), 10, 32)
+	if err != nil {
+		c.Fatalf("Failed to parse pid from %s: %s\n", path, err)
+	}
+
+	daemonPid := int(rawPid)
+	if daemonPid > 0 {
+		daemon.SignalDaemonDump(daemonPid)
 	}
 }
 
 func (s *DockerSuite) TearDownTest(c *check.C) {
-	testEnv.Clean(c, dockerBinary)
+	testEnv.Clean(c)
 }
 
 func init() {
@@ -120,7 +120,7 @@
 }
 
 func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
-	testRequires(c, DaemonIsLinux, registry.Hosting)
+	testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
 	s.reg = setupRegistry(c, false, "", "")
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
@@ -154,7 +154,7 @@
 }
 
 func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
-	testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64)
+	testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64, SameHostDaemon)
 	s.reg = setupRegistry(c, true, "", "")
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
@@ -188,7 +188,7 @@
 }
 
 func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
-	testRequires(c, DaemonIsLinux, registry.Hosting)
+	testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
 	s.reg = setupRegistry(c, false, "htpasswd", "")
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
@@ -224,7 +224,7 @@
 }
 
 func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
-	testRequires(c, DaemonIsLinux, registry.Hosting)
+	testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
 	})
@@ -319,7 +319,7 @@
 }
 
 func (s *DockerSwarmSuite) SetUpTest(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
 }
 
 func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Swarm {
@@ -471,7 +471,7 @@
 }
 
 func (ps *DockerPluginSuite) SetUpSuite(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, registry.Hosting)
 	ps.registry = setupRegistry(c, false, "", "")
 
 	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
diff --git a/integration-cli/cli/build/build.go b/integration-cli/cli/build/build.go
index 8ffaa35..da55df3 100644
--- a/integration-cli/cli/build/build.go
+++ b/integration-cli/cli/build/build.go
@@ -5,7 +5,7 @@
 	"strings"
 
 	"github.com/docker/docker/integration-cli/cli/build/fakecontext"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 type testingT interface {
diff --git a/integration-cli/cli/build/fakegit/fakegit.go b/integration-cli/cli/build/fakegit/fakegit.go
index 74faffd..ad028dc 100644
--- a/integration-cli/cli/build/fakegit/fakegit.go
+++ b/integration-cli/cli/build/fakegit/fakegit.go
@@ -11,9 +11,11 @@
 
 	"github.com/docker/docker/integration-cli/cli/build/fakecontext"
 	"github.com/docker/docker/integration-cli/cli/build/fakestorage"
+	"github.com/stretchr/testify/require"
 )
 
 type testingT interface {
+	require.TestingT
 	logT
 	Fatal(args ...interface{})
 	Fatalf(string, ...interface{})
diff --git a/integration-cli/cli/build/fakestorage/fixtures.go b/integration-cli/cli/build/fakestorage/fixtures.go
index f6a63dc..2eb7284 100644
--- a/integration-cli/cli/build/fakestorage/fixtures.go
+++ b/integration-cli/cli/build/fakestorage/fixtures.go
@@ -30,7 +30,7 @@
 	}
 	defer os.RemoveAll(tmp)
 
-	goos := testEnv.DaemonPlatform()
+	goos := testEnv.OSType
 	if goos == "" {
 		goos = "linux"
 	}
@@ -39,27 +39,34 @@
 		goarch = "amd64"
 	}
 
-	goCmd, lookErr := exec.LookPath("go")
-	if lookErr != nil {
-		t.Fatalf("could not build http server: %v", lookErr)
-	}
-
-	cmd := exec.Command(goCmd, "build", "-o", filepath.Join(tmp, "httpserver"), "github.com/docker/docker/contrib/httpserver")
-	cmd.Env = append(os.Environ(), []string{
-		"CGO_ENABLED=0",
-		"GOOS=" + goos,
-		"GOARCH=" + goarch,
-	}...)
-	var out []byte
-	if out, err = cmd.CombinedOutput(); err != nil {
-		t.Fatalf("could not build http server: %s", string(out))
-	}
-
 	cpCmd, lookErr := exec.LookPath("cp")
 	if lookErr != nil {
 		t.Fatalf("could not build http server: %v", lookErr)
 	}
-	if out, err = exec.Command(cpCmd, "../contrib/httpserver/Dockerfile", filepath.Join(tmp, "Dockerfile")).CombinedOutput(); err != nil {
+
+	if _, err = os.Stat("../contrib/httpserver/httpserver"); os.IsNotExist(err) {
+		goCmd, lookErr := exec.LookPath("go")
+		if lookErr != nil {
+			t.Fatalf("could not build http server: %v", lookErr)
+		}
+
+		cmd := exec.Command(goCmd, "build", "-o", filepath.Join(tmp, "httpserver"), "github.com/docker/docker/contrib/httpserver")
+		cmd.Env = append(os.Environ(), []string{
+			"CGO_ENABLED=0",
+			"GOOS=" + goos,
+			"GOARCH=" + goarch,
+		}...)
+		var out []byte
+		if out, err = cmd.CombinedOutput(); err != nil {
+			t.Fatalf("could not build http server: %s", string(out))
+		}
+	} else {
+		if out, err := exec.Command(cpCmd, "../contrib/httpserver/httpserver", filepath.Join(tmp, "httpserver")).CombinedOutput(); err != nil {
+			t.Fatalf("could not copy http server: %v", string(out))
+		}
+	}
+
+	if out, err := exec.Command(cpCmd, "../contrib/httpserver/Dockerfile", filepath.Join(tmp, "Dockerfile")).CombinedOutput(); err != nil {
 		t.Fatalf("could not build http server: %v", string(out))
 	}
 
diff --git a/integration-cli/cli/build/fakestorage/storage.go b/integration-cli/cli/build/fakestorage/storage.go
index 49f47e4..25cd872 100644
--- a/integration-cli/cli/build/fakestorage/storage.go
+++ b/integration-cli/cli/build/fakestorage/storage.go
@@ -8,39 +8,20 @@
 	"net/url"
 	"os"
 	"strings"
-	"sync"
 
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build/fakecontext"
-	"github.com/docker/docker/integration-cli/environment"
 	"github.com/docker/docker/integration-cli/request"
+	"github.com/docker/docker/internal/test/environment"
 	"github.com/docker/docker/pkg/stringutils"
+	"github.com/stretchr/testify/require"
 )
 
-var (
-	testEnv  *environment.Execution
-	onlyOnce sync.Once
-)
-
-// EnsureTestEnvIsLoaded make sure the test environment is loaded for this package
-func EnsureTestEnvIsLoaded(t testingT) {
-	var doIt bool
-	var err error
-	onlyOnce.Do(func() {
-		doIt = true
-	})
-
-	if !doIt {
-		return
-	}
-	testEnv, err = environment.New()
-	if err != nil {
-		t.Fatalf("error loading testenv : %v", err)
-	}
-}
+var testEnv *environment.Execution
 
 type testingT interface {
+	require.TestingT
 	logT
 	Fatal(args ...interface{})
 	Fatalf(string, ...interface{})
@@ -58,11 +39,20 @@
 	CtxDir() string
 }
 
+// SetTestEnvironment sets a static test environment
+// TODO: decouple this package from environment
+func SetTestEnvironment(env *environment.Execution) {
+	testEnv = env
+}
+
 // New returns a static file server that will be use as build context.
 func New(t testingT, dir string, modifiers ...func(*fakecontext.Fake) error) Fake {
+	if testEnv == nil {
+		t.Fatal("fakstorage package requires SetTestEnvironment() to be called before use.")
+	}
 	ctx := fakecontext.New(t, dir, modifiers...)
-	if testEnv.LocalDaemon() {
-		return newLocalFakeStorage(t, ctx)
+	if testEnv.IsLocalDaemon() {
+		return newLocalFakeStorage(ctx)
 	}
 	return newRemoteFileServer(t, ctx)
 }
@@ -86,7 +76,7 @@
 	return s.Fake.Close()
 }
 
-func newLocalFakeStorage(t testingT, ctx *fakecontext.Fake) *localFileStorage {
+func newLocalFakeStorage(ctx *fakecontext.Fake) *localFileStorage {
 	handler := http.FileServer(http.Dir(ctx.Dir))
 	server := httptest.NewServer(handler)
 	return &localFileStorage{
diff --git a/integration-cli/cli/cli.go b/integration-cli/cli/cli.go
index d835521..813c3ad 100644
--- a/integration-cli/cli/cli.go
+++ b/integration-cli/cli/cli.go
@@ -4,35 +4,20 @@
 	"fmt"
 	"io"
 	"strings"
-	"sync"
 	"time"
 
 	"github.com/docker/docker/integration-cli/daemon"
 	"github.com/docker/docker/integration-cli/environment"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/pkg/errors"
 )
 
-var (
-	testEnv  *environment.Execution
-	onlyOnce sync.Once
-)
+var testEnv *environment.Execution
 
-// EnsureTestEnvIsLoaded make sure the test environment is loaded for this package
-func EnsureTestEnvIsLoaded(t testingT) {
-	var doIt bool
-	var err error
-	onlyOnce.Do(func() {
-		doIt = true
-	})
-
-	if !doIt {
-		return
-	}
-	testEnv, err = environment.New()
-	if err != nil {
-		t.Fatalf("error loading testenv : %v", err)
-	}
+// SetTestEnvironment sets a static test environment
+// TODO: decouple this package from environment
+func SetTestEnvironment(env *environment.Execution) {
+	testEnv = env
 }
 
 // CmdOperator defines functions that can modify a command
@@ -130,7 +115,7 @@
 // validateArgs is a checker to ensure tests are not running commands which are
 // not supported on platforms. Specifically on Windows this is 'busybox top'.
 func validateArgs(args ...string) error {
-	if testEnv.DaemonPlatform() != "windows" {
+	if testEnv.OSType != "windows" {
 		return nil
 	}
 	foundBusybox := -1
@@ -229,3 +214,11 @@
 		return nil
 	}
 }
+
+// WithStdin sets the standard input reader for the command
+func WithStdin(stdin io.Reader) func(*icmd.Cmd) func() {
+	return func(cmd *icmd.Cmd) func() {
+		cmd.Stdin = stdin
+		return nil
+	}
+}
diff --git a/integration-cli/daemon/daemon.go b/integration-cli/daemon/daemon.go
index 8b086c9..06bf504 100644
--- a/integration-cli/daemon/daemon.go
+++ b/integration-cli/daemon/daemon.go
@@ -14,21 +14,26 @@
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api"
+	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/events"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/docker/go-connections/sockets"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/pkg/errors"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/net/context"
 )
 
 type testingT interface {
+	require.TestingT
 	logT
 	Fatalf(string, ...interface{})
 }
@@ -325,9 +330,7 @@
 // then save the busybox image from the main daemon and load it into this Daemon instance.
 func (d *Daemon) StartWithBusybox(t testingT, arg ...string) {
 	d.Start(t, arg...)
-	if err := d.LoadBusybox(); err != nil {
-		t.Fatalf("Error loading busybox image to current daemon: %s\n%v", d.id, err)
-	}
+	d.LoadBusybox(t)
 }
 
 // Kill will send a SIGKILL to the daemon
@@ -489,27 +492,24 @@
 	}
 }
 
-// LoadBusybox will load the stored busybox into a newly started daemon
-func (d *Daemon) LoadBusybox() error {
-	bb := filepath.Join(d.Folder, "busybox.tar")
-	if _, err := os.Stat(bb); err != nil {
-		if !os.IsNotExist(err) {
-			return errors.Errorf("unexpected error on busybox.tar stat: %v", err)
-		}
-		// saving busybox image from main daemon
-		if out, err := exec.Command(d.dockerBinary, "save", "--output", bb, "busybox:latest").CombinedOutput(); err != nil {
-			imagesOut, _ := exec.Command(d.dockerBinary, "images", "--format", "{{ .Repository }}:{{ .Tag }}").CombinedOutput()
-			return errors.Errorf("could not save busybox image: %s\n%s", string(out), strings.TrimSpace(string(imagesOut)))
-		}
-	}
-	// loading busybox image to this daemon
-	if out, err := d.Cmd("load", "--input", bb); err != nil {
-		return errors.Errorf("could not load busybox image: %s", out)
-	}
-	if err := os.Remove(bb); err != nil {
-		return err
-	}
-	return nil
+// LoadBusybox image into the daemon
+func (d *Daemon) LoadBusybox(t testingT) {
+	clientHost, err := client.NewEnvClient()
+	require.NoError(t, err, "failed to create client")
+	defer clientHost.Close()
+
+	ctx := context.Background()
+	reader, err := clientHost.ImageSave(ctx, []string{"busybox:latest"})
+	require.NoError(t, err, "failed to download busybox")
+	defer reader.Close()
+
+	client, err := d.NewClient()
+	require.NoError(t, err, "failed to create client")
+	defer client.Close()
+
+	resp, err := client.ImageLoad(ctx, reader, true)
+	require.NoError(t, err, "failed to load busybox")
+	defer resp.Body.Close()
 }
 
 func (d *Daemon) queryRootDir() (string, error) {
@@ -545,7 +545,7 @@
 	}
 	var b []byte
 	var i Info
-	b, err = testutil.ReadBody(body)
+	b, err = request.ReadBody(body)
 	if err == nil && resp.StatusCode == http.StatusOK {
 		// read the docker root dir
 		if err = json.Unmarshal(b, &i); err == nil {
@@ -570,20 +570,13 @@
 	return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...)
 }
 
-// GetBaseDeviceSize returns the base device size of the daemon
-func (d *Daemon) GetBaseDeviceSize(c *check.C) int64 {
-	infoCmdOutput, _, err := testutil.RunCommandPipelineWithOutput(
-		exec.Command(d.dockerBinary, "-H", d.Sock(), "info"),
-		exec.Command("grep", "Base Device Size"),
-	)
-	c.Assert(err, checker.IsNil)
-	basesizeSlice := strings.Split(infoCmdOutput, ":")
-	basesize := strings.Trim(basesizeSlice[1], " ")
-	basesize = strings.Trim(basesize, "\n")[:len(basesize)-3]
-	basesizeFloat, err := strconv.ParseFloat(strings.Trim(basesize, " "), 64)
-	c.Assert(err, checker.IsNil)
-	basesizeBytes := int64(basesizeFloat) * (1024 * 1024 * 1024)
-	return basesizeBytes
+// Info returns the info struct for this daemon
+func (d *Daemon) Info(t require.TestingT) types.Info {
+	apiclient, err := request.NewClientForHost(d.Sock())
+	require.NoError(t, err)
+	info, err := apiclient.Info(context.Background())
+	require.NoError(t, err)
+	return info
 }
 
 // Cmd executes a docker CLI command against this daemon.
@@ -620,7 +613,7 @@
 	if err != nil {
 		return -1, nil, err
 	}
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	return res.StatusCode, b, err
 }
 
@@ -757,6 +750,16 @@
 	return nil
 }
 
+// NewClient creates new client based on daemon's socket path
+func (d *Daemon) NewClient() (*client.Client, error) {
+	httpClient, err := request.NewHTTPClient(d.Sock())
+	if err != nil {
+		return nil, err
+	}
+
+	return client.NewClient(d.Sock(), api.DefaultVersion, httpClient, nil)
+}
+
 // WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time.
 // Deprecated: use cli.WaitCmd instead
 func WaitInspectWithArgs(dockerBinary, name, expr, expected string, timeout time.Duration, arg ...string) error {
diff --git a/integration-cli/daemon/daemon_swarm.go b/integration-cli/daemon/daemon_swarm.go
index ba41406..c37c726 100644
--- a/integration-cli/daemon/daemon_swarm.go
+++ b/integration-cli/daemon/daemon_swarm.go
@@ -1,7 +1,6 @@
 package daemon
 
 import (
-	"context"
 	"encoding/json"
 	"fmt"
 	"net/http"
@@ -11,10 +10,10 @@
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/swarm"
-	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
 	"github.com/pkg/errors"
+	"golang.org/x/net/context"
 )
 
 // Swarm is a test daemon with helpers for participating in a swarm.
@@ -30,10 +29,12 @@
 	if req.ListenAddr == "" {
 		req.ListenAddr = d.ListenAddr
 	}
-	status, out, err := d.SockRequest("POST", "/swarm/init", req)
-	if status != http.StatusOK {
-		return fmt.Errorf("initializing swarm: invalid statuscode %v, %q", status, out)
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("initializing swarm: failed to create client %v", err)
 	}
+	defer cli.Close()
+	_, err = cli.SwarmInit(context.Background(), req)
 	if err != nil {
 		return fmt.Errorf("initializing swarm: %v", err)
 	}
@@ -50,10 +51,12 @@
 	if req.ListenAddr == "" {
 		req.ListenAddr = d.ListenAddr
 	}
-	status, out, err := d.SockRequest("POST", "/swarm/join", req)
-	if status != http.StatusOK {
-		return fmt.Errorf("joining swarm: invalid statuscode %v, %q", status, out)
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("joining swarm: failed to create client %v", err)
 	}
+	defer cli.Close()
+	err = cli.SwarmJoin(context.Background(), req)
 	if err != nil {
 		return fmt.Errorf("joining swarm: %v", err)
 	}
@@ -67,14 +70,12 @@
 
 // Leave forces daemon to leave current cluster.
 func (d *Swarm) Leave(force bool) error {
-	url := "/swarm/leave"
-	if force {
-		url += "?force=1"
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("leaving swarm: failed to create client %v", err)
 	}
-	status, out, err := d.SockRequest("POST", url, nil)
-	if status != http.StatusOK {
-		return fmt.Errorf("leaving swarm: invalid statuscode %v, %q", status, out)
-	}
+	defer cli.Close()
+	err = cli.SwarmLeave(context.Background(), force)
 	if err != nil {
 		err = fmt.Errorf("leaving swarm: %v", err)
 	}
@@ -83,28 +84,27 @@
 
 // SwarmInfo returns the swarm information of the daemon
 func (d *Swarm) SwarmInfo() (swarm.Info, error) {
-	var info struct {
-		Swarm swarm.Info
-	}
-	status, dt, err := d.SockRequest("GET", "/info", nil)
-	if status != http.StatusOK {
-		return info.Swarm, fmt.Errorf("get swarm info: invalid statuscode %v", status)
-	}
+	cli, err := d.NewClient()
 	if err != nil {
-		return info.Swarm, fmt.Errorf("get swarm info: %v", err)
+		return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
 	}
-	if err := json.Unmarshal(dt, &info); err != nil {
-		return info.Swarm, err
+
+	info, err := cli.Info(context.Background())
+	if err != nil {
+		return swarm.Info{}, fmt.Errorf("get swarm info: %v", err)
 	}
+
 	return info.Swarm, nil
 }
 
 // Unlock tries to unlock a locked swarm
 func (d *Swarm) Unlock(req swarm.UnlockRequest) error {
-	status, out, err := d.SockRequest("POST", "/swarm/unlock", req)
-	if status != http.StatusOK {
-		return fmt.Errorf("unlocking swarm: invalid statuscode %v, %q", status, out)
+	cli, err := d.NewClient()
+	if err != nil {
+		return fmt.Errorf("unlocking swarm: failed to create client %v", err)
 	}
+	defer cli.Close()
+	err = cli.SwarmUnlock(context.Background(), req)
 	if err != nil {
 		err = errors.Wrap(err, "unlocking swarm")
 	}
@@ -129,19 +129,19 @@
 // CreateServiceWithOptions creates a swarm service given the specified service constructors
 // and auth config
 func (d *Swarm) CreateServiceWithOptions(c *check.C, opts types.ServiceCreateOptions, f ...ServiceConstructor) string {
-	cl, err := client.NewClient(d.Sock(), "", nil, nil)
-	c.Assert(err, checker.IsNil, check.Commentf("failed to create client"))
-	defer cl.Close()
-
 	var service swarm.Service
 	for _, fn := range f {
 		fn(&service)
 	}
 
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
 	defer cancel()
 
-	res, err := cl.ServiceCreate(ctx, service.Spec, opts)
+	res, err := cli.ServiceCreate(ctx, service.Spec, opts)
 	c.Assert(err, checker.IsNil)
 	return res.ID
 }
@@ -153,28 +153,31 @@
 
 // GetService returns the swarm service corresponding to the specified id
 func (d *Swarm) GetService(c *check.C, id string) *swarm.Service {
-	var service swarm.Service
-	status, out, err := d.SockRequest("GET", "/services/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &service), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	service, _, err := cli.ServiceInspectWithRaw(context.Background(), id, types.ServiceInspectOptions{})
+	c.Assert(err, checker.IsNil)
 	return &service
 }
 
 // GetServiceTasks returns the swarm tasks for the specified service
 func (d *Swarm) GetServiceTasks(c *check.C, service string) []swarm.Task {
-	var tasks []swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	filterArgs := filters.NewArgs()
 	filterArgs.Add("desired-state", "running")
 	filterArgs.Add("service", service)
-	filters, err := filters.ToParam(filterArgs)
-	c.Assert(err, checker.IsNil)
 
-	status, out, err := d.SockRequest("GET", "/tasks?filters="+filters, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &tasks), checker.IsNil)
+	options := types.TaskListOptions{
+		Filters: filterArgs,
+	}
+
+	tasks, err := cli.TaskList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
 	return tasks
 }
 
@@ -252,17 +255,19 @@
 
 // CheckRunningTaskNetworks returns the number of times each network is referenced from a task.
 func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.CommentInterface) {
-	var tasks []swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	filterArgs := filters.NewArgs()
 	filterArgs.Add("desired-state", "running")
-	filters, err := filters.ToParam(filterArgs)
-	c.Assert(err, checker.IsNil)
 
-	status, out, err := d.SockRequest("GET", "/tasks?filters="+filters, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &tasks), checker.IsNil)
+	options := types.TaskListOptions{
+		Filters: filterArgs,
+	}
+
+	tasks, err := cli.TaskList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
 
 	result := make(map[string]int)
 	for _, task := range tasks {
@@ -275,17 +280,19 @@
 
 // CheckRunningTaskImages returns the times each image is running as a task.
 func (d *Swarm) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) {
-	var tasks []swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	filterArgs := filters.NewArgs()
 	filterArgs.Add("desired-state", "running")
-	filters, err := filters.ToParam(filterArgs)
-	c.Assert(err, checker.IsNil)
 
-	status, out, err := d.SockRequest("GET", "/tasks?filters="+filters, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &tasks), checker.IsNil)
+	options := types.TaskListOptions{
+		Filters: filterArgs,
+	}
+
+	tasks, err := cli.TaskList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
 
 	result := make(map[string]int)
 	for _, task := range tasks {
@@ -310,246 +317,281 @@
 
 // GetTask returns the swarm task identified by the specified id
 func (d *Swarm) GetTask(c *check.C, id string) swarm.Task {
-	var task swarm.Task
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	status, out, err := d.SockRequest("GET", "/tasks/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &task), checker.IsNil)
+	task, _, err := cli.TaskInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	return task
 }
 
 // UpdateService updates a swarm service with the specified service constructor
 func (d *Swarm) UpdateService(c *check.C, service *swarm.Service, f ...ServiceConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	for _, fn := range f {
 		fn(service)
 	}
-	url := fmt.Sprintf("/services/%s/update?version=%d", service.ID, service.Version.Index)
-	status, out, err := d.SockRequest("POST", url, service.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	_, err = cli.ServiceUpdate(context.Background(), service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
+	c.Assert(err, checker.IsNil)
 }
 
 // RemoveService removes the specified service
 func (d *Swarm) RemoveService(c *check.C, id string) {
-	status, out, err := d.SockRequest("DELETE", "/services/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	err = cli.ServiceRemove(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 }
 
 // GetNode returns a swarm node identified by the specified id
 func (d *Swarm) GetNode(c *check.C, id string) *swarm.Node {
-	var node swarm.Node
-	status, out, err := d.SockRequest("GET", "/nodes/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &node), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	node, _, err := cli.NodeInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	c.Assert(node.ID, checker.Equals, id)
 	return &node
 }
 
 // RemoveNode removes the specified node
 func (d *Swarm) RemoveNode(c *check.C, id string, force bool) {
-	url := "/nodes/" + id
-	if force {
-		url += "?force=1"
-	}
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	status, out, err := d.SockRequest("DELETE", url, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	options := types.NodeRemoveOptions{
+		Force: force,
+	}
+	err = cli.NodeRemove(context.Background(), id, options)
+	c.Assert(err, checker.IsNil)
 }
 
 // UpdateNode updates a swarm node with the specified node constructor
 func (d *Swarm) UpdateNode(c *check.C, id string, f ...NodeConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	for i := 0; ; i++ {
 		node := d.GetNode(c, id)
 		for _, fn := range f {
 			fn(node)
 		}
-		url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index)
-		status, out, err := d.SockRequest("POST", url, node.Spec)
-		if i < 10 && strings.Contains(string(out), "update out of sequence") {
+
+		err = cli.NodeUpdate(context.Background(), node.ID, node.Version, node.Spec)
+		if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") {
 			time.Sleep(100 * time.Millisecond)
 			continue
 		}
-		c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-		c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+		c.Assert(err, checker.IsNil)
 		return
 	}
 }
 
 // ListNodes returns the list of the current swarm nodes
 func (d *Swarm) ListNodes(c *check.C) []swarm.Node {
-	status, out, err := d.SockRequest("GET", "/nodes", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	nodes := []swarm.Node{}
-	c.Assert(json.Unmarshal(out, &nodes), checker.IsNil)
+	nodes, err := cli.NodeList(context.Background(), types.NodeListOptions{})
+	c.Assert(err, checker.IsNil)
+
 	return nodes
 }
 
 // ListServices returns the list of the current swarm services
 func (d *Swarm) ListServices(c *check.C) []swarm.Service {
-	status, out, err := d.SockRequest("GET", "/services", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	services := []swarm.Service{}
-	c.Assert(json.Unmarshal(out, &services), checker.IsNil)
+	services, err := cli.ServiceList(context.Background(), types.ServiceListOptions{})
+	c.Assert(err, checker.IsNil)
 	return services
 }
 
 // CreateSecret creates a secret given the specified spec
 func (d *Swarm) CreateSecret(c *check.C, secretSpec swarm.SecretSpec) string {
-	status, out, err := d.SockRequest("POST", "/secrets/create", secretSpec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf("output: %q", string(out)))
+	scr, err := cli.SecretCreate(context.Background(), secretSpec)
+	c.Assert(err, checker.IsNil)
 
-	var scr types.SecretCreateResponse
-	c.Assert(json.Unmarshal(out, &scr), checker.IsNil)
 	return scr.ID
 }
 
 // ListSecrets returns the list of the current swarm secrets
 func (d *Swarm) ListSecrets(c *check.C) []swarm.Secret {
-	status, out, err := d.SockRequest("GET", "/secrets", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	secrets := []swarm.Secret{}
-	c.Assert(json.Unmarshal(out, &secrets), checker.IsNil)
+	secrets, err := cli.SecretList(context.Background(), types.SecretListOptions{})
+	c.Assert(err, checker.IsNil)
 	return secrets
 }
 
 // GetSecret returns a swarm secret identified by the specified id
 func (d *Swarm) GetSecret(c *check.C, id string) *swarm.Secret {
-	var secret swarm.Secret
-	status, out, err := d.SockRequest("GET", "/secrets/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &secret), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	secret, _, err := cli.SecretInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	return &secret
 }
 
 // DeleteSecret removes the swarm secret identified by the specified id
 func (d *Swarm) DeleteSecret(c *check.C, id string) {
-	status, out, err := d.SockRequest("DELETE", "/secrets/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusNoContent, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	err = cli.SecretRemove(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 }
 
 // UpdateSecret updates the swarm secret identified by the specified id
 // Currently, only label update is supported.
 func (d *Swarm) UpdateSecret(c *check.C, id string, f ...SecretConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	secret := d.GetSecret(c, id)
 	for _, fn := range f {
 		fn(secret)
 	}
-	url := fmt.Sprintf("/secrets/%s/update?version=%d", secret.ID, secret.Version.Index)
-	status, out, err := d.SockRequest("POST", url, secret.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	err = cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec)
+
+	c.Assert(err, checker.IsNil)
 }
 
 // CreateConfig creates a config given the specified spec
 func (d *Swarm) CreateConfig(c *check.C, configSpec swarm.ConfigSpec) string {
-	status, out, err := d.SockRequest("POST", "/configs/create", configSpec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf("output: %q", string(out)))
-
-	var scr types.ConfigCreateResponse
-	c.Assert(json.Unmarshal(out, &scr), checker.IsNil)
+	scr, err := cli.ConfigCreate(context.Background(), configSpec)
+	c.Assert(err, checker.IsNil)
 	return scr.ID
 }
 
 // ListConfigs returns the list of the current swarm configs
 func (d *Swarm) ListConfigs(c *check.C) []swarm.Config {
-	status, out, err := d.SockRequest("GET", "/configs", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	configs := []swarm.Config{}
-	c.Assert(json.Unmarshal(out, &configs), checker.IsNil)
+	configs, err := cli.ConfigList(context.Background(), types.ConfigListOptions{})
+	c.Assert(err, checker.IsNil)
 	return configs
 }
 
 // GetConfig returns a swarm config identified by the specified id
 func (d *Swarm) GetConfig(c *check.C, id string) *swarm.Config {
-	var config swarm.Config
-	status, out, err := d.SockRequest("GET", "/configs/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &config), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	config, _, err := cli.ConfigInspectWithRaw(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 	return &config
 }
 
 // DeleteConfig removes the swarm config identified by the specified id
 func (d *Swarm) DeleteConfig(c *check.C, id string) {
-	status, out, err := d.SockRequest("DELETE", "/configs/"+id, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusNoContent, check.Commentf("output: %q", string(out)))
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	err = cli.ConfigRemove(context.Background(), id)
+	c.Assert(err, checker.IsNil)
 }
 
 // UpdateConfig updates the swarm config identified by the specified id
 // Currently, only label update is supported.
 func (d *Swarm) UpdateConfig(c *check.C, id string, f ...ConfigConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	config := d.GetConfig(c, id)
 	for _, fn := range f {
 		fn(config)
 	}
-	url := fmt.Sprintf("/configs/%s/update?version=%d", config.ID, config.Version.Index)
-	status, out, err := d.SockRequest("POST", url, config.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	err = cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec)
+	c.Assert(err, checker.IsNil)
 }
 
 // GetSwarm returns the current swarm object
 func (d *Swarm) GetSwarm(c *check.C) swarm.Swarm {
-	var sw swarm.Swarm
-	status, out, err := d.SockRequest("GET", "/swarm", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	sw, err := cli.SwarmInspect(context.Background())
+	c.Assert(err, checker.IsNil)
 	return sw
 }
 
 // UpdateSwarm updates the current swarm object with the specified spec constructors
 func (d *Swarm) UpdateSwarm(c *check.C, f ...SpecConstructor) {
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	sw := d.GetSwarm(c)
 	for _, fn := range f {
 		fn(&sw.Spec)
 	}
-	url := fmt.Sprintf("/swarm/update?version=%d", sw.Version.Index)
-	status, out, err := d.SockRequest("POST", url, sw.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+
+	err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{})
+	c.Assert(err, checker.IsNil)
 }
 
 // RotateTokens update the swarm to rotate tokens
 func (d *Swarm) RotateTokens(c *check.C) {
-	var sw swarm.Swarm
-	status, out, err := d.SockRequest("GET", "/swarm", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	url := fmt.Sprintf("/swarm/update?version=%d&rotateWorkerToken=true&rotateManagerToken=true", sw.Version.Index)
-	status, out, err = d.SockRequest("POST", url, sw.Spec)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	sw, err := cli.SwarmInspect(context.Background())
+	c.Assert(err, checker.IsNil)
+
+	flags := swarm.UpdateFlags{
+		RotateManagerToken: true,
+		RotateWorkerToken:  true,
+	}
+
+	err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags)
+	c.Assert(err, checker.IsNil)
 }
 
 // JoinTokens returns the current swarm join tokens
 func (d *Swarm) JoinTokens(c *check.C) swarm.JoinTokens {
-	var sw swarm.Swarm
-	status, out, err := d.SockRequest("GET", "/swarm", nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
-	c.Assert(json.Unmarshal(out, &sw), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	sw, err := cli.SwarmInspect(context.Background())
+	c.Assert(err, checker.IsNil)
 	return sw.JoinTokens
 }
 
@@ -570,17 +612,14 @@
 
 // CheckLeader returns whether there is a leader on the swarm or not
 func (d *Swarm) CheckLeader(c *check.C) (interface{}, check.CommentInterface) {
-	errList := check.Commentf("could not get node list")
-	status, out, err := d.SockRequest("GET", "/nodes", nil)
-	if err != nil {
-		return err, errList
-	}
-	if status != http.StatusOK {
-		return fmt.Errorf("expected http status OK, got: %d", status), errList
-	}
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	var ls []swarm.Node
-	if err := json.Unmarshal(out, &ls); err != nil {
+	errList := check.Commentf("could not get node list")
+
+	ls, err := cli.NodeList(context.Background(), types.NodeListOptions{})
+	if err != nil {
 		return err, errList
 	}
 
diff --git a/integration-cli/daemon/daemon_windows.go b/integration-cli/daemon/daemon_windows.go
index f8df27c..e445aa6 100644
--- a/integration-cli/daemon/daemon_windows.go
+++ b/integration-cli/daemon/daemon_windows.go
@@ -3,47 +3,19 @@
 import (
 	"fmt"
 	"strconv"
-	"syscall"
-	"unsafe"
 
 	"github.com/go-check/check"
 	"golang.org/x/sys/windows"
 )
 
-func openEvent(desiredAccess uint32, inheritHandle bool, name string, proc *windows.LazyProc) (handle windows.Handle, err error) {
-	namep, _ := windows.UTF16PtrFromString(name)
-	var _p2 uint32
-	if inheritHandle {
-		_p2 = 1
-	}
-	r0, _, e1 := proc.Call(uintptr(desiredAccess), uintptr(_p2), uintptr(unsafe.Pointer(namep)))
-	handle = windows.Handle(r0)
-	if handle == windows.InvalidHandle {
-		err = e1
-	}
-	return
-}
-
-func pulseEvent(handle windows.Handle, proc *windows.LazyProc) (err error) {
-	r0, _, _ := proc.Call(uintptr(handle))
-	if r0 != 0 {
-		err = syscall.Errno(r0)
-	}
-	return
-}
-
 // SignalDaemonDump sends a signal to the daemon to write a dump file
 func SignalDaemonDump(pid int) {
-	modkernel32 := windows.NewLazySystemDLL("kernel32.dll")
-	procOpenEvent := modkernel32.NewProc("OpenEventW")
-	procPulseEvent := modkernel32.NewProc("PulseEvent")
-
-	ev := "Global\\docker-daemon-" + strconv.Itoa(pid)
-	h2, _ := openEvent(0x0002, false, ev, procOpenEvent)
-	if h2 == 0 {
+	ev, _ := windows.UTF16PtrFromString("Global\\docker-daemon-" + strconv.Itoa(pid))
+	h2, err := windows.OpenEvent(0x0002, false, ev)
+	if h2 == 0 || err != nil {
 		return
 	}
-	pulseEvent(h2, procPulseEvent)
+	windows.PulseEvent(h2)
 }
 
 func signalDaemonReload(pid int) error {
diff --git a/integration-cli/docker_api_attach_test.go b/integration-cli/docker_api_attach_test.go
index 11f7340..a3aa40f 100644
--- a/integration-cli/docker_api_attach_test.go
+++ b/integration-cli/docker_api_attach_test.go
@@ -15,7 +15,6 @@
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/pkg/stdcopy"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/go-check/check"
 	"golang.org/x/net/websocket"
 )
@@ -80,18 +79,20 @@
 	resp, err := client.Do(req)
 	// connection will shutdown, err should be "persistent connection closed"
 	c.Assert(resp.StatusCode, checker.Equals, http.StatusNotFound)
-	content, err := testutil.ReadBody(resp.Body)
+	content, err := request.ReadBody(resp.Body)
 	c.Assert(err, checker.IsNil)
 	expected := "No such container: doesnotexist\r\n"
 	c.Assert(string(content), checker.Equals, expected)
 }
 
 func (s *DockerSuite) TestGetContainersWsAttachContainerNotFound(c *check.C) {
-	status, body, err := request.SockRequest("GET", "/containers/doesnotexist/attach/ws", nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	res, body, err := request.Get("/containers/doesnotexist/attach/ws")
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNotFound)
+	c.Assert(err, checker.IsNil)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	expected := "No such container: doesnotexist"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, b), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
@@ -178,6 +179,7 @@
 	// Make sure we don't see "hello" if Logs is false
 	client, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer client.Close()
 
 	cid, _ = dockerCmd(c, "run", "-di", "busybox", "/bin/sh", "-c", "echo hello; cat")
 	cid = strings.TrimSpace(cid)
diff --git a/integration-cli/docker_api_auth_test.go b/integration-cli/docker_api_auth_test.go
index cc903c0..a1f7a09 100644
--- a/integration-cli/docker_api_auth_test.go
+++ b/integration-cli/docker_api_auth_test.go
@@ -1,12 +1,11 @@
 package main
 
 import (
-	"net/http"
-
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 // Test case for #22244
@@ -16,11 +15,11 @@
 		Username: "no-user",
 		Password: "no-password",
 	}
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
+	_, err = cli.RegistryLogin(context.Background(), config)
 	expected := "Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password"
-	status, body, err := request.SockRequest("POST", "/auth", config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusUnauthorized)
-	msg := getErrorMessage(c, body)
-	c.Assert(msg, checker.Contains, expected, check.Commentf("Expected: %v, got: %v", expected, msg))
+	c.Assert(err.Error(), checker.Contains, expected)
 }
diff --git a/integration-cli/docker_api_build_test.go b/integration-cli/docker_api_build_test.go
index c1ab766..8c494f1 100644
--- a/integration-cli/docker_api_build_test.go
+++ b/integration-cli/docker_api_build_test.go
@@ -12,15 +12,14 @@
 	"strings"
 
 	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/client/session"
-	"github.com/docker/docker/client/session/filesync"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli/build/fakecontext"
 	"github.com/docker/docker/integration-cli/cli/build/fakegit"
 	"github.com/docker/docker/integration-cli/cli/build/fakestorage"
 	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/go-check/check"
+	"github.com/moby/buildkit/session"
+	"github.com/moby/buildkit/session/filesync"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"golang.org/x/net/context"
@@ -29,6 +28,7 @@
 
 func (s *DockerSuite) TestBuildAPIDockerFileRemote(c *check.C) {
 	testRequires(c, NotUserNamespace)
+
 	var testD string
 	if testEnv.DaemonPlatform() == "windows" {
 		testD = `FROM busybox
@@ -47,7 +47,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
-	buf, err := testutil.ReadBody(body)
+	buf, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	// Make sure Dockerfile exists.
@@ -135,7 +135,7 @@
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
 	defer body.Close()
-	content, err := testutil.ReadBody(body)
+	content, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	// Build used the wrong dockerfile.
@@ -153,7 +153,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
-	buf, err := testutil.ReadBody(body)
+	buf, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	out := string(buf)
@@ -174,7 +174,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
-	buf, err := testutil.ReadBody(body)
+	buf, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	out := string(buf)
@@ -196,7 +196,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
-	buf, err := testutil.ReadBody(body)
+	buf, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	out := string(buf)
@@ -243,7 +243,7 @@
 		c.Assert(err, checker.IsNil)
 		c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
-		out, err := testutil.ReadBody(body)
+		out, err := request.ReadBody(body)
 		c.Assert(err, checker.IsNil)
 		lines := strings.Split(string(out), "\n")
 		c.Assert(len(lines), checker.GreaterThan, 1)
@@ -280,7 +280,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
-	out, err := testutil.ReadBody(body)
+	out, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(string(out), checker.Contains, "Successfully built")
 }
@@ -299,7 +299,7 @@
 		require.NoError(c, err)
 		assert.Equal(c, http.StatusOK, res.StatusCode)
 
-		out, err := testutil.ReadBody(body)
+		out, err := request.ReadBody(body)
 		require.NoError(c, err)
 		assert.Contains(c, string(out), "Successfully built")
 		return out
@@ -361,7 +361,7 @@
 	require.NoError(c, err)
 	assert.Equal(c, http.StatusOK, res.StatusCode)
 
-	out, err := testutil.ReadBody(body)
+	out, err := request.ReadBody(body)
 	require.NoError(c, err)
 	assert.Contains(c, string(out), "Successfully built")
 }
@@ -405,11 +405,116 @@
 	require.NoError(c, err)
 	assert.Equal(c, http.StatusOK, res.StatusCode)
 
-	out, err := testutil.ReadBody(body)
+	out, err := request.ReadBody(body)
 	require.NoError(c, err)
 	assert.Contains(c, string(out), "Successfully built")
 }
 
+func (s *DockerSuite) TestBuildChownOnCopy(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	dockerfile := `FROM busybox
+		RUN echo 'test1:x:1001:1001::/bin:/bin/false' >> /etc/passwd
+		RUN echo 'test1:x:1001:' >> /etc/group
+		RUN echo 'test2:x:1002:' >> /etc/group
+		COPY --chown=test1:1002 . /new_dir
+		RUN ls -l /
+		RUN [ $(ls -l / | grep new_dir | awk '{print $3":"$4}') = 'test1:test2' ]
+		RUN [ $(ls -nl / | grep new_dir | awk '{print $3":"$4}') = '1001:1002' ]
+	`
+	ctx := fakecontext.New(c, "",
+		fakecontext.WithDockerfile(dockerfile),
+		fakecontext.WithFile("test_file1", "some test content"),
+	)
+	defer ctx.Close()
+
+	res, body, err := request.Post(
+		"/build",
+		request.RawContent(ctx.AsTarReader(c)),
+		request.ContentType("application/x-tar"))
+	c.Assert(err, checker.IsNil)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
+
+	out, err := request.ReadBody(body)
+	require.NoError(c, err)
+	assert.Contains(c, string(out), "Successfully built")
+}
+
+func (s *DockerSuite) TestBuildCopyCacheOnFileChange(c *check.C) {
+
+	dockerfile := `FROM busybox
+COPY file /file`
+
+	ctx1 := fakecontext.New(c, "",
+		fakecontext.WithDockerfile(dockerfile),
+		fakecontext.WithFile("file", "foo"))
+	ctx2 := fakecontext.New(c, "",
+		fakecontext.WithDockerfile(dockerfile),
+		fakecontext.WithFile("file", "bar"))
+
+	var build = func(ctx *fakecontext.Fake) string {
+		res, body, err := request.Post("/build",
+			request.RawContent(ctx.AsTarReader(c)),
+			request.ContentType("application/x-tar"))
+
+		require.NoError(c, err)
+		assert.Equal(c, http.StatusOK, res.StatusCode)
+
+		out, err := request.ReadBody(body)
+
+		ids := getImageIDsFromBuild(c, out)
+		return ids[len(ids)-1]
+	}
+
+	id1 := build(ctx1)
+	id2 := build(ctx1)
+	id3 := build(ctx2)
+
+	if id1 != id2 {
+		c.Fatal("didn't use the cache")
+	}
+	if id1 == id3 {
+		c.Fatal("COPY With different source file should not share same cache")
+	}
+}
+
+func (s *DockerSuite) TestBuildAddCacheOnFileChange(c *check.C) {
+
+	dockerfile := `FROM busybox
+ADD file /file`
+
+	ctx1 := fakecontext.New(c, "",
+		fakecontext.WithDockerfile(dockerfile),
+		fakecontext.WithFile("file", "foo"))
+	ctx2 := fakecontext.New(c, "",
+		fakecontext.WithDockerfile(dockerfile),
+		fakecontext.WithFile("file", "bar"))
+
+	var build = func(ctx *fakecontext.Fake) string {
+		res, body, err := request.Post("/build",
+			request.RawContent(ctx.AsTarReader(c)),
+			request.ContentType("application/x-tar"))
+
+		require.NoError(c, err)
+		assert.Equal(c, http.StatusOK, res.StatusCode)
+
+		out, err := request.ReadBody(body)
+
+		ids := getImageIDsFromBuild(c, out)
+		return ids[len(ids)-1]
+	}
+
+	id1 := build(ctx1)
+	id2 := build(ctx1)
+	id3 := build(ctx2)
+
+	if id1 != id2 {
+		c.Fatal("didn't use the cache")
+	}
+	if id1 == id3 {
+		c.Fatal("COPY With different source file should not share same cache")
+	}
+}
+
 func (s *DockerSuite) TestBuildWithSession(c *check.C) {
 	testRequires(c, ExperimentalDaemon)
 
@@ -461,7 +566,7 @@
 	require.NoError(c, err)
 	assert.Equal(c, http.StatusOK, res.StatusCode)
 
-	outBytes, err := testutil.ReadBody(body)
+	outBytes, err := request.ReadBody(body)
 	require.NoError(c, err)
 	assert.Contains(c, string(outBytes), "Successfully built")
 	assert.Equal(c, strings.Count(string(outBytes), "Using cache"), 4)
@@ -481,7 +586,9 @@
 	sess, err := session.NewSession("foo1", "foo")
 	assert.Nil(c, err)
 
-	fsProvider := filesync.NewFSSyncProvider(dir, nil)
+	fsProvider := filesync.NewFSSyncProvider([]filesync.SyncedDir{
+		{Dir: dir},
+	})
 	sess.Allow(fsProvider)
 
 	g, ctx := errgroup.WithContext(context.Background())
@@ -491,7 +598,7 @@
 	})
 
 	g.Go(func() error {
-		res, body, err := request.Post("/build?remote=client-session&session="+sess.UUID(), func(req *http.Request) error {
+		res, body, err := request.Post("/build?remote=client-session&session="+sess.ID(), func(req *http.Request) error {
 			req.Body = ioutil.NopCloser(strings.NewReader(dockerfile))
 			return nil
 		})
@@ -499,7 +606,7 @@
 			return err
 		}
 		assert.Equal(c, res.StatusCode, http.StatusOK)
-		out, err := testutil.ReadBody(body)
+		out, err := request.ReadBody(body)
 		require.NoError(c, err)
 		assert.Contains(c, string(out), "Successfully built")
 		sess.Close()
diff --git a/integration-cli/docker_api_containers_test.go b/integration-cli/docker_api_containers_test.go
index 25c7244..cd3566f 100644
--- a/integration-cli/docker_api_containers_test.go
+++ b/integration-cli/docker_api_containers_test.go
@@ -8,10 +8,10 @@
 	"io"
 	"io/ioutil"
 	"net/http"
-	"net/url"
 	"os"
 	"path/filepath"
 	"regexp"
+	"runtime"
 	"strconv"
 	"strings"
 	"time"
@@ -20,6 +20,7 @@
 	containertypes "github.com/docker/docker/api/types/container"
 	mounttypes "github.com/docker/docker/api/types/mount"
 	networktypes "github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
@@ -27,9 +28,13 @@
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/docker/volume"
+	"github.com/docker/go-connections/nat"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/poll"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestContainerAPIGetAll(c *check.C) {
@@ -37,35 +42,42 @@
 	name := "getall"
 	dockerCmd(c, "run", "--name", name, "busybox", "true")
 
-	status, body, err := request.SockRequest("GET", "/containers/json?all=1", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	var inspectJSON []struct {
-		Names []string
+	options := types.ContainerListOptions{
+		All: true,
 	}
-	err = json.Unmarshal(body, &inspectJSON)
-	c.Assert(err, checker.IsNil, check.Commentf("unable to unmarshal response body"))
-
-	c.Assert(inspectJSON, checker.HasLen, startCount+1)
-
-	actual := inspectJSON[0].Names[0]
+	containers, err := cli.ContainerList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
+	c.Assert(containers, checker.HasLen, startCount+1)
+	actual := containers[0].Names[0]
 	c.Assert(actual, checker.Equals, "/"+name)
 }
 
 // regression test for empty json field being omitted #13691
 func (s *DockerSuite) TestContainerAPIGetJSONNoFieldsOmitted(c *check.C) {
+	startCount := getContainerCount(c)
 	dockerCmd(c, "run", "busybox", "true")
 
-	status, body, err := request.SockRequest("GET", "/containers/json?all=1", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
+
+	options := types.ContainerListOptions{
+		All: true,
+	}
+	containers, err := cli.ContainerList(context.Background(), options)
+	c.Assert(err, checker.IsNil)
+	c.Assert(containers, checker.HasLen, startCount+1)
+	actual := fmt.Sprintf("%+v", containers[0])
 
 	// empty Labels field triggered this bug, make sense to check for everything
 	// cause even Ports for instance can trigger this bug
 	// better safe than sorry..
 	fields := []string{
-		"Id",
+		"ID",
 		"Names",
 		"Image",
 		"Command",
@@ -79,7 +91,7 @@
 	// decoding into types.Container do not work since it eventually unmarshal
 	// and empty field to an empty go map, so we just check for a string
 	for _, f := range fields {
-		if !strings.Contains(string(body), f) {
+		if !strings.Contains(actual, f) {
 			c.Fatalf("Field %s is missing and it shouldn't", f)
 		}
 	}
@@ -87,7 +99,7 @@
 
 type containerPs struct {
 	Names []string
-	Ports []map[string]interface{}
+	Ports []types.Port
 }
 
 // regression test for non-empty fields from #13901
@@ -98,30 +110,30 @@
 	port := 80
 	runSleepingContainer(c, "--name", name, "--expose", strconv.Itoa(port))
 
-	status, body, err := request.SockRequest("GET", "/containers/json?all=1", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	var resp []containerPs
-	err = json.Unmarshal(body, &resp)
+	options := types.ContainerListOptions{
+		All: true,
+	}
+	containers, err := cli.ContainerList(context.Background(), options)
 	c.Assert(err, checker.IsNil)
-
-	var foundContainer *containerPs
-	for _, container := range resp {
-		for _, testName := range container.Names {
+	var foundContainer containerPs
+	for _, c := range containers {
+		for _, testName := range c.Names {
 			if "/"+name == testName {
-				foundContainer = &container
+				foundContainer.Names = c.Names
+				foundContainer.Ports = c.Ports
 				break
 			}
 		}
 	}
 
 	c.Assert(foundContainer.Ports, checker.HasLen, 1)
-	c.Assert(foundContainer.Ports[0]["PrivatePort"], checker.Equals, float64(port))
-	_, ok := foundContainer.Ports[0]["PublicPort"]
-	c.Assert(ok, checker.Not(checker.Equals), true)
-	_, ok = foundContainer.Ports[0]["IP"]
-	c.Assert(ok, checker.Not(checker.Equals), true)
+	c.Assert(foundContainer.Ports[0].PrivatePort, checker.Equals, uint16(port))
+	c.Assert(foundContainer.Ports[0].PublicPort, checker.NotNil)
+	c.Assert(foundContainer.Ports[0].IP, checker.NotNil)
 }
 
 func (s *DockerSuite) TestContainerAPIGetExport(c *check.C) {
@@ -130,12 +142,15 @@
 	name := "exportcontainer"
 	dockerCmd(c, "run", "--name", name, "busybox", "touch", "/test")
 
-	status, body, err := request.SockRequest("GET", "/containers/"+name+"/export", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
+	body, err := cli.ContainerExport(context.Background(), name)
+	c.Assert(err, checker.IsNil)
+	defer body.Close()
 	found := false
-	for tarReader := tar.NewReader(bytes.NewReader(body)); ; {
+	for tarReader := tar.NewReader(body); ; {
 		h, err := tarReader.Next()
 		if err != nil && err == io.EOF {
 			break
@@ -154,15 +169,12 @@
 	name := "changescontainer"
 	dockerCmd(c, "run", "--name", name, "busybox", "rm", "/etc/passwd")
 
-	status, body, err := request.SockRequest("GET", "/containers/"+name+"/changes", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	changes := []struct {
-		Kind int
-		Path string
-	}{}
-	c.Assert(json.Unmarshal(body, &changes), checker.IsNil, check.Commentf("unable to unmarshal response body"))
+	changes, err := cli.ContainerDiff(context.Background(), name)
+	c.Assert(err, checker.IsNil)
 
 	// Check the changelog for removal of /etc/passwd
 	success := false
@@ -181,14 +193,19 @@
 	runSleepingContainer(c, "--name", name)
 
 	type b struct {
-		status int
-		body   []byte
-		err    error
+		stats types.ContainerStats
+		err   error
 	}
+
 	bc := make(chan b, 1)
 	go func() {
-		status, body, err := request.SockRequest("GET", "/containers/"+name+"/stats", nil, daemonHost())
-		bc <- b{status, body, err}
+		cli, err := client.NewEnvClient()
+		c.Assert(err, checker.IsNil)
+		defer cli.Close()
+
+		stats, err := cli.ContainerStats(context.Background(), name, true)
+		c.Assert(err, checker.IsNil)
+		bc <- b{stats, err}
 	}()
 
 	// allow some time to stream the stats from the container
@@ -201,10 +218,8 @@
 	case <-time.After(2 * time.Second):
 		c.Fatal("stream was not closed after container was removed")
 	case sr := <-bc:
-		c.Assert(sr.err, checker.IsNil)
-		c.Assert(sr.status, checker.Equals, http.StatusOK)
-
-		dec := json.NewDecoder(bytes.NewBuffer(sr.body))
+		dec := json.NewDecoder(sr.stats.Body)
+		defer sr.stats.Body.Close()
 		var s *types.Stats
 		// decode only one object from the stream
 		c.Assert(dec.Decode(&s), checker.IsNil)
@@ -215,16 +230,20 @@
 	out := runSleepingContainer(c)
 	id := strings.TrimSpace(out)
 
-	buf := &testutil.ChannelBuffer{C: make(chan []byte, 1)}
+	buf := &ChannelBuffer{C: make(chan []byte, 1)}
 	defer buf.Close()
 
-	_, body, err := request.Get("/containers/"+id+"/stats?stream=1", request.JSON)
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	defer body.Close()
+	defer cli.Close()
+
+	stats, err := cli.ContainerStats(context.Background(), id, true)
+	c.Assert(err, checker.IsNil)
+	defer stats.Body.Close()
 
 	chErr := make(chan error, 1)
 	go func() {
-		_, err = io.Copy(buf, body)
+		_, err = io.Copy(buf, stats.Body)
 		chErr <- err
 	}()
 
@@ -243,6 +262,34 @@
 	c.Assert(<-chErr, checker.IsNil)
 }
 
+// ChannelBuffer holds a chan of byte array that can be populate in a goroutine.
+type ChannelBuffer struct {
+	C chan []byte
+}
+
+// Write implements Writer.
+func (c *ChannelBuffer) Write(b []byte) (int, error) {
+	c.C <- b
+	return len(b), nil
+}
+
+// Close closes the go channel.
+func (c *ChannelBuffer) Close() error {
+	close(c.C)
+	return nil
+}
+
+// ReadTimeout reads the content of the channel in the specified byte array with
+// the specified duration as timeout.
+func (c *ChannelBuffer) ReadTimeout(p []byte, n time.Duration) (int, error) {
+	select {
+	case b := <-c.C:
+		return copy(p[0:], b), nil
+	case <-time.After(n):
+		return -1, fmt.Errorf("timeout reading from channel")
+	}
+}
+
 // regression test for gh13421
 // previous test was just checking one stat entry so it didn't fail (stats with
 // stream false always return one stat)
@@ -251,14 +298,19 @@
 	runSleepingContainer(c, "--name", name)
 
 	type b struct {
-		status int
-		body   io.ReadCloser
-		err    error
+		stats types.ContainerStats
+		err   error
 	}
+
 	bc := make(chan b, 1)
 	go func() {
-		status, body, err := request.Get("/containers/" + name + "/stats")
-		bc <- b{status.StatusCode, body, err}
+		cli, err := client.NewEnvClient()
+		c.Assert(err, checker.IsNil)
+		defer cli.Close()
+
+		stats, err := cli.ContainerStats(context.Background(), name, true)
+		c.Assert(err, checker.IsNil)
+		bc <- b{stats, err}
 	}()
 
 	// allow some time to stream the stats from the container
@@ -271,10 +323,8 @@
 	case <-time.After(2 * time.Second):
 		c.Fatal("stream was not closed after container was removed")
 	case sr := <-bc:
-		c.Assert(sr.err, checker.IsNil)
-		c.Assert(sr.status, checker.Equals, http.StatusOK)
-
-		b, err := ioutil.ReadAll(sr.body)
+		b, err := ioutil.ReadAll(sr.stats.Body)
+		defer sr.stats.Body.Close()
 		c.Assert(err, checker.IsNil)
 		s := string(b)
 		// count occurrences of "read" of types.Stats
@@ -289,14 +339,20 @@
 	runSleepingContainer(c, "--name", name)
 
 	type b struct {
-		status int
-		body   []byte
-		err    error
+		stats types.ContainerStats
+		err   error
 	}
+
 	bc := make(chan b, 1)
+
 	go func() {
-		status, body, err := request.SockRequest("GET", "/containers/"+name+"/stats?stream=0", nil, daemonHost())
-		bc <- b{status, body, err}
+		cli, err := client.NewEnvClient()
+		c.Assert(err, checker.IsNil)
+		defer cli.Close()
+
+		stats, err := cli.ContainerStats(context.Background(), name, false)
+		c.Assert(err, checker.IsNil)
+		bc <- b{stats, err}
 	}()
 
 	// allow some time to stream the stats from the container
@@ -309,10 +365,10 @@
 	case <-time.After(2 * time.Second):
 		c.Fatal("stream was not closed after container was removed")
 	case sr := <-bc:
-		c.Assert(sr.err, checker.IsNil)
-		c.Assert(sr.status, checker.Equals, http.StatusOK)
-
-		s := string(sr.body)
+		b, err := ioutil.ReadAll(sr.stats.Body)
+		defer sr.stats.Body.Close()
+		c.Assert(err, checker.IsNil)
+		s := string(b)
 		// count occurrences of `"read"` of types.Stats
 		c.Assert(strings.Count(s, `"read"`), checker.Equals, 1, check.Commentf("Expected only one stat streamed, got %d", strings.Count(s, `"read"`)))
 	}
@@ -322,24 +378,23 @@
 	name := "statscontainer"
 	dockerCmd(c, "create", "--name", name, "busybox", "ps")
 
-	type stats struct {
-		status int
-		err    error
-	}
-	chResp := make(chan stats)
+	chResp := make(chan error)
 
 	// We expect an immediate response, but if it's not immediate, the test would hang, so put it in a goroutine
 	// below we'll check this on a timeout.
 	go func() {
-		resp, body, err := request.Get("/containers/" + name + "/stats")
-		body.Close()
-		chResp <- stats{resp.StatusCode, err}
+		cli, err := client.NewEnvClient()
+		c.Assert(err, checker.IsNil)
+		defer cli.Close()
+
+		resp, err := cli.ContainerStats(context.Background(), name, false)
+		defer resp.Body.Close()
+		chResp <- err
 	}()
 
 	select {
-	case r := <-chResp:
-		c.Assert(r.err, checker.IsNil)
-		c.Assert(r.status, checker.Equals, http.StatusOK)
+	case err := <-chResp:
+		c.Assert(err, checker.IsNil)
 	case <-time.After(10 * time.Second):
 		c.Fatal("timeout waiting for stats response for stopped container")
 	}
@@ -356,9 +411,12 @@
 	out := cli.DockerCmd(c, "run", "-d", "busybox", "sleep", "30").Combined()
 	ContainerID := strings.TrimSpace(out)
 
-	resp, _, err := request.Post("/containers/" + ContainerID + "/pause")
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(resp.StatusCode, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerPause(context.Background(), ContainerID)
+	c.Assert(err, checker.IsNil)
 
 	pausedContainers := getPaused(c)
 
@@ -366,9 +424,8 @@
 		c.Fatalf("there should be one paused container and not %d", len(pausedContainers))
 	}
 
-	resp, _, err = request.Post("/containers/" + ContainerID + "/unpause")
+	err = cli.ContainerUnpause(context.Background(), ContainerID)
 	c.Assert(err, checker.IsNil)
-	c.Assert(resp.StatusCode, checker.Equals, http.StatusNoContent)
 
 	pausedContainers = getPaused(c)
 	c.Assert(pausedContainers, checker.HasLen, 0, check.Commentf("There should be no paused container."))
@@ -380,15 +437,12 @@
 	id := strings.TrimSpace(string(out))
 	c.Assert(waitRun(id), checker.IsNil)
 
-	type topResp struct {
-		Titles    []string
-		Processes [][]string
-	}
-	var top topResp
-	status, b, err := request.SockRequest("GET", "/containers/"+id+"/top?ps_args=aux", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	c.Assert(json.Unmarshal(b, &top), checker.IsNil)
+	defer cli.Close()
+
+	top, err := cli.ContainerTop(context.Background(), id, []string{"aux"})
+	c.Assert(err, checker.IsNil)
 	c.Assert(top.Titles, checker.HasLen, 11, check.Commentf("expected 11 titles, found %d: %v", len(top.Titles), top.Titles))
 
 	if top.Titles[0] != "USER" || top.Titles[10] != "COMMAND" {
@@ -405,15 +459,12 @@
 	id := strings.TrimSpace(string(out))
 	c.Assert(waitRun(id), checker.IsNil)
 
-	type topResp struct {
-		Titles    []string
-		Processes [][]string
-	}
-	var top topResp
-	status, b, err := request.SockRequest("GET", "/containers/"+id+"/top", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	c.Assert(json.Unmarshal(b, &top), checker.IsNil)
+	defer cli.Close()
+
+	top, err := cli.ContainerTop(context.Background(), id, nil)
+	c.Assert(err, checker.IsNil)
 	c.Assert(top.Titles, checker.HasLen, 4, check.Commentf("expected 4 titles, found %d: %v", len(top.Titles), top.Titles))
 
 	if top.Titles[0] != "Name" || top.Titles[3] != "Private Working Set" {
@@ -437,16 +488,16 @@
 	cName := "testapicommit"
 	dockerCmd(c, "run", "--name="+cName, "busybox", "/bin/sh", "-c", "touch /test")
 
-	name := "testcontainerapicommit"
-	status, b, err := request.SockRequest("POST", "/commit?repo="+name+"&testtag=tag&container="+cName, nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	type resp struct {
-		ID string
+	options := types.ContainerCommitOptions{
+		Reference: "testcontainerapicommit:testtag",
 	}
-	var img resp
-	c.Assert(json.Unmarshal(b, &img), checker.IsNil)
+
+	img, err := cli.ContainerCommit(context.Background(), cName, options)
+	c.Assert(err, checker.IsNil)
 
 	cmd := inspectField(c, img.ID, "Config.Cmd")
 	c.Assert(cmd, checker.Equals, "[/bin/sh -c touch /test]", check.Commentf("got wrong Cmd from commit: %q", cmd))
@@ -459,20 +510,20 @@
 	cName := "testapicommitwithconfig"
 	dockerCmd(c, "run", "--name="+cName, "busybox", "/bin/sh", "-c", "touch /test")
 
-	config := map[string]interface{}{
-		"Labels": map[string]string{"key1": "value1", "key2": "value2"},
-	}
-
-	name := "testcontainerapicommitwithconfig"
-	status, b, err := request.SockRequest("POST", "/commit?repo="+name+"&container="+cName, config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	type resp struct {
-		ID string
+	config := containertypes.Config{
+		Labels: map[string]string{"key1": "value1", "key2": "value2"}}
+
+	options := types.ContainerCommitOptions{
+		Reference: "testcontainerapicommitwithconfig",
+		Config:    &config,
 	}
-	var img resp
-	c.Assert(json.Unmarshal(b, &img), checker.IsNil)
+
+	img, err := cli.ContainerCommit(context.Background(), cName, options)
+	c.Assert(err, checker.IsNil)
 
 	label1 := inspectFieldMap(c, img.ID, "Config.Labels", "key1")
 	c.Assert(label1, checker.Equals, "value1")
@@ -490,76 +541,79 @@
 func (s *DockerSuite) TestContainerAPIBadPort(c *check.C) {
 	// TODO Windows to Windows CI - Port this test
 	testRequires(c, DaemonIsLinux)
-	config := map[string]interface{}{
-		"Image": "busybox",
-		"Cmd":   []string{"/bin/sh", "-c", "echo test"},
-		"PortBindings": map[string]interface{}{
-			"8080/tcp": []map[string]interface{}{
+
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"/bin/sh", "-c", "echo test"},
+	}
+
+	hostConfig := containertypes.HostConfig{
+		PortBindings: nat.PortMap{
+			"8080/tcp": []nat.PortBinding{
 				{
-					"HostIP":   "",
-					"HostPort": "aa80",
-				},
+					HostIP:   "",
+					HostPort: "aa80"},
 			},
 		},
 	}
 
-	jsonData := bytes.NewBuffer(nil)
-	json.NewEncoder(jsonData).Encode(config)
-
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
-	c.Assert(getErrorMessage(c, body), checker.Equals, `invalid port specification: "aa80"`, check.Commentf("Incorrect error msg: %s", body))
+	defer cli.Close()
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
+	c.Assert(err.Error(), checker.Contains, `invalid port specification: "aa80"`)
 }
 
 func (s *DockerSuite) TestContainerAPICreate(c *check.C) {
-	config := map[string]interface{}{
-		"Image": "busybox",
-		"Cmd":   []string{"/bin/sh", "-c", "touch /test && ls /test"},
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"/bin/sh", "-c", "touch /test && ls /test"},
 	}
 
-	status, b, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	type createResp struct {
-		ID string
-	}
-	var container createResp
-	c.Assert(json.Unmarshal(b, &container), checker.IsNil)
+	container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
+	c.Assert(err, checker.IsNil)
 
 	out, _ := dockerCmd(c, "start", "-a", container.ID)
 	c.Assert(strings.TrimSpace(out), checker.Equals, "/test")
 }
 
 func (s *DockerSuite) TestContainerAPICreateEmptyConfig(c *check.C) {
-	config := map[string]interface{}{}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
+	defer cli.Close()
 
-	expected := "Config cannot be empty in order to create a container"
-	c.Assert(getErrorMessage(c, body), checker.Equals, expected)
+	_, err = cli.ContainerCreate(context.Background(), &containertypes.Config{}, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
+
+	expected := "No command specified"
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestContainerAPICreateMultipleNetworksConfig(c *check.C) {
 	// Container creation must fail if client specified configurations for more than one network
-	config := map[string]interface{}{
-		"Image": "busybox",
-		"NetworkingConfig": networktypes.NetworkingConfig{
-			EndpointsConfig: map[string]*networktypes.EndpointSettings{
-				"net1": {},
-				"net2": {},
-				"net3": {},
-			},
+	config := containertypes.Config{
+		Image: "busybox",
+	}
+
+	networkingConfig := networktypes.NetworkingConfig{
+		EndpointsConfig: map[string]*networktypes.EndpointSettings{
+			"net1": {},
+			"net2": {},
+			"net3": {},
 		},
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
-	msg := getErrorMessage(c, body)
+	defer cli.Close()
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networkingConfig, "")
+	msg := err.Error()
 	// network name order in error message is not deterministic
 	c.Assert(msg, checker.Contains, "Container cannot be connected to network endpoints")
 	c.Assert(msg, checker.Contains, "net1")
@@ -570,25 +624,22 @@
 func (s *DockerSuite) TestContainerAPICreateWithHostName(c *check.C) {
 	domainName := "test-domain"
 	hostName := "test-hostname"
-	config := map[string]interface{}{
-		"Image":      "busybox",
-		"Hostname":   hostName,
-		"Domainname": domainName,
+	config := containertypes.Config{
+		Image:      "busybox",
+		Hostname:   hostName,
+		Domainname: domainName,
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	var container containertypes.ContainerCreateCreatedBody
-	c.Assert(json.Unmarshal(body, &container), checker.IsNil)
-
-	status, body, err = request.SockRequest("GET", "/containers/"+container.ID+"/json", nil, daemonHost())
+	container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
 
-	var containerJSON types.ContainerJSON
-	c.Assert(json.Unmarshal(body, &containerJSON), checker.IsNil)
+	containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
+	c.Assert(err, checker.IsNil)
+
 	c.Assert(containerJSON.Config.Hostname, checker.Equals, hostName, check.Commentf("Mismatched Hostname"))
 	c.Assert(containerJSON.Config.Domainname, checker.Equals, domainName, check.Commentf("Mismatched Domainname"))
 }
@@ -606,51 +657,51 @@
 	UtilCreateNetworkMode(c, "container:web1")
 }
 
-func UtilCreateNetworkMode(c *check.C, networkMode string) {
-	config := map[string]interface{}{
-		"Image":      "busybox",
-		"HostConfig": map[string]interface{}{"NetworkMode": networkMode},
+func UtilCreateNetworkMode(c *check.C, networkMode containertypes.NetworkMode) {
+	config := containertypes.Config{
+		Image: "busybox",
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	hostConfig := containertypes.HostConfig{
+		NetworkMode: networkMode,
+	}
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	var container containertypes.ContainerCreateCreatedBody
-	c.Assert(json.Unmarshal(body, &container), checker.IsNil)
-
-	status, body, err = request.SockRequest("GET", "/containers/"+container.ID+"/json", nil, daemonHost())
+	container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
 
-	var containerJSON types.ContainerJSON
-	c.Assert(json.Unmarshal(body, &containerJSON), checker.IsNil)
+	containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
+	c.Assert(err, checker.IsNil)
+
 	c.Assert(containerJSON.HostConfig.NetworkMode, checker.Equals, containertypes.NetworkMode(networkMode), check.Commentf("Mismatched NetworkMode"))
 }
 
 func (s *DockerSuite) TestContainerAPICreateWithCpuSharesCpuset(c *check.C) {
 	// TODO Windows to Windows CI. The CpuShares part could be ported.
 	testRequires(c, DaemonIsLinux)
-	config := map[string]interface{}{
-		"Image":      "busybox",
-		"CpuShares":  512,
-		"CpusetCpus": "0",
+	config := containertypes.Config{
+		Image: "busybox",
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	hostConfig := containertypes.HostConfig{
+		Resources: containertypes.Resources{
+			CPUShares:  512,
+			CpusetCpus: "0",
+		},
+	}
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	var container containertypes.ContainerCreateCreatedBody
-	c.Assert(json.Unmarshal(body, &container), checker.IsNil)
-
-	status, body, err = request.SockRequest("GET", "/containers/"+container.ID+"/json", nil, daemonHost())
+	container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
 
-	var containerJSON types.ContainerJSON
-
-	c.Assert(json.Unmarshal(body, &containerJSON), checker.IsNil)
+	containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
+	c.Assert(err, checker.IsNil)
 
 	out := inspectField(c, containerJSON.ID, "HostConfig.CpuShares")
 	c.Assert(out, checker.Equals, "512")
@@ -673,13 +724,13 @@
 	// Try with no content-type
 	res, body, err := create("")
 	c.Assert(err, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 	body.Close()
 
 	// Try with wrong content-type
 	res, body, err = create("application/xml")
 	c.Assert(err, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 	body.Close()
 
 	// now application/json
@@ -705,9 +756,9 @@
 
 	res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
 	c.Assert(err, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(string(b[:]), checker.Contains, "invalid port")
 }
@@ -725,9 +776,9 @@
 
 	res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
 	c.Assert(err, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(string(b[:]), checker.Contains, "invalid restart policy")
 }
@@ -745,9 +796,9 @@
 
 	res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
 	c.Assert(err, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(string(b[:]), checker.Contains, "maximum retry count cannot be used with restart policy")
 }
@@ -765,9 +816,9 @@
 
 	res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
 	c.Assert(err, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(string(b[:]), checker.Contains, "maximum retry count cannot be negative")
 }
@@ -818,7 +869,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	type createResp struct {
 		ID string
@@ -847,10 +898,10 @@
 
 	res, body, err := request.Post("/containers/create", request.RawString(config), request.JSON)
 	c.Assert(err, checker.IsNil)
-	b, err2 := testutil.ReadBody(body)
+	b, err2 := request.ReadBody(body)
 	c.Assert(err2, checker.IsNil)
 
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 	c.Assert(string(b), checker.Contains, "Minimum memory limit allowed is 4MB")
 }
 
@@ -859,10 +910,13 @@
 
 	containerID := strings.TrimSpace(out)
 	newName := "TestContainerAPIRenameNew"
-	statusCode, _, err := request.SockRequest("POST", "/containers/"+containerID+"/rename?name="+newName, nil, daemonHost())
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	// 204 No Content is expected, not 200
-	c.Assert(statusCode, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerRename(context.Background(), containerID, newName)
+	c.Assert(err, checker.IsNil)
 
 	name := inspectField(c, containerID, "Name")
 	c.Assert(name, checker.Equals, "/"+newName, check.Commentf("Failed to rename container"))
@@ -872,9 +926,12 @@
 	name := "test-api-kill"
 	runSleepingContainer(c, "-i", "--name", name)
 
-	status, _, err := request.SockRequest("POST", "/containers/"+name+"/kill", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerKill(context.Background(), name, "SIGKILL")
+	c.Assert(err, checker.IsNil)
 
 	state := inspectField(c, name, "State.Running")
 	c.Assert(state, checker.Equals, "false", check.Commentf("got wrong State from container %s: %q", name, state))
@@ -883,10 +940,14 @@
 func (s *DockerSuite) TestContainerAPIRestart(c *check.C) {
 	name := "test-api-restart"
 	runSleepingContainer(c, "-di", "--name", name)
-
-	status, _, err := request.SockRequest("POST", "/containers/"+name+"/restart?t=1", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	timeout := 1 * time.Second
+	err = cli.ContainerRestart(context.Background(), name, &timeout)
+	c.Assert(err, checker.IsNil)
+
 	c.Assert(waitInspect(name, "{{ .State.Restarting  }} {{ .State.Running  }}", "false true", 15*time.Second), checker.IsNil)
 }
 
@@ -896,51 +957,59 @@
 	id := strings.TrimSpace(out)
 	c.Assert(waitRun(id), checker.IsNil)
 
-	status, _, err := request.SockRequest("POST", "/containers/"+name+"/restart", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerRestart(context.Background(), name, nil)
+	c.Assert(err, checker.IsNil)
+
 	c.Assert(waitInspect(name, "{{ .State.Restarting  }} {{ .State.Running  }}", "false true", 15*time.Second), checker.IsNil)
 }
 
 func (s *DockerSuite) TestContainerAPIStart(c *check.C) {
 	name := "testing-start"
-	config := map[string]interface{}{
-		"Image":     "busybox",
-		"Cmd":       append([]string{"/bin/sh", "-c"}, sleepCommandForDaemonPlatform()...),
-		"OpenStdin": true,
+	config := containertypes.Config{
+		Image:     "busybox",
+		Cmd:       append([]string{"/bin/sh", "-c"}, sleepCommandForDaemonPlatform()...),
+		OpenStdin: true,
 	}
 
-	status, _, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	status, _, err = request.SockRequest("POST", "/containers/"+name+"/start", nil, daemonHost())
+	_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, name)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+
+	err = cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
+	c.Assert(err, checker.IsNil)
 
 	// second call to start should give 304
-	status, _, err = request.SockRequest("POST", "/containers/"+name+"/start", nil, daemonHost())
+	// maybe add ContainerStartWithRaw to test it
+	err = cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
 	c.Assert(err, checker.IsNil)
 
 	// TODO(tibor): figure out why this doesn't work on windows
-	if testEnv.LocalDaemon() {
-		c.Assert(status, checker.Equals, http.StatusNotModified)
-	}
 }
 
 func (s *DockerSuite) TestContainerAPIStop(c *check.C) {
 	name := "test-api-stop"
 	runSleepingContainer(c, "-i", "--name", name)
+	timeout := 30 * time.Second
 
-	status, _, err := request.SockRequest("POST", "/containers/"+name+"/stop?t=30", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerStop(context.Background(), name, &timeout)
+	c.Assert(err, checker.IsNil)
 	c.Assert(waitInspect(name, "{{ .State.Running  }}", "false", 60*time.Second), checker.IsNil)
 
 	// second call to start should give 304
-	status, _, err = request.SockRequest("POST", "/containers/"+name+"/stop?t=30", nil, daemonHost())
+	// maybe add ContainerStartWithRaw to test it
+	err = cli.ContainerStop(context.Background(), name, &timeout)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotModified)
 }
 
 func (s *DockerSuite) TestContainerAPIWait(c *check.C) {
@@ -952,14 +1021,18 @@
 	}
 	dockerCmd(c, "run", "--name", name, "busybox", sleepCmd, "2")
 
-	status, body, err := request.SockRequest("POST", "/containers/"+name+"/wait", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	c.Assert(waitInspect(name, "{{ .State.Running  }}", "false", 60*time.Second), checker.IsNil)
+	defer cli.Close()
 
-	var waitres containertypes.ContainerWaitOKBody
-	c.Assert(json.Unmarshal(body, &waitres), checker.IsNil)
-	c.Assert(waitres.StatusCode, checker.Equals, int64(0))
+	waitresC, errC := cli.ContainerWait(context.Background(), name, "")
+
+	select {
+	case err = <-errC:
+		c.Assert(err, checker.IsNil)
+	case waitres := <-waitresC:
+		c.Assert(waitres.StatusCode, checker.Equals, int64(0))
+	}
 }
 
 func (s *DockerSuite) TestContainerAPICopyNotExistsAnyMore(c *check.C) {
@@ -969,10 +1042,10 @@
 	postData := types.CopyConfig{
 		Resource: "/test.txt",
 	}
-
-	status, _, err := request.SockRequest("POST", "/containers/"+name+"/copy", postData, daemonHost())
+	// no copy in client/
+	res, _, err := request.Post("/containers/"+name+"/copy", request.JSONBody(postData))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNotFound)
 }
 
 func (s *DockerSuite) TestContainerAPICopyPre124(c *check.C) {
@@ -984,12 +1057,12 @@
 		Resource: "/test.txt",
 	}
 
-	status, body, err := request.SockRequest("POST", "/v1.23/containers/"+name+"/copy", postData, daemonHost())
+	res, body, err := request.Post("/v1.23/containers/"+name+"/copy", request.JSONBody(postData))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 
 	found := false
-	for tarReader := tar.NewReader(bytes.NewReader(body)); ; {
+	for tarReader := tar.NewReader(body); ; {
 		h, err := tarReader.Next()
 		if err != nil {
 			if err == io.EOF {
@@ -1005,7 +1078,7 @@
 	c.Assert(found, checker.True)
 }
 
-func (s *DockerSuite) TestContainerAPICopyResourcePathEmptyPr124(c *check.C) {
+func (s *DockerSuite) TestContainerAPICopyResourcePathEmptyPre124(c *check.C) {
 	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
 	name := "test-container-api-copy-resource-empty"
 	dockerCmd(c, "run", "--name", name, "busybox", "touch", "/test.txt")
@@ -1014,10 +1087,12 @@
 		Resource: "",
 	}
 
-	status, body, err := request.SockRequest("POST", "/v1.23/containers/"+name+"/copy", postData, daemonHost())
+	res, body, err := request.Post("/v1.23/containers/"+name+"/copy", request.JSONBody(postData))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
-	c.Assert(string(body), checker.Matches, "Path cannot be empty\n")
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
+	b, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+	c.Assert(string(b), checker.Matches, "Path cannot be empty\n")
 }
 
 func (s *DockerSuite) TestContainerAPICopyResourcePathNotFoundPre124(c *check.C) {
@@ -1029,10 +1104,13 @@
 		Resource: "/notexist",
 	}
 
-	status, body, err := request.SockRequest("POST", "/v1.23/containers/"+name+"/copy", postData, daemonHost())
+	res, body, err := request.Post("/v1.23/containers/"+name+"/copy", request.JSONBody(postData))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
-	c.Assert(string(body), checker.Matches, "Could not find the file /notexist in container "+name+"\n")
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNotFound)
+
+	b, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+	c.Assert(string(b), checker.Matches, "Could not find the file /notexist in container "+name+"\n")
 }
 
 func (s *DockerSuite) TestContainerAPICopyContainerNotFoundPr124(c *check.C) {
@@ -1041,9 +1119,9 @@
 		Resource: "/something",
 	}
 
-	status, _, err := request.SockRequest("POST", "/v1.23/containers/notexists/copy", postData, daemonHost())
+	res, _, err := request.Post("/v1.23/containers/notexists/copy", request.JSONBody(postData))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNotFound)
 }
 
 func (s *DockerSuite) TestContainerAPIDelete(c *check.C) {
@@ -1054,27 +1132,38 @@
 
 	dockerCmd(c, "stop", id)
 
-	status, _, err := request.SockRequest("DELETE", "/containers/"+id, nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{})
+	c.Assert(err, checker.IsNil)
 }
 
 func (s *DockerSuite) TestContainerAPIDeleteNotExist(c *check.C) {
-	status, body, err := request.SockRequest("DELETE", "/containers/doesnotexist", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound)
-	c.Assert(getErrorMessage(c, body), checker.Matches, "No such container: doesnotexist")
+	defer cli.Close()
+
+	err = cli.ContainerRemove(context.Background(), "doesnotexist", types.ContainerRemoveOptions{})
+	c.Assert(err.Error(), checker.Contains, "No such container: doesnotexist")
 }
 
 func (s *DockerSuite) TestContainerAPIDeleteForce(c *check.C) {
 	out := runSleepingContainer(c)
-
 	id := strings.TrimSpace(out)
 	c.Assert(waitRun(id), checker.IsNil)
 
-	status, _, err := request.SockRequest("DELETE", "/containers/"+id+"?force=1", nil, daemonHost())
+	removeOptions := types.ContainerRemoveOptions{
+		Force: true,
+	}
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerRemove(context.Background(), id, removeOptions)
+	c.Assert(err, checker.IsNil)
 }
 
 func (s *DockerSuite) TestContainerAPIDeleteRemoveLinks(c *check.C) {
@@ -1093,9 +1182,16 @@
 	links := inspectFieldJSON(c, id2, "HostConfig.Links")
 	c.Assert(links, checker.Equals, "[\"/tlink1:/tlink2/tlink1\"]", check.Commentf("expected to have links between containers"))
 
-	status, b, err := request.SockRequest("DELETE", "/containers/tlink2/tlink1?link=1", nil, daemonHost())
+	removeOptions := types.ContainerRemoveOptions{
+		RemoveLinks: true,
+	}
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	err = cli.ContainerRemove(context.Background(), "tlink2/tlink1", removeOptions)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusNoContent, check.Commentf(string(b)))
 
 	linksPostRm := inspectFieldJSON(c, id2, "HostConfig.Links")
 	c.Assert(linksPostRm, checker.Equals, "null", check.Commentf("call to api deleteContainer links should have removed the specified links"))
@@ -1107,9 +1203,13 @@
 	id := strings.TrimSpace(out)
 	c.Assert(waitRun(id), checker.IsNil)
 
-	status, _, err := request.SockRequest("DELETE", "/containers/"+id, nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusConflict)
+	defer cli.Close()
+
+	err = cli.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{})
+	expected := "cannot remove a running container"
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestContainerAPIDeleteRemoveVolume(c *check.C) {
@@ -1129,9 +1229,18 @@
 	_, err = os.Stat(source)
 	c.Assert(err, checker.IsNil)
 
-	status, _, err := request.SockRequest("DELETE", "/containers/"+id+"?v=1&force=1", nil, daemonHost())
+	removeOptions := types.ContainerRemoveOptions{
+		Force:         true,
+		RemoveVolumes: true,
+	}
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerRemove(context.Background(), id, removeOptions)
+	c.Assert(err, check.IsNil)
+
 	_, err = os.Stat(source)
 	c.Assert(os.IsNotExist(err), checker.True, check.Commentf("expected to get ErrNotExist error, got %v", err))
 }
@@ -1163,31 +1272,38 @@
 	containerID := strings.TrimSpace(out)
 	c.Assert(waitRun(containerID), checker.IsNil)
 
-	statusCode, _, err := request.SockRequest("POST", "/containers/"+containerID+"/stop", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	// 204 No Content is expected, not 200
-	c.Assert(statusCode, checker.Equals, http.StatusNoContent)
+	defer cli.Close()
+
+	err = cli.ContainerStop(context.Background(), containerID, nil)
+	c.Assert(err, checker.IsNil)
 	c.Assert(waitInspect(containerID, "{{ .State.Running  }}", "false", 60*time.Second), checker.IsNil)
 }
 
 // #14170
 func (s *DockerSuite) TestPostContainerAPICreateWithStringOrSliceEntrypoint(c *check.C) {
-	config := struct {
-		Image      string
-		Entrypoint string
-		Cmd        []string
-	}{"busybox", "echo", []string{"hello", "world"}}
-	_, _, err := request.SockRequest("POST", "/containers/create?name=echotest", config, daemonHost())
+	config := containertypes.Config{
+		Image:      "busybox",
+		Entrypoint: []string{"echo"},
+		Cmd:        []string{"hello", "world"},
+	}
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "echotest")
 	c.Assert(err, checker.IsNil)
 	out, _ := dockerCmd(c, "start", "-a", "echotest")
 	c.Assert(strings.TrimSpace(out), checker.Equals, "hello world")
 
 	config2 := struct {
 		Image      string
-		Entrypoint []string
+		Entrypoint string
 		Cmd        []string
-	}{"busybox", []string{"echo"}, []string{"hello", "world"}}
-	_, _, err = request.SockRequest("POST", "/containers/create?name=echotest2", config2, daemonHost())
+	}{"busybox", "echo", []string{"hello", "world"}}
+	_, _, err = request.Post("/containers/create?name=echotest2", request.JSONBody(config2))
 	c.Assert(err, checker.IsNil)
 	out, _ = dockerCmd(c, "start", "-a", "echotest2")
 	c.Assert(strings.TrimSpace(out), checker.Equals, "hello world")
@@ -1195,21 +1311,26 @@
 
 // #14170
 func (s *DockerSuite) TestPostContainersCreateWithStringOrSliceCmd(c *check.C) {
-	config := struct {
-		Image      string
-		Entrypoint string
-		Cmd        string
-	}{"busybox", "echo", "hello world"}
-	_, _, err := request.SockRequest("POST", "/containers/create?name=echotest", config, daemonHost())
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"echo", "hello", "world"},
+	}
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "echotest")
 	c.Assert(err, checker.IsNil)
 	out, _ := dockerCmd(c, "start", "-a", "echotest")
 	c.Assert(strings.TrimSpace(out), checker.Equals, "hello world")
 
 	config2 := struct {
-		Image string
-		Cmd   []string
-	}{"busybox", []string{"echo", "hello", "world"}}
-	_, _, err = request.SockRequest("POST", "/containers/create?name=echotest2", config2, daemonHost())
+		Image      string
+		Entrypoint string
+		Cmd        string
+	}{"busybox", "echo", "hello world"}
+	_, _, err = request.Post("/containers/create?name=echotest2", request.JSONBody(config2))
 	c.Assert(err, checker.IsNil)
 	out, _ = dockerCmd(c, "start", "-a", "echotest2")
 	c.Assert(strings.TrimSpace(out), checker.Equals, "hello world")
@@ -1224,29 +1345,37 @@
 		CapAdd  string
 		CapDrop string
 	}{"busybox", "NET_ADMIN", "SYS_ADMIN"}
-	status, _, err := request.SockRequest("POST", "/containers/create?name=capaddtest0", config, daemonHost())
+	res, _, err := request.Post("/containers/create?name=capaddtest0", request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
-	config2 := struct {
-		Image   string
-		CapAdd  []string
-		CapDrop []string
-	}{"busybox", []string{"NET_ADMIN", "SYS_ADMIN"}, []string{"SETGID"}}
-	status, _, err = request.SockRequest("POST", "/containers/create?name=capaddtest1", config2, daemonHost())
+	config2 := containertypes.Config{
+		Image: "busybox",
+	}
+	hostConfig := containertypes.HostConfig{
+		CapAdd:  []string{"NET_ADMIN", "SYS_ADMIN"},
+		CapDrop: []string{"SETGID"},
+	}
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
+
+	_, err = cli.ContainerCreate(context.Background(), &config2, &hostConfig, &networktypes.NetworkingConfig{}, "capaddtest1")
+	c.Assert(err, checker.IsNil)
 }
 
 // #14915
 func (s *DockerSuite) TestContainerAPICreateNoHostConfig118(c *check.C) {
 	testRequires(c, DaemonIsLinux) // Windows only support 1.25 or later
-	config := struct {
-		Image string
-	}{"busybox"}
-	status, _, err := request.SockRequest("POST", "/v1.18/containers/create", config, daemonHost())
+	config := containertypes.Config{
+		Image: "busybox",
+	}
+
+	cli, err := request.NewEnvClientWithVersion("v1.18")
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
 }
 
 // Ensure an error occurs when you have a container read-only rootfs but you
@@ -1271,88 +1400,83 @@
 	// Attempt to extract to a symlink in the volume which points to a
 	// directory outside the volume. This should cause an error because the
 	// rootfs is read-only.
-	query := make(url.Values, 1)
-	query.Set("path", "/vol2/symlinkToAbsDir")
-	urlPath := fmt.Sprintf("/v1.20/containers/%s/archive?%s", cID, query.Encode())
-
-	statusCode, body, err := request.SockRequest("PUT", urlPath, nil, daemonHost())
+	var httpClient *http.Client
+	cli, err := client.NewClient(daemonHost(), "v1.20", httpClient, map[string]string{})
 	c.Assert(err, checker.IsNil)
 
-	if !isCpCannotCopyReadOnly(fmt.Errorf(string(body))) {
-		c.Fatalf("expected ErrContainerRootfsReadonly error, but got %d: %s", statusCode, string(body))
-	}
-}
-
-func (s *DockerSuite) TestContainerAPIGetContainersJSONEmpty(c *check.C) {
-	status, body, err := request.SockRequest("GET", "/containers/json?all=1", nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	c.Assert(string(body), checker.Equals, "[]\n")
+	err = cli.CopyToContainer(context.Background(), cID, "/vol2/symlinkToAbsDir", nil, types.CopyToContainerOptions{})
+	c.Assert(err.Error(), checker.Contains, "container rootfs is marked read-only")
 }
 
 func (s *DockerSuite) TestPostContainersCreateWithWrongCpusetValues(c *check.C) {
 	// Not supported on Windows
 	testRequires(c, DaemonIsLinux)
 
-	c1 := struct {
-		Image      string
-		CpusetCpus string
-	}{"busybox", "1-42,,"}
-	name := "wrong-cpuset-cpus"
-	status, body, err := request.SockRequest("POST", "/containers/create?name="+name, c1, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
-	expected := "Invalid value 1-42,, for cpuset cpus"
-	c.Assert(getErrorMessage(c, body), checker.Equals, expected)
+	defer cli.Close()
 
-	c2 := struct {
-		Image      string
-		CpusetMems string
-	}{"busybox", "42-3,1--"}
+	config := containertypes.Config{
+		Image: "busybox",
+	}
+	hostConfig1 := containertypes.HostConfig{
+		Resources: containertypes.Resources{
+			CpusetCpus: "1-42,,",
+		},
+	}
+	name := "wrong-cpuset-cpus"
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig1, &networktypes.NetworkingConfig{}, name)
+	expected := "Invalid value 1-42,, for cpuset cpus"
+	c.Assert(err.Error(), checker.Contains, expected)
+
+	hostConfig2 := containertypes.HostConfig{
+		Resources: containertypes.Resources{
+			CpusetMems: "42-3,1--",
+		},
+	}
 	name = "wrong-cpuset-mems"
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, c2, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig2, &networktypes.NetworkingConfig{}, name)
 	expected = "Invalid value 42-3,1-- for cpuset mems"
-	c.Assert(getErrorMessage(c, body), checker.Equals, expected)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestPostContainersCreateShmSizeNegative(c *check.C) {
 	// ShmSize is not supported on Windows
 	testRequires(c, DaemonIsLinux)
-	config := map[string]interface{}{
-		"Image":      "busybox",
-		"HostConfig": map[string]interface{}{"ShmSize": -1},
+	config := containertypes.Config{
+		Image: "busybox",
+	}
+	hostConfig := containertypes.HostConfig{
+		ShmSize: -1,
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
-	c.Assert(getErrorMessage(c, body), checker.Contains, "SHM size can not be less than 0")
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
+	c.Assert(err.Error(), checker.Contains, "SHM size can not be less than 0")
 }
 
 func (s *DockerSuite) TestPostContainersCreateShmSizeHostConfigOmitted(c *check.C) {
 	// ShmSize is not supported on Windows
 	testRequires(c, DaemonIsLinux)
 	var defaultSHMSize int64 = 67108864
-	config := map[string]interface{}{
-		"Image": "busybox",
-		"Cmd":   "mount",
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"mount"},
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated)
 
-	var container containertypes.ContainerCreateCreatedBody
-	c.Assert(json.Unmarshal(body, &container), check.IsNil)
-
-	status, body, err = request.SockRequest("GET", "/containers/"+container.ID+"/json", nil, daemonHost())
+	containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
-
-	var containerJSON types.ContainerJSON
-	c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil)
 
 	c.Assert(containerJSON.HostConfig.ShmSize, check.Equals, defaultSHMSize)
 
@@ -1366,25 +1490,20 @@
 func (s *DockerSuite) TestPostContainersCreateShmSizeOmitted(c *check.C) {
 	// ShmSize is not supported on Windows
 	testRequires(c, DaemonIsLinux)
-	config := map[string]interface{}{
-		"Image":      "busybox",
-		"HostConfig": map[string]interface{}{},
-		"Cmd":        "mount",
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"mount"},
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated)
 
-	var container containertypes.ContainerCreateCreatedBody
-	c.Assert(json.Unmarshal(body, &container), check.IsNil)
-
-	status, body, err = request.SockRequest("GET", "/containers/"+container.ID+"/json", nil, daemonHost())
+	containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
-
-	var containerJSON types.ContainerJSON
-	c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil)
 
 	c.Assert(containerJSON.HostConfig.ShmSize, check.Equals, int64(67108864))
 
@@ -1398,25 +1517,24 @@
 func (s *DockerSuite) TestPostContainersCreateWithShmSize(c *check.C) {
 	// ShmSize is not supported on Windows
 	testRequires(c, DaemonIsLinux)
-	config := map[string]interface{}{
-		"Image":      "busybox",
-		"Cmd":        "mount",
-		"HostConfig": map[string]interface{}{"ShmSize": 1073741824},
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"mount"},
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	hostConfig := containertypes.HostConfig{
+		ShmSize: 1073741824,
+	}
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	container, err := cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated)
 
-	var container containertypes.ContainerCreateCreatedBody
-	c.Assert(json.Unmarshal(body, &container), check.IsNil)
-
-	status, body, err = request.SockRequest("GET", "/containers/"+container.ID+"/json", nil, daemonHost())
+	containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
-
-	var containerJSON types.ContainerJSON
-	c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil)
 
 	c.Assert(containerJSON.HostConfig.ShmSize, check.Equals, int64(1073741824))
 
@@ -1430,23 +1548,19 @@
 func (s *DockerSuite) TestPostContainersCreateMemorySwappinessHostConfigOmitted(c *check.C) {
 	// Swappiness is not supported on Windows
 	testRequires(c, DaemonIsLinux)
-	config := map[string]interface{}{
-		"Image": "busybox",
+	config := containertypes.Config{
+		Image: "busybox",
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create", config, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	container, err := cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, "")
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated)
 
-	var container containertypes.ContainerCreateCreatedBody
-	c.Assert(json.Unmarshal(body, &container), check.IsNil)
-
-	status, body, err = request.SockRequest("GET", "/containers/"+container.ID+"/json", nil, daemonHost())
+	containerJSON, err := cli.ContainerInspect(context.Background(), container.ID)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
-
-	var containerJSON types.ContainerJSON
-	c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil)
 
 	c.Assert(containerJSON.HostConfig.MemorySwappiness, check.IsNil)
 }
@@ -1456,42 +1570,43 @@
 	// OomScoreAdj is not supported on Windows
 	testRequires(c, DaemonIsLinux)
 
-	config := struct {
-		Image       string
-		OomScoreAdj int
-	}{"busybox", 1001}
+	config := containertypes.Config{
+		Image: "busybox",
+	}
+
+	hostConfig := containertypes.HostConfig{
+		OomScoreAdj: 1001,
+	}
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	name := "oomscoreadj-over"
-	status, b, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, name)
 
 	expected := "Invalid value 1001, range for oom score adj is [-1000, 1000]"
-	msg := getErrorMessage(c, b)
-	if !strings.Contains(msg, expected) {
-		c.Fatalf("Expected output to contain %q, got %q", expected, msg)
+	c.Assert(err.Error(), checker.Contains, expected)
+
+	hostConfig = containertypes.HostConfig{
+		OomScoreAdj: -1001,
 	}
 
-	config = struct {
-		Image       string
-		OomScoreAdj int
-	}{"busybox", -1001}
 	name = "oomscoreadj-low"
-	status, b, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, name)
+
 	expected = "Invalid value -1001, range for oom score adj is [-1000, 1000]"
-	msg = getErrorMessage(c, b)
-	if !strings.Contains(msg, expected) {
-		c.Fatalf("Expected output to contain %q, got %q", expected, msg)
-	}
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 // test case for #22210 where an empty container name caused panic.
 func (s *DockerSuite) TestContainerAPIDeleteWithEmptyName(c *check.C) {
-	status, out, err := request.SockRequest("DELETE", "/containers/", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
-	c.Assert(string(out), checker.Contains, "No container name or ID supplied")
+	defer cli.Close()
+
+	err = cli.ContainerRemove(context.Background(), "", types.ContainerRemoveOptions{})
+	c.Assert(err.Error(), checker.Contains, "No such container")
 }
 
 func (s *DockerSuite) TestContainerAPIStatsWithNetworkDisabled(c *check.C) {
@@ -1499,31 +1614,33 @@
 	testRequires(c, DaemonIsLinux)
 
 	name := "testing-network-disabled"
-	config := map[string]interface{}{
-		"Image":           "busybox",
-		"Cmd":             []string{"top"},
-		"NetworkDisabled": true,
+
+	config := containertypes.Config{
+		Image:           "busybox",
+		Cmd:             []string{"top"},
+		NetworkDisabled: true,
 	}
 
-	status, _, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	defer cli.Close()
 
-	status, _, err = request.SockRequest("POST", "/containers/"+name+"/start", nil, daemonHost())
+	_, err = cli.ContainerCreate(context.Background(), &config, &containertypes.HostConfig{}, &networktypes.NetworkingConfig{}, name)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+
+	err = cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
+	c.Assert(err, checker.IsNil)
 
 	c.Assert(waitRun(name), check.IsNil)
 
 	type b struct {
-		status int
-		body   []byte
-		err    error
+		stats types.ContainerStats
+		err   error
 	}
 	bc := make(chan b, 1)
 	go func() {
-		status, body, err := request.SockRequest("GET", "/containers/"+name+"/stats", nil, daemonHost())
-		bc <- b{status, body, err}
+		stats, err := cli.ContainerStats(context.Background(), name, false)
+		bc <- b{stats, err}
 	}()
 
 	// allow some time to stream the stats from the container
@@ -1537,26 +1654,15 @@
 		c.Fatal("stream was not closed after container was removed")
 	case sr := <-bc:
 		c.Assert(sr.err, checker.IsNil)
-		c.Assert(sr.status, checker.Equals, http.StatusOK)
-
-		// decode only one object from the stream
-		var s *types.Stats
-		dec := json.NewDecoder(bytes.NewBuffer(sr.body))
-		c.Assert(dec.Decode(&s), checker.IsNil)
+		sr.stats.Body.Close()
 	}
 }
 
 func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) {
-	type m mounttypes.Mount
-	type hc struct{ Mounts []m }
-	type cfg struct {
-		Image      string
-		HostConfig hc
-	}
 	type testCase struct {
-		config cfg
-		status int
-		msg    string
+		config     containertypes.Config
+		hostConfig containertypes.HostConfig
+		msg        string
 	}
 
 	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
@@ -1565,78 +1671,82 @@
 
 	cases := []testCase{
 		{
-			config: cfg{
+			config: containertypes.Config{
 				Image: "busybox",
-				HostConfig: hc{
-					Mounts: []m{{
-						Type:   "notreal",
-						Target: destPath}}}},
-			status: http.StatusBadRequest,
-			msg:    "mount type unknown",
+			},
+			hostConfig: containertypes.HostConfig{
+				Mounts: []mounttypes.Mount{{
+					Type:   "notreal",
+					Target: destPath,
+				},
+				},
+			},
+
+			msg: "mount type unknown",
 		},
 		{
-			config: cfg{
+			config: containertypes.Config{
 				Image: "busybox",
-				HostConfig: hc{
-					Mounts: []m{{
-						Type: "bind"}}}},
-			status: http.StatusBadRequest,
-			msg:    "Target must not be empty",
+			},
+			hostConfig: containertypes.HostConfig{
+				Mounts: []mounttypes.Mount{{
+					Type: "bind"}}},
+			msg: "Target must not be empty",
 		},
 		{
-			config: cfg{
+			config: containertypes.Config{
 				Image: "busybox",
-				HostConfig: hc{
-					Mounts: []m{{
-						Type:   "bind",
-						Target: destPath}}}},
-			status: http.StatusBadRequest,
-			msg:    "Source must not be empty",
+			},
+			hostConfig: containertypes.HostConfig{
+				Mounts: []mounttypes.Mount{{
+					Type:   "bind",
+					Target: destPath}}},
+			msg: "Source must not be empty",
 		},
 		{
-			config: cfg{
+			config: containertypes.Config{
 				Image: "busybox",
-				HostConfig: hc{
-					Mounts: []m{{
-						Type:   "bind",
-						Source: notExistPath,
-						Target: destPath}}}},
-			status: http.StatusBadRequest,
-			msg:    "bind source path does not exist",
+			},
+			hostConfig: containertypes.HostConfig{
+				Mounts: []mounttypes.Mount{{
+					Type:   "bind",
+					Source: notExistPath,
+					Target: destPath}}},
+			msg: "bind source path does not exist",
 		},
 		{
-			config: cfg{
+			config: containertypes.Config{
 				Image: "busybox",
-				HostConfig: hc{
-					Mounts: []m{{
-						Type: "volume"}}}},
-			status: http.StatusBadRequest,
-			msg:    "Target must not be empty",
+			},
+			hostConfig: containertypes.HostConfig{
+				Mounts: []mounttypes.Mount{{
+					Type: "volume"}}},
+			msg: "Target must not be empty",
 		},
 		{
-			config: cfg{
+			config: containertypes.Config{
 				Image: "busybox",
-				HostConfig: hc{
-					Mounts: []m{{
-						Type:   "volume",
-						Source: "hello",
-						Target: destPath}}}},
-			status: http.StatusCreated,
-			msg:    "",
+			},
+			hostConfig: containertypes.HostConfig{
+				Mounts: []mounttypes.Mount{{
+					Type:   "volume",
+					Source: "hello",
+					Target: destPath}}},
+			msg: "",
 		},
 		{
-			config: cfg{
+			config: containertypes.Config{
 				Image: "busybox",
-				HostConfig: hc{
-					Mounts: []m{{
-						Type:   "volume",
-						Source: "hello2",
-						Target: destPath,
-						VolumeOptions: &mounttypes.VolumeOptions{
-							DriverConfig: &mounttypes.Driver{
-								Name: "local"}}}}}},
-			status: http.StatusCreated,
-			msg:    "",
+			},
+			hostConfig: containertypes.HostConfig{
+				Mounts: []mounttypes.Mount{{
+					Type:   "volume",
+					Source: "hello2",
+					Target: destPath,
+					VolumeOptions: &mounttypes.VolumeOptions{
+						DriverConfig: &mounttypes.Driver{
+							Name: "local"}}}}},
+			msg: "",
 		},
 	}
 
@@ -1646,27 +1756,27 @@
 		defer os.RemoveAll(tmpDir)
 		cases = append(cases, []testCase{
 			{
-				config: cfg{
+				config: containertypes.Config{
 					Image: "busybox",
-					HostConfig: hc{
-						Mounts: []m{{
-							Type:   "bind",
-							Source: tmpDir,
-							Target: destPath}}}},
-				status: http.StatusCreated,
-				msg:    "",
+				},
+				hostConfig: containertypes.HostConfig{
+					Mounts: []mounttypes.Mount{{
+						Type:   "bind",
+						Source: tmpDir,
+						Target: destPath}}},
+				msg: "",
 			},
 			{
-				config: cfg{
+				config: containertypes.Config{
 					Image: "busybox",
-					HostConfig: hc{
-						Mounts: []m{{
-							Type:          "bind",
-							Source:        tmpDir,
-							Target:        destPath,
-							VolumeOptions: &mounttypes.VolumeOptions{}}}}},
-				status: http.StatusBadRequest,
-				msg:    "VolumeOptions must not be specified",
+				},
+				hostConfig: containertypes.HostConfig{
+					Mounts: []mounttypes.Mount{{
+						Type:          "bind",
+						Source:        tmpDir,
+						Target:        destPath,
+						VolumeOptions: &mounttypes.VolumeOptions{}}}},
+				msg: "VolumeOptions must not be specified",
 			},
 		}...)
 	}
@@ -1674,67 +1784,70 @@
 	if DaemonIsLinux() {
 		cases = append(cases, []testCase{
 			{
-				config: cfg{
+				config: containertypes.Config{
 					Image: "busybox",
-					HostConfig: hc{
-						Mounts: []m{{
-							Type:   "volume",
-							Source: "hello3",
-							Target: destPath,
-							VolumeOptions: &mounttypes.VolumeOptions{
-								DriverConfig: &mounttypes.Driver{
-									Name:    "local",
-									Options: map[string]string{"o": "size=1"}}}}}}},
-				status: http.StatusCreated,
-				msg:    "",
+				},
+				hostConfig: containertypes.HostConfig{
+					Mounts: []mounttypes.Mount{{
+						Type:   "volume",
+						Source: "hello3",
+						Target: destPath,
+						VolumeOptions: &mounttypes.VolumeOptions{
+							DriverConfig: &mounttypes.Driver{
+								Name:    "local",
+								Options: map[string]string{"o": "size=1"}}}}}},
+				msg: "",
 			},
 			{
-				config: cfg{
+				config: containertypes.Config{
 					Image: "busybox",
-					HostConfig: hc{
-						Mounts: []m{{
-							Type:   "tmpfs",
-							Target: destPath}}}},
-				status: http.StatusCreated,
-				msg:    "",
+				},
+				hostConfig: containertypes.HostConfig{
+					Mounts: []mounttypes.Mount{{
+						Type:   "tmpfs",
+						Target: destPath}}},
+				msg: "",
 			},
 			{
-				config: cfg{
+				config: containertypes.Config{
 					Image: "busybox",
-					HostConfig: hc{
-						Mounts: []m{{
-							Type:   "tmpfs",
-							Target: destPath,
-							TmpfsOptions: &mounttypes.TmpfsOptions{
-								SizeBytes: 4096 * 1024,
-								Mode:      0700,
-							}}}}},
-				status: http.StatusCreated,
-				msg:    "",
+				},
+				hostConfig: containertypes.HostConfig{
+					Mounts: []mounttypes.Mount{{
+						Type:   "tmpfs",
+						Target: destPath,
+						TmpfsOptions: &mounttypes.TmpfsOptions{
+							SizeBytes: 4096 * 1024,
+							Mode:      0700,
+						}}}},
+				msg: "",
 			},
 
 			{
-				config: cfg{
+				config: containertypes.Config{
 					Image: "busybox",
-					HostConfig: hc{
-						Mounts: []m{{
-							Type:   "tmpfs",
-							Source: "/shouldnotbespecified",
-							Target: destPath}}}},
-				status: http.StatusBadRequest,
-				msg:    "Source must not be specified",
+				},
+				hostConfig: containertypes.HostConfig{
+					Mounts: []mounttypes.Mount{{
+						Type:   "tmpfs",
+						Source: "/shouldnotbespecified",
+						Target: destPath}}},
+				msg: "Source must not be specified",
 			},
 		}...)
 
 	}
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	for i, x := range cases {
 		c.Logf("case %d", i)
-		status, b, err := request.SockRequest("POST", "/containers/create", x.config, daemonHost())
-		c.Assert(err, checker.IsNil)
-		c.Assert(status, checker.Equals, x.status, check.Commentf("%s\n%v", string(b), cases[i].config))
+		_, err = cli.ContainerCreate(context.Background(), &x.config, &x.hostConfig, &networktypes.NetworkingConfig{}, "")
 		if len(x.msg) > 0 {
-			c.Assert(string(b), checker.Contains, x.msg, check.Commentf("%v", cases[i].config))
+			c.Assert(err.Error(), checker.Contains, x.msg, check.Commentf("%v", cases[i].config))
+		} else {
+			c.Assert(err, checker.IsNil)
 		}
 	}
 }
@@ -1749,15 +1862,21 @@
 	defer os.RemoveAll(tmpDir)
 	err = ioutil.WriteFile(filepath.Join(tmpDir, "bar"), []byte("hello"), 666)
 	c.Assert(err, checker.IsNil)
-
-	data := map[string]interface{}{
-		"Image":      "busybox",
-		"Cmd":        []string{"/bin/sh", "-c", "cat /foo/bar"},
-		"HostConfig": map[string]interface{}{"Mounts": []map[string]interface{}{{"Type": "bind", "Source": tmpDir, "Target": destPath}}},
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"/bin/sh", "-c", "cat /foo/bar"},
 	}
-	status, resp, err := request.SockRequest("POST", "/containers/create?name=test", data, daemonHost())
-	c.Assert(err, checker.IsNil, check.Commentf(string(resp)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(resp)))
+	hostConfig := containertypes.HostConfig{
+		Mounts: []mounttypes.Mount{
+			{Type: "bind", Source: tmpDir, Target: destPath},
+		},
+	}
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, "test")
+	c.Assert(err, checker.IsNil)
 
 	out, _ := dockerCmd(c, "start", "-a", "test")
 	c.Assert(out, checker.Equals, "hello")
@@ -1783,18 +1902,38 @@
 	}
 
 	type testCase struct {
-		cfg      mounttypes.Mount
+		spec     mounttypes.Mount
 		expected types.MountPoint
 	}
 
+	var selinuxSharedLabel string
+	if runtime.GOOS == "linux" {
+		selinuxSharedLabel = "z"
+	}
+
 	cases := []testCase{
 		// use literal strings here for `Type` instead of the defined constants in the volume package to keep this honest
 		// Validation of the actual `Mount` struct is done in another test is not needed here
-		{mounttypes.Mount{Type: "volume", Target: destPath}, types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath}},
-		{mounttypes.Mount{Type: "volume", Target: destPath + slash}, types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath}},
-		{mounttypes.Mount{Type: "volume", Target: destPath, Source: "test1"}, types.MountPoint{Type: "volume", Name: "test1", RW: true, Destination: destPath}},
-		{mounttypes.Mount{Type: "volume", Target: destPath, ReadOnly: true, Source: "test2"}, types.MountPoint{Type: "volume", Name: "test2", RW: false, Destination: destPath}},
-		{mounttypes.Mount{Type: "volume", Target: destPath, Source: "test3", VolumeOptions: &mounttypes.VolumeOptions{DriverConfig: &mounttypes.Driver{Name: volume.DefaultDriverName}}}, types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", Name: "test3", RW: true, Destination: destPath}},
+		{
+			spec:     mounttypes.Mount{Type: "volume", Target: destPath},
+			expected: types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath, Mode: selinuxSharedLabel},
+		},
+		{
+			spec:     mounttypes.Mount{Type: "volume", Target: destPath + slash},
+			expected: types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath, Mode: selinuxSharedLabel},
+		},
+		{
+			spec:     mounttypes.Mount{Type: "volume", Target: destPath, Source: "test1"},
+			expected: types.MountPoint{Type: "volume", Name: "test1", RW: true, Destination: destPath, Mode: selinuxSharedLabel},
+		},
+		{
+			spec:     mounttypes.Mount{Type: "volume", Target: destPath, ReadOnly: true, Source: "test2"},
+			expected: types.MountPoint{Type: "volume", Name: "test2", RW: false, Destination: destPath, Mode: selinuxSharedLabel},
+		},
+		{
+			spec:     mounttypes.Mount{Type: "volume", Target: destPath, Source: "test3", VolumeOptions: &mounttypes.VolumeOptions{DriverConfig: &mounttypes.Driver{Name: volume.DefaultDriverName}}},
+			expected: types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", Name: "test3", RW: true, Destination: destPath, Mode: selinuxSharedLabel},
+		},
 	}
 
 	if SameHostDaemon() {
@@ -1803,8 +1942,23 @@
 		c.Assert(err, checker.IsNil)
 		defer os.RemoveAll(tmpDir1)
 		cases = append(cases, []testCase{
-			{mounttypes.Mount{Type: "bind", Source: tmpDir1, Target: destPath}, types.MountPoint{Type: "bind", RW: true, Destination: destPath, Source: tmpDir1}},
-			{mounttypes.Mount{Type: "bind", Source: tmpDir1, Target: destPath, ReadOnly: true}, types.MountPoint{Type: "bind", RW: false, Destination: destPath, Source: tmpDir1}},
+			{
+				spec: mounttypes.Mount{
+					Type:   "bind",
+					Source: tmpDir1,
+					Target: destPath,
+				},
+				expected: types.MountPoint{
+					Type:        "bind",
+					RW:          true,
+					Destination: destPath,
+					Source:      tmpDir1,
+				},
+			},
+			{
+				spec:     mounttypes.Mount{Type: "bind", Source: tmpDir1, Target: destPath, ReadOnly: true},
+				expected: types.MountPoint{Type: "bind", RW: false, Destination: destPath, Source: tmpDir1},
+			},
 		}...)
 
 		// for modes only supported on Linux
@@ -1817,19 +1971,40 @@
 			c.Assert(mount.ForceMount("", tmpDir3, "none", "shared"), checker.IsNil)
 
 			cases = append(cases, []testCase{
-				{mounttypes.Mount{Type: "bind", Source: tmpDir3, Target: destPath}, types.MountPoint{Type: "bind", RW: true, Destination: destPath, Source: tmpDir3}},
-				{mounttypes.Mount{Type: "bind", Source: tmpDir3, Target: destPath, ReadOnly: true}, types.MountPoint{Type: "bind", RW: false, Destination: destPath, Source: tmpDir3}},
-				{mounttypes.Mount{Type: "bind", Source: tmpDir3, Target: destPath, ReadOnly: true, BindOptions: &mounttypes.BindOptions{Propagation: "shared"}}, types.MountPoint{Type: "bind", RW: false, Destination: destPath, Source: tmpDir3, Propagation: "shared"}},
+				{
+					spec:     mounttypes.Mount{Type: "bind", Source: tmpDir3, Target: destPath},
+					expected: types.MountPoint{Type: "bind", RW: true, Destination: destPath, Source: tmpDir3},
+				},
+				{
+					spec:     mounttypes.Mount{Type: "bind", Source: tmpDir3, Target: destPath, ReadOnly: true},
+					expected: types.MountPoint{Type: "bind", RW: false, Destination: destPath, Source: tmpDir3},
+				},
+				{
+					spec:     mounttypes.Mount{Type: "bind", Source: tmpDir3, Target: destPath, ReadOnly: true, BindOptions: &mounttypes.BindOptions{Propagation: "shared"}},
+					expected: types.MountPoint{Type: "bind", RW: false, Destination: destPath, Source: tmpDir3, Propagation: "shared"},
+				},
 			}...)
 		}
 	}
 
 	if testEnv.DaemonPlatform() != "windows" { // Windows does not support volume populate
 		cases = append(cases, []testCase{
-			{mounttypes.Mount{Type: "volume", Target: destPath, VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}}, types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath}},
-			{mounttypes.Mount{Type: "volume", Target: destPath + slash, VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}}, types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath}},
-			{mounttypes.Mount{Type: "volume", Target: destPath, Source: "test4", VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}}, types.MountPoint{Type: "volume", Name: "test4", RW: true, Destination: destPath}},
-			{mounttypes.Mount{Type: "volume", Target: destPath, Source: "test5", ReadOnly: true, VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}}, types.MountPoint{Type: "volume", Name: "test5", RW: false, Destination: destPath}},
+			{
+				spec:     mounttypes.Mount{Type: "volume", Target: destPath, VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}},
+				expected: types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath, Mode: selinuxSharedLabel},
+			},
+			{
+				spec:     mounttypes.Mount{Type: "volume", Target: destPath + slash, VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}},
+				expected: types.MountPoint{Driver: volume.DefaultDriverName, Type: "volume", RW: true, Destination: destPath, Mode: selinuxSharedLabel},
+			},
+			{
+				spec:     mounttypes.Mount{Type: "volume", Target: destPath, Source: "test4", VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}},
+				expected: types.MountPoint{Type: "volume", Name: "test4", RW: true, Destination: destPath, Mode: selinuxSharedLabel},
+			},
+			{
+				spec:     mounttypes.Mount{Type: "volume", Target: destPath, Source: "test5", ReadOnly: true, VolumeOptions: &mounttypes.VolumeOptions{NoCopy: true}},
+				expected: types.MountPoint{Type: "volume", Name: "test5", RW: false, Destination: destPath, Mode: selinuxSharedLabel},
+			},
 		}...)
 	}
 
@@ -1840,93 +2015,124 @@
 	type createResp struct {
 		ID string `json:"Id"`
 	}
+
+	ctx := context.Background()
+	apiclient := testEnv.APIClient()
 	for i, x := range cases {
-		c.Logf("case %d - config: %v", i, x.cfg)
-		status, data, err := request.SockRequest("POST", "/containers/create", wrapper{containertypes.Config{Image: testImg}, containertypes.HostConfig{Mounts: []mounttypes.Mount{x.cfg}}}, daemonHost())
-		c.Assert(err, checker.IsNil, check.Commentf(string(data)))
-		c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(data)))
+		c.Logf("case %d - config: %v", i, x.spec)
+		container, err := apiclient.ContainerCreate(
+			ctx,
+			&containertypes.Config{Image: testImg},
+			&containertypes.HostConfig{Mounts: []mounttypes.Mount{x.spec}},
+			&networktypes.NetworkingConfig{},
+			"")
+		require.NoError(c, err)
 
-		var resp createResp
-		err = json.Unmarshal(data, &resp)
-		c.Assert(err, checker.IsNil, check.Commentf(string(data)))
-		id := resp.ID
+		containerInspect, err := apiclient.ContainerInspect(ctx, container.ID)
+		require.NoError(c, err)
+		mps := containerInspect.Mounts
+		require.Len(c, mps, 1)
+		mountPoint := mps[0]
 
-		var mps []types.MountPoint
-		err = json.NewDecoder(strings.NewReader(inspectFieldJSON(c, id, "Mounts"))).Decode(&mps)
-		c.Assert(err, checker.IsNil)
-		c.Assert(mps, checker.HasLen, 1)
-		c.Assert(mps[0].Destination, checker.Equals, x.expected.Destination)
+		if x.expected.Source != "" {
+			assert.Equal(c, x.expected.Source, mountPoint.Source)
+		}
+		if x.expected.Name != "" {
+			assert.Equal(c, x.expected.Name, mountPoint.Name)
+		}
+		if x.expected.Driver != "" {
+			assert.Equal(c, x.expected.Driver, mountPoint.Driver)
+		}
+		if x.expected.Propagation != "" {
+			assert.Equal(c, x.expected.Propagation, mountPoint.Propagation)
+		}
+		assert.Equal(c, x.expected.RW, mountPoint.RW)
+		assert.Equal(c, x.expected.Type, mountPoint.Type)
+		assert.Equal(c, x.expected.Mode, mountPoint.Mode)
+		assert.Equal(c, x.expected.Destination, mountPoint.Destination)
 
-		if len(x.expected.Source) > 0 {
-			c.Assert(mps[0].Source, checker.Equals, x.expected.Source)
-		}
-		if len(x.expected.Name) > 0 {
-			c.Assert(mps[0].Name, checker.Equals, x.expected.Name)
-		}
-		if len(x.expected.Driver) > 0 {
-			c.Assert(mps[0].Driver, checker.Equals, x.expected.Driver)
-		}
-		c.Assert(mps[0].RW, checker.Equals, x.expected.RW)
-		c.Assert(mps[0].Type, checker.Equals, x.expected.Type)
-		c.Assert(mps[0].Mode, checker.Equals, x.expected.Mode)
-		if len(x.expected.Propagation) > 0 {
-			c.Assert(mps[0].Propagation, checker.Equals, x.expected.Propagation)
-		}
+		err = apiclient.ContainerStart(ctx, container.ID, types.ContainerStartOptions{})
+		require.NoError(c, err)
+		poll.WaitOn(c, containerExit(apiclient, container.ID), poll.WithDelay(time.Second))
 
-		out, _, err := dockerCmdWithError("start", "-a", id)
-		if (x.cfg.Type != "volume" || (x.cfg.VolumeOptions != nil && x.cfg.VolumeOptions.NoCopy)) && testEnv.DaemonPlatform() != "windows" {
-			c.Assert(err, checker.NotNil, check.Commentf("%s\n%v", out, mps[0]))
-		} else {
-			c.Assert(err, checker.IsNil, check.Commentf("%s\n%v", out, mps[0]))
-		}
+		err = apiclient.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{
+			RemoveVolumes: true,
+			Force:         true,
+		})
+		require.NoError(c, err)
 
-		dockerCmd(c, "rm", "-fv", id)
-		if x.cfg.Type == "volume" && len(x.cfg.Source) > 0 {
-			// This should still exist even though we removed the container
-			dockerCmd(c, "volume", "inspect", mps[0].Name)
-		} else {
-			// This should be removed automatically when we removed the container
-			out, _, err := dockerCmdWithError("volume", "inspect", mps[0].Name)
-			c.Assert(err, checker.NotNil, check.Commentf(out))
+		switch {
+
+		// Named volumes still exist after the container is removed
+		case x.spec.Type == "volume" && len(x.spec.Source) > 0:
+			_, err := apiclient.VolumeInspect(ctx, mountPoint.Name)
+			require.NoError(c, err)
+
+		// Bind mounts are never removed with the container
+		case x.spec.Type == "bind":
+
+		// anonymous volumes are removed
+		default:
+			_, err := apiclient.VolumeInspect(ctx, mountPoint.Name)
+			assert.True(c, client.IsErrNotFound(err))
 		}
 	}
 }
 
+func containerExit(apiclient client.APIClient, name string) func(poll.LogT) poll.Result {
+	return func(logT poll.LogT) poll.Result {
+		container, err := apiclient.ContainerInspect(context.Background(), name)
+		if err != nil {
+			return poll.Error(err)
+		}
+		switch container.State.Status {
+		case "created", "running":
+			return poll.Continue("container %s is %s, waiting for exit", name, container.State.Status)
+		}
+		return poll.Success()
+	}
+}
+
 func (s *DockerSuite) TestContainersAPICreateMountsTmpfs(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	type testCase struct {
-		cfg             map[string]interface{}
+		cfg             mounttypes.Mount
 		expectedOptions []string
 	}
 	target := "/foo"
 	cases := []testCase{
 		{
-			cfg: map[string]interface{}{
-				"Type":   "tmpfs",
-				"Target": target},
+			cfg: mounttypes.Mount{
+				Type:   "tmpfs",
+				Target: target},
 			expectedOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime"},
 		},
 		{
-			cfg: map[string]interface{}{
-				"Type":   "tmpfs",
-				"Target": target,
-				"TmpfsOptions": map[string]interface{}{
-					"SizeBytes": 4096 * 1024, "Mode": 0700}},
+			cfg: mounttypes.Mount{
+				Type:   "tmpfs",
+				Target: target,
+				TmpfsOptions: &mounttypes.TmpfsOptions{
+					SizeBytes: 4096 * 1024, Mode: 0700}},
 			expectedOptions: []string{"rw", "nosuid", "nodev", "noexec", "relatime", "size=4096k", "mode=700"},
 		},
 	}
 
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	config := containertypes.Config{
+		Image: "busybox",
+		Cmd:   []string{"/bin/sh", "-c", fmt.Sprintf("mount | grep 'tmpfs on %s'", target)},
+	}
 	for i, x := range cases {
 		cName := fmt.Sprintf("test-tmpfs-%d", i)
-		data := map[string]interface{}{
-			"Image": "busybox",
-			"Cmd": []string{"/bin/sh", "-c",
-				fmt.Sprintf("mount | grep 'tmpfs on %s'", target)},
-			"HostConfig": map[string]interface{}{"Mounts": []map[string]interface{}{x.cfg}},
+		hostConfig := containertypes.HostConfig{
+			Mounts: []mounttypes.Mount{x.cfg},
 		}
-		status, resp, err := request.SockRequest("POST", "/containers/create?name="+cName, data, daemonHost())
-		c.Assert(err, checker.IsNil, check.Commentf(string(resp)))
-		c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(resp)))
+
+		_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &networktypes.NetworkingConfig{}, cName)
+		c.Assert(err, checker.IsNil)
 		out, _ := dockerCmd(c, "start", "-a", cName)
 		for _, option := range x.expectedOptions {
 			c.Assert(out, checker.Contains, option)
diff --git a/integration-cli/docker_api_containers_windows_test.go b/integration-cli/docker_api_containers_windows_test.go
new file mode 100644
index 0000000..4cbe067
--- /dev/null
+++ b/integration-cli/docker_api_containers_windows_test.go
@@ -0,0 +1,71 @@
+// +build windows
+
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"math/rand"
+	"net/http"
+	"strings"
+
+	winio "github.com/Microsoft/go-winio"
+	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/request"
+	"github.com/go-check/check"
+)
+
+func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *check.C) {
+	testRequires(c, SameHostDaemon, DaemonIsWindowsAtLeastBuild(16210)) // Named pipe support was added in RS3
+
+	// Create a host pipe to map into the container
+	hostPipeName := fmt.Sprintf(`\\.\pipe\docker-cli-test-pipe-%x`, rand.Uint64())
+	pc := &winio.PipeConfig{
+		SecurityDescriptor: "D:P(A;;GA;;;AU)", // Allow all users access to the pipe
+	}
+	l, err := winio.ListenPipe(hostPipeName, pc)
+	if err != nil {
+		c.Fatal(err)
+	}
+	defer l.Close()
+
+	// Asynchronously read data that the container writes to the mapped pipe.
+	var b []byte
+	ch := make(chan error)
+	go func() {
+		conn, err := l.Accept()
+		if err == nil {
+			b, err = ioutil.ReadAll(conn)
+			conn.Close()
+		}
+		ch <- err
+	}()
+
+	containerPipeName := `\\.\pipe\docker-cli-test-pipe`
+	text := "hello from a pipe"
+	cmd := fmt.Sprintf("echo %s > %s", text, containerPipeName)
+
+	name := "test-bind-npipe"
+	data := map[string]interface{}{
+		"Image":      testEnv.MinimalBaseImage(),
+		"Cmd":        []string{"cmd", "/c", cmd},
+		"HostConfig": map[string]interface{}{"Mounts": []map[string]interface{}{{"Type": "npipe", "Source": hostPipeName, "Target": containerPipeName}}},
+	}
+
+	status, resp, err := request.SockRequest("POST", "/containers/create?name="+name, data, daemonHost())
+	c.Assert(err, checker.IsNil, check.Commentf(string(resp)))
+	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(resp)))
+
+	status, _, err = request.SockRequest("POST", "/containers/"+name+"/start", nil, daemonHost())
+	c.Assert(err, checker.IsNil)
+	c.Assert(status, checker.Equals, http.StatusNoContent)
+
+	err = <-ch
+	if err != nil {
+		c.Fatal(err)
+	}
+	result := strings.TrimSpace(string(b))
+	if result != text {
+		c.Errorf("expected pipe to contain %s, got %s", text, result)
+	}
+}
diff --git a/integration-cli/docker_api_create_test.go b/integration-cli/docker_api_create_test.go
index e404b6c..760e715 100644
--- a/integration-cli/docker_api_create_test.go
+++ b/integration-cli/docker_api_create_test.go
@@ -11,82 +11,6 @@
 	"github.com/go-check/check"
 )
 
-func (s *DockerSuite) TestAPICreateWithNotExistImage(c *check.C) {
-	name := "test"
-	config := map[string]interface{}{
-		"Image":   "test456:v1",
-		"Volumes": map[string]struct{}{"/tmp": {}},
-	}
-
-	status, body, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusNotFound)
-	expected := "No such image: test456:v1"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
-
-	config2 := map[string]interface{}{
-		"Image":   "test456",
-		"Volumes": map[string]struct{}{"/tmp": {}},
-	}
-
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config2, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusNotFound)
-	expected = "No such image: test456:latest"
-	c.Assert(getErrorMessage(c, body), checker.Equals, expected)
-
-	config3 := map[string]interface{}{
-		"Image": "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
-	}
-
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config3, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusNotFound)
-	expected = "No such image: sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa"
-	c.Assert(getErrorMessage(c, body), checker.Equals, expected)
-
-}
-
-// Test for #25099
-func (s *DockerSuite) TestAPICreateEmptyEnv(c *check.C) {
-	name := "test1"
-	config := map[string]interface{}{
-		"Image": "busybox",
-		"Env":   []string{"", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
-		"Cmd":   []string{"true"},
-	}
-
-	status, body, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
-	expected := "invalid environment variable:"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
-
-	name = "test2"
-	config = map[string]interface{}{
-		"Image": "busybox",
-		"Env":   []string{"=", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
-		"Cmd":   []string{"true"},
-	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
-	expected = "invalid environment variable: ="
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
-
-	name = "test3"
-	config = map[string]interface{}{
-		"Image": "busybox",
-		"Env":   []string{"=foo", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"},
-		"Cmd":   []string{"true"},
-	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
-	expected = "invalid environment variable: =foo"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
-}
-
 func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) {
 	// test invalid Interval in Healthcheck: less than 0s
 	name := "test1"
@@ -99,11 +23,15 @@
 		},
 	}
 
-	status, body, err := request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err := request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected := fmt.Sprintf("Interval in Healthcheck cannot be less than %s", container.MinimumDuration)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid Interval in Healthcheck: larger than 0s but less than 1ms
 	name = "test2"
@@ -115,10 +43,14 @@
 			"Retries":  int(1000),
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid Timeout in Healthcheck: less than 1ms
 	name = "test3"
@@ -130,11 +62,15 @@
 			"Retries":  int(1000),
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected = fmt.Sprintf("Timeout in Healthcheck cannot be less than %s", container.MinimumDuration)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid Retries in Healthcheck: less than 0
 	name = "test4"
@@ -146,11 +82,15 @@
 			"Retries":  int(-10),
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected = "Retries in Healthcheck cannot be negative"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 
 	// test invalid StartPeriod in Healthcheck: not 0 and less than 1ms
 	name = "test3"
@@ -163,9 +103,13 @@
 			"StartPeriod": 100 * time.Microsecond,
 		},
 	}
-	status, body, err = request.SockRequest("POST", "/containers/create?name="+name, config, daemonHost())
+	res, body, err = request.Post("/containers/create?name="+name, request.JSONBody(config))
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
+
+	buf, err = request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
 	expected = fmt.Sprintf("StartPeriod in Healthcheck cannot be less than %s", container.MinimumDuration)
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(getErrorMessage(c, buf), checker.Contains, expected)
 }
diff --git a/integration-cli/docker_api_exec_resize_test.go b/integration-cli/docker_api_exec_resize_test.go
index f43bc2d..961d911 100644
--- a/integration-cli/docker_api_exec_resize_test.go
+++ b/integration-cli/docker_api_exec_resize_test.go
@@ -20,9 +20,9 @@
 	cleanedContainerID := strings.TrimSpace(out)
 
 	endpoint := "/exec/" + cleanedContainerID + "/resize?h=foo&w=bar"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
+	res, _, err := request.Post(endpoint)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 }
 
 // Part of #14845
@@ -36,16 +36,19 @@
 			"Cmd":         []string{"/bin/sh"},
 		}
 		uri := fmt.Sprintf("/containers/%s/exec", name)
-		status, body, err := request.SockRequest("POST", uri, data, daemonHost())
+		res, body, err := request.Post(uri, request.JSONBody(data))
 		if err != nil {
 			return err
 		}
-		if status != http.StatusCreated {
-			return fmt.Errorf("POST %s is expected to return %d, got %d", uri, http.StatusCreated, status)
+		if res.StatusCode != http.StatusCreated {
+			return fmt.Errorf("POST %s is expected to return %d, got %d", uri, http.StatusCreated, res.StatusCode)
 		}
 
+		buf, err := request.ReadBody(body)
+		c.Assert(err, checker.IsNil)
+
 		out := map[string]string{}
-		err = json.Unmarshal(body, &out)
+		err = json.Unmarshal(buf, &out)
 		if err != nil {
 			return fmt.Errorf("ExecCreate returned invalid json. Error: %q", err.Error())
 		}
diff --git a/integration-cli/docker_api_exec_test.go b/integration-cli/docker_api_exec_test.go
index 2539934..6e18df8 100644
--- a/integration-cli/docker_api_exec_test.go
+++ b/integration-cli/docker_api_exec_test.go
@@ -10,10 +10,12 @@
 	"net/http"
 	"time"
 
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 // Regression test for #9414
@@ -21,12 +23,15 @@
 	name := "exec_test"
 	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
 
-	status, body, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), map[string]interface{}{"Cmd": nil}, daemonHost())
+	res, body, err := request.Post(fmt.Sprintf("/containers/%s/exec", name), request.JSONBody(map[string]interface{}{"Cmd": nil}))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
+
+	b, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
 
 	comment := check.Commentf("Expected message when creating exec command with no Cmd specified")
-	c.Assert(getErrorMessage(c, body), checker.Contains, "No exec command specified", comment)
+	c.Assert(getErrorMessage(c, b), checker.Contains, "No exec command specified", comment)
 }
 
 func (s *DockerSuite) TestExecAPICreateNoValidContentType(c *check.C) {
@@ -40,9 +45,9 @@
 
 	res, body, err := request.Post(fmt.Sprintf("/containers/%s/exec", name), request.RawContent(ioutil.NopCloser(jsonData)), request.ContentType("test/plain"))
 	c.Assert(err, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	comment := check.Commentf("Expected message when creating exec command with invalid Content-Type specified")
@@ -56,12 +61,18 @@
 	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
 
 	dockerCmd(c, "pause", name)
-	status, body, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), map[string]interface{}{"Cmd": []string{"true"}}, daemonHost())
+
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusConflict)
+	defer cli.Close()
+
+	config := types.ExecConfig{
+		Cmd: []string{"true"},
+	}
+	_, err = cli.ContainerExecCreate(context.Background(), name, config)
 
 	comment := check.Commentf("Expected message when creating exec command with Container %s is paused", name)
-	c.Assert(getErrorMessage(c, body), checker.Contains, "Container "+name+" is paused, unpause the container before exec", comment)
+	c.Assert(err.Error(), checker.Contains, "Container "+name+" is paused, unpause the container before exec", comment)
 }
 
 func (s *DockerSuite) TestExecAPIStart(c *check.C) {
@@ -109,7 +120,7 @@
 	resp, body, err := request.Post(fmt.Sprintf("/v1.20/exec/%s/start", id), request.RawString(`{"Detach": true}`), request.ContentType("text/plain"))
 	c.Assert(err, checker.IsNil)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	comment := check.Commentf("response body: %s", b)
 	c.Assert(err, checker.IsNil, comment)
 	c.Assert(resp.StatusCode, checker.Equals, http.StatusOK, comment)
@@ -129,22 +140,23 @@
 func (s *DockerSuite) TestExecAPIStartWithDetach(c *check.C) {
 	name := "foo"
 	runSleepingContainer(c, "-d", "-t", "--name", name)
-	data := map[string]interface{}{
-		"cmd":         []string{"true"},
-		"AttachStdin": true,
-	}
-	_, b, err := request.SockRequest("POST", fmt.Sprintf("/containers/%s/exec", name), data, daemonHost())
-	c.Assert(err, checker.IsNil, check.Commentf(string(b)))
 
-	createResp := struct {
-		ID string `json:"Id"`
-	}{}
-	c.Assert(json.Unmarshal(b, &createResp), checker.IsNil, check.Commentf(string(b)))
+	config := types.ExecConfig{
+		Cmd:          []string{"true"},
+		AttachStderr: true,
+	}
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	createResp, err := cli.ContainerExecCreate(context.Background(), name, config)
+	c.Assert(err, checker.IsNil)
 
 	_, body, err := request.Post(fmt.Sprintf("/exec/%s/start", createResp.ID), request.RawString(`{"Detach": true}`), request.JSON)
 	c.Assert(err, checker.IsNil)
 
-	b, err = testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	comment := check.Commentf("response body: %s", b)
 	c.Assert(err, checker.IsNil, comment)
 
@@ -177,7 +189,7 @@
 	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
 
 	id := createExecCmd(c, name, "invalid")
-	startExec(c, id, http.StatusNotFound)
+	startExec(c, id, http.StatusBadRequest)
 	waitForExec(c, id)
 
 	var inspectJSON struct{ ExecIDs []string }
@@ -207,7 +219,7 @@
 	resp, body, err := request.Post(fmt.Sprintf("/exec/%s/start", id), request.RawString(`{"Detach": true}`), request.JSON)
 	c.Assert(err, checker.IsNil)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	comment := check.Commentf("response body: %s", b)
 	c.Assert(err, checker.IsNil, comment)
 	c.Assert(resp.StatusCode, checker.Equals, code, comment)
diff --git a/integration-cli/docker_api_images_test.go b/integration-cli/docker_api_images_test.go
index d44b307..fba69dc 100644
--- a/integration-cli/docker_api_images_test.go
+++ b/integration-cli/docker_api_images_test.go
@@ -1,38 +1,40 @@
 package main
 
 import (
-	"encoding/json"
 	"net/http"
 	"net/http/httptest"
-	"net/url"
 	"strings"
 
 	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/image"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestAPIImagesFilter(c *check.C) {
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	name := "utest:tag1"
 	name2 := "utest/docker:tag2"
 	name3 := "utest:5000/docker:tag3"
 	for _, n := range []string{name, name2, name3} {
 		dockerCmd(c, "tag", "busybox", n)
 	}
-	type image types.ImageSummary
-	getImages := func(filter string) []image {
-		v := url.Values{}
-		v.Set("filter", filter)
-		status, b, err := request.SockRequest("GET", "/images/json?"+v.Encode(), nil, daemonHost())
-		c.Assert(err, checker.IsNil)
-		c.Assert(status, checker.Equals, http.StatusOK)
-
-		var images []image
-		err = json.Unmarshal(b, &images)
+	getImages := func(filter string) []types.ImageSummary {
+		filters := filters.NewArgs()
+		filters.Add("reference", filter)
+		options := types.ImageListOptions{
+			All:     false,
+			Filters: filters,
+		}
+		images, err := cli.ImageList(context.Background(), options)
 		c.Assert(err, checker.IsNil)
 
 		return images
@@ -53,9 +55,7 @@
 }
 
 func (s *DockerSuite) TestAPIImagesSaveAndLoad(c *check.C) {
-	// TODO Windows to Windows CI: Investigate further why this test fails.
 	testRequires(c, Network)
-	testRequires(c, DaemonIsLinux)
 	buildImageSuccessfully(c, "saveandload", build.WithDockerfile("FROM busybox\nENV FOO bar"))
 	id := getIDByName(c, "saveandload")
 
@@ -76,6 +76,10 @@
 }
 
 func (s *DockerSuite) TestAPIImagesDelete(c *check.C) {
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	if testEnv.DaemonPlatform() != "windows" {
 		testRequires(c, Network)
 	}
@@ -85,20 +89,21 @@
 
 	dockerCmd(c, "tag", name, "test:tag1")
 
-	status, _, err := request.SockRequest("DELETE", "/images/"+id, nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusConflict)
+	_, err = cli.ImageRemove(context.Background(), id, types.ImageRemoveOptions{})
+	c.Assert(err.Error(), checker.Contains, "unable to delete")
 
-	status, _, err = request.SockRequest("DELETE", "/images/test:noexist", nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound) //Status Codes:404 – no such image
+	_, err = cli.ImageRemove(context.Background(), "test:noexist", types.ImageRemoveOptions{})
+	c.Assert(err.Error(), checker.Contains, "No such image")
 
-	status, _, err = request.SockRequest("DELETE", "/images/test:tag1", nil, daemonHost())
+	_, err = cli.ImageRemove(context.Background(), "test:tag1", types.ImageRemoveOptions{})
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
 }
 
 func (s *DockerSuite) TestAPIImagesHistory(c *check.C) {
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
 	if testEnv.DaemonPlatform() != "windows" {
 		testRequires(c, Network)
 	}
@@ -106,20 +111,15 @@
 	buildImageSuccessfully(c, name, build.WithDockerfile("FROM busybox\nENV FOO bar"))
 	id := getIDByName(c, name)
 
-	status, body, err := request.SockRequest("GET", "/images/"+id+"/history", nil, daemonHost())
+	historydata, err := cli.ImageHistory(context.Background(), id)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-
-	var historydata []image.HistoryResponseItem
-	err = json.Unmarshal(body, &historydata)
-	c.Assert(err, checker.IsNil, check.Commentf("Error on unmarshal"))
 
 	c.Assert(historydata, checker.Not(checker.HasLen), 0)
 	c.Assert(historydata[0].Tags[0], checker.Equals, "test-api-images-history:latest")
 }
 
 func (s *DockerSuite) TestAPIImagesImportBadSrc(c *check.C) {
-	testRequires(c, Network)
+	testRequires(c, Network, SameHostDaemon)
 
 	server := httptest.NewServer(http.NewServeMux())
 	defer server.Close()
@@ -135,9 +135,8 @@
 	}
 
 	for _, te := range tt {
-		res, b, err := request.SockRequestRaw("POST", strings.Join([]string{"/images/create?fromSrc=", te.fromSrc}, ""), nil, "application/json", daemonHost())
+		res, _, err := request.Post(strings.Join([]string{"/images/create?fromSrc=", te.fromSrc}, ""), request.JSON)
 		c.Assert(err, check.IsNil)
-		b.Close()
 		c.Assert(res.StatusCode, checker.Equals, te.statusExp)
 		c.Assert(res.Header.Get("Content-Type"), checker.Equals, "application/json")
 	}
@@ -158,11 +157,11 @@
 // Test case for 30027: image size reported as -1 in v1.12 client against v1.13 daemon.
 // This test checks to make sure both v1.12 and v1.13 client against v1.13 daemon get correct `Size` after the fix.
 func (s *DockerSuite) TestAPIImagesSizeCompatibility(c *check.C) {
-	status, b, err := request.SockRequest("GET", "/images/json", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	var images []types.ImageSummary
-	err = json.Unmarshal(b, &images)
+	defer cli.Close()
+
+	images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
 	c.Assert(err, checker.IsNil)
 	c.Assert(len(images), checker.Not(checker.Equals), 0)
 	for _, image := range images {
@@ -179,11 +178,12 @@
 		VirtualSize int64
 		Labels      map[string]string
 	}
-	status, b, err = request.SockRequest("GET", "/v1.24/images/json", nil, daemonHost())
+
+	cli, err = request.NewEnvClientWithVersion("v1.24")
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
-	var v124Images []v124Image
-	err = json.Unmarshal(b, &v124Images)
+	defer cli.Close()
+
+	v124Images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
 	c.Assert(err, checker.IsNil)
 	c.Assert(len(v124Images), checker.Not(checker.Equals), 0)
 	for _, image := range v124Images {
diff --git a/integration-cli/docker_api_info_test.go b/integration-cli/docker_api_info_test.go
index 9cb873d..60ca4b9 100644
--- a/integration-cli/docker_api_info_test.go
+++ b/integration-cli/docker_api_info_test.go
@@ -1,21 +1,26 @@
 package main
 
 import (
+	"encoding/json"
 	"net/http"
 
-	"encoding/json"
+	"fmt"
+
 	"github.com/docker/docker/api/types"
+
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestInfoAPI(c *check.C) {
-	endpoint := "/info"
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+	info, err := cli.Info(context.Background())
 	c.Assert(err, checker.IsNil)
 
 	// always shown fields
@@ -37,7 +42,7 @@
 		"ServerVersion",
 		"SecurityOptions"}
 
-	out := string(body)
+	out := fmt.Sprintf("%+v", info)
 	for _, linePrefix := range stringsToCheck {
 		c.Assert(out, checker.Contains, linePrefix)
 	}
@@ -52,7 +57,7 @@
 	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 	c.Assert(err, checker.IsNil)
 
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	var i types.Info
@@ -64,13 +69,15 @@
 
 func (s *DockerSuite) TestInfoAPIVersioned(c *check.C) {
 	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
-	endpoint := "/v1.20/info"
 
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+	res, body, err := request.Get("/v1.20/info")
+	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
 	c.Assert(err, checker.IsNil)
 
-	out := string(body)
+	b, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
+	out := string(b)
 	c.Assert(out, checker.Contains, "ExecutionDriver")
 	c.Assert(out, checker.Contains, "not supported")
 }
diff --git a/integration-cli/docker_api_inspect_test.go b/integration-cli/docker_api_inspect_test.go
index f2aa883..6386354 100644
--- a/integration-cli/docker_api_inspect_test.go
+++ b/integration-cli/docker_api_inspect_test.go
@@ -2,13 +2,14 @@
 
 import (
 	"encoding/json"
-	"net/http"
 	"strings"
 
+	"golang.org/x/net/context"
+
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/versions/v1p20"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/pkg/stringutils"
 	"github.com/go-check/check"
 )
@@ -106,18 +107,14 @@
 
 func (s *DockerSuite) TestInspectAPIImageResponse(c *check.C) {
 	dockerCmd(c, "tag", "busybox:latest", "busybox:mytag")
-
-	endpoint := "/images/busybox/json"
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
-
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	var imageJSON types.ImageInspect
-	err = json.Unmarshal(body, &imageJSON)
-	c.Assert(err, checker.IsNil, check.Commentf("Unable to unmarshal body for latest version"))
+	imageJSON, _, err := cli.ImageInspectWithRaw(context.Background(), "busybox")
+	c.Assert(err, checker.IsNil)
+
 	c.Assert(imageJSON.RepoTags, checker.HasLen, 2)
-
 	c.Assert(stringutils.InSlice(imageJSON.RepoTags, "busybox:latest"), checker.Equals, true)
 	c.Assert(stringutils.InSlice(imageJSON.RepoTags, "busybox:mytag"), checker.Equals, true)
 }
diff --git a/integration-cli/docker_api_inspect_unix_test.go b/integration-cli/docker_api_inspect_unix_test.go
index f7731f3..dae64be 100644
--- a/integration-cli/docker_api_inspect_unix_test.go
+++ b/integration-cli/docker_api_inspect_unix_test.go
@@ -4,12 +4,11 @@
 
 import (
 	"encoding/json"
-	"fmt"
-	"net/http"
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 // #16665
@@ -19,9 +18,10 @@
 
 	name := "cpusetinconfig-pre120"
 	dockerCmd(c, "run", "--name", name, "--cpuset-cpus", "0", "busybox", "true")
-
-	status, body, err := request.SockRequest("GET", fmt.Sprintf("/v1.19/containers/%s/json", name), nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusOK)
+	cli, err := request.NewEnvClientWithVersion("v1.19")
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+	_, body, err := cli.ContainerInspectWithRaw(context.Background(), name, false)
 	c.Assert(err, check.IsNil)
 
 	var inspectJSON map[string]interface{}
diff --git a/integration-cli/docker_api_ipcmode_test.go b/integration-cli/docker_api_ipcmode_test.go
new file mode 100644
index 0000000..07fbbca
--- /dev/null
+++ b/integration-cli/docker_api_ipcmode_test.go
@@ -0,0 +1,222 @@
+// build +linux
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"strings"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/integration-cli/checker"
+	"github.com/docker/docker/integration-cli/cli"
+	"github.com/docker/docker/integration-cli/request"
+	"github.com/go-check/check"
+	"golang.org/x/net/context"
+)
+
+/* testIpcCheckDevExists checks whether a given mount (identified by its
+ * major:minor pair from /proc/self/mountinfo) exists on the host system.
+ *
+ * The format of /proc/self/mountinfo is like:
+ *
+ * 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw
+ *       ^^^^\
+ *            - this is the minor:major we look for
+ */
+func testIpcCheckDevExists(mm string) (bool, error) {
+	f, err := os.Open("/proc/self/mountinfo")
+	if err != nil {
+		return false, err
+	}
+	defer f.Close()
+
+	s := bufio.NewScanner(f)
+	for s.Scan() {
+		fields := strings.Fields(s.Text())
+		if len(fields) < 7 {
+			continue
+		}
+		if fields[2] == mm {
+			return true, nil
+		}
+	}
+
+	if err := s.Err(); err != nil {
+		return false, err
+	}
+
+	return false, nil
+}
+
+// testIpcNonePrivateShareable is a helper function to test "none",
+// "private" and "shareable" modes.
+func testIpcNonePrivateShareable(c *check.C, mode string, mustBeMounted bool, mustBeShared bool) {
+	cfg := container.Config{
+		Image: "busybox",
+		Cmd:   []string{"top"},
+	}
+	hostCfg := container.HostConfig{
+		IpcMode: container.IpcMode(mode),
+	}
+	ctx := context.Background()
+
+	client, err := request.NewClient()
+	c.Assert(err, checker.IsNil)
+
+	resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
+	c.Assert(err, checker.IsNil)
+	c.Assert(len(resp.Warnings), checker.Equals, 0)
+
+	err = client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
+	c.Assert(err, checker.IsNil)
+
+	// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
+	cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
+	mm := cli.DockerCmd(c, "exec", "-i", resp.ID, "sh", "-c", cmd).Combined()
+	if !mustBeMounted {
+		c.Assert(mm, checker.Equals, "")
+		// no more checks to perform
+		return
+	}
+	c.Assert(mm, checker.Matches, "^[0-9]+:[0-9]+$")
+
+	shared, err := testIpcCheckDevExists(mm)
+	c.Assert(err, checker.IsNil)
+	c.Logf("[testIpcPrivateShareable] ipcmode: %v, ipcdev: %v, shared: %v, mustBeShared: %v\n", mode, mm, shared, mustBeShared)
+	c.Assert(shared, checker.Equals, mustBeShared)
+}
+
+/* TestAPIIpcModeNone checks the container "none" IPC mode
+ * (--ipc none) works as expected. It makes sure there is no
+ * /dev/shm mount inside the container.
+ */
+func (s *DockerSuite) TestAPIIpcModeNone(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	testIpcNonePrivateShareable(c, "none", false, false)
+}
+
+/* TestAPIIpcModePrivate checks the container private IPC mode
+ * (--ipc private) works as expected. It gets the minor:major pair
+ * of /dev/shm mount from the container, and makes sure there is no
+ * such pair on the host.
+ */
+func (s *DockerSuite) TestAPIIpcModePrivate(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+	testIpcNonePrivateShareable(c, "private", true, false)
+}
+
+/* TestAPIIpcModeShareable checks the container shareable IPC mode
+ * (--ipc shareable) works as expected. It gets the minor:major pair
+ * of /dev/shm mount from the container, and makes sure such pair
+ * also exists on the host.
+ */
+func (s *DockerSuite) TestAPIIpcModeShareable(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+	testIpcNonePrivateShareable(c, "shareable", true, true)
+}
+
+// testIpcContainer is a helper function to test --ipc container:NNN mode in various scenarios
+func testIpcContainer(s *DockerSuite, c *check.C, donorMode string, mustWork bool) {
+	cfg := container.Config{
+		Image: "busybox",
+		Cmd:   []string{"top"},
+	}
+	hostCfg := container.HostConfig{
+		IpcMode: container.IpcMode(donorMode),
+	}
+	ctx := context.Background()
+
+	client, err := request.NewClient()
+	c.Assert(err, checker.IsNil)
+
+	// create and start the "donor" container
+	resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
+	c.Assert(err, checker.IsNil)
+	c.Assert(len(resp.Warnings), checker.Equals, 0)
+	name1 := resp.ID
+
+	err = client.ContainerStart(ctx, name1, types.ContainerStartOptions{})
+	c.Assert(err, checker.IsNil)
+
+	// create and start the second container
+	hostCfg.IpcMode = container.IpcMode("container:" + name1)
+	resp, err = client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
+	c.Assert(err, checker.IsNil)
+	c.Assert(len(resp.Warnings), checker.Equals, 0)
+	name2 := resp.ID
+
+	err = client.ContainerStart(ctx, name2, types.ContainerStartOptions{})
+	if !mustWork {
+		// start should fail with a specific error
+		c.Assert(err, checker.NotNil)
+		c.Assert(fmt.Sprintf("%v", err), checker.Contains, "non-shareable IPC")
+		// no more checks to perform here
+		return
+	}
+
+	// start should succeed
+	c.Assert(err, checker.IsNil)
+
+	// check that IPC is shared
+	// 1. create a file in the first container
+	cli.DockerCmd(c, "exec", name1, "sh", "-c", "printf covfefe > /dev/shm/bar")
+	// 2. check it's the same file in the second one
+	out := cli.DockerCmd(c, "exec", "-i", name2, "cat", "/dev/shm/bar").Combined()
+	c.Assert(out, checker.Matches, "^covfefe$")
+}
+
+/* TestAPIIpcModeShareableAndContainer checks that a container created with
+ * --ipc container:ID can use IPC of another shareable container.
+ */
+func (s *DockerSuite) TestAPIIpcModeShareableAndContainer(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	testIpcContainer(s, c, "shareable", true)
+}
+
+/* TestAPIIpcModePrivateAndContainer checks that a container created with
+ * --ipc container:ID can NOT use IPC of another private container.
+ */
+func (s *DockerSuite) TestAPIIpcModePrivateAndContainer(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	testIpcContainer(s, c, "private", false)
+}
+
+/* TestAPIIpcModeHost checks that a container created with --ipc host
+ * can use IPC of the host system.
+ */
+func (s *DockerSuite) TestAPIIpcModeHost(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon, NotUserNamespace)
+
+	cfg := container.Config{
+		Image: "busybox",
+		Cmd:   []string{"top"},
+	}
+	hostCfg := container.HostConfig{
+		IpcMode: container.IpcMode("host"),
+	}
+	ctx := context.Background()
+
+	client, err := request.NewClient()
+	c.Assert(err, checker.IsNil)
+
+	resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
+	c.Assert(err, checker.IsNil)
+	c.Assert(len(resp.Warnings), checker.Equals, 0)
+	name := resp.ID
+
+	err = client.ContainerStart(ctx, name, types.ContainerStartOptions{})
+	c.Assert(err, checker.IsNil)
+
+	// check that IPC is shared
+	// 1. create a file inside container
+	cli.DockerCmd(c, "exec", name, "sh", "-c", "printf covfefe > /dev/shm/."+name)
+	// 2. check it's the same on the host
+	bytes, err := ioutil.ReadFile("/dev/shm/." + name)
+	c.Assert(err, checker.IsNil)
+	c.Assert(string(bytes), checker.Matches, "^covfefe$")
+	// 3. clean up
+	cli.DockerCmd(c, "exec", name, "rm", "-f", "/dev/shm/."+name)
+}
diff --git a/integration-cli/docker_api_logs_test.go b/integration-cli/docker_api_logs_test.go
index 5e953b7..1f2a30a 100644
--- a/integration-cli/docker_api_logs_test.go
+++ b/integration-cli/docker_api_logs_test.go
@@ -7,9 +7,12 @@
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestLogsAPIWithStdout(c *check.C) {
@@ -51,13 +54,13 @@
 func (s *DockerSuite) TestLogsAPINoStdoutNorStderr(c *check.C) {
 	name := "logs_test"
 	dockerCmd(c, "run", "-d", "-t", "--name", name, "busybox", "/bin/sh")
-
-	status, body, err := request.SockRequest("GET", fmt.Sprintf("/containers/%s/logs", name), nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
+	_, err = cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{})
 	expected := "Bad parameters: you must choose at least one stream"
-	c.Assert(getErrorMessage(c, body), checker.Contains, expected)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 // Regression test for #12704
diff --git a/integration-cli/docker_api_network_test.go b/integration-cli/docker_api_network_test.go
index 129ec7e..108dd4c 100644
--- a/integration-cli/docker_api_network_test.go
+++ b/integration-cli/docker_api_network_test.go
@@ -76,7 +76,7 @@
 	c.Assert(nr.Name, checker.Equals, "bridge")
 }
 
-func (s *DockerSuite) TestAPINetworkInspect(c *check.C) {
+func (s *DockerSuite) TestAPINetworkInspectBridge(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	// Inspect default bridge network
 	nr := getNetworkResource(c, "bridge")
@@ -94,13 +94,15 @@
 	c.Assert(nr.Internal, checker.Equals, false)
 	c.Assert(nr.EnableIPv6, checker.Equals, false)
 	c.Assert(nr.IPAM.Driver, checker.Equals, "default")
-	c.Assert(len(nr.Containers), checker.Equals, 1)
 	c.Assert(nr.Containers[containerID], checker.NotNil)
 
 	ip, _, err := net.ParseCIDR(nr.Containers[containerID].IPv4Address)
 	c.Assert(err, checker.IsNil)
 	c.Assert(ip.String(), checker.Equals, containerIP)
+}
 
+func (s *DockerSuite) TestAPINetworkInspectUserDefinedNetwork(c *check.C) {
+	testRequires(c, DaemonIsLinux)
 	// IPAM configuration inspect
 	ipam := &network.IPAM{
 		Driver: "default",
@@ -117,7 +119,7 @@
 	id0 := createNetwork(c, config, true)
 	c.Assert(isNetworkAvailable(c, "br0"), checker.Equals, true)
 
-	nr = getNetworkResource(c, id0)
+	nr := getNetworkResource(c, id0)
 	c.Assert(len(nr.IPAM.Config), checker.Equals, 1)
 	c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "172.28.0.0/16")
 	c.Assert(nr.IPAM.Config[0].IPRange, checker.Equals, "172.28.5.0/24")
@@ -280,7 +282,7 @@
 		filterArgs = filters.NewArgs()
 	)
 	filterArgs.Add("name", name)
-	filterJSON, err := filters.ToParam(filterArgs)
+	filterJSON, err := filters.ToJSON(filterArgs)
 	c.Assert(err, checker.IsNil)
 	v.Set("filters", filterJSON)
 
@@ -291,9 +293,16 @@
 	nJSON := []types.NetworkResource{}
 	err = json.NewDecoder(body).Decode(&nJSON)
 	c.Assert(err, checker.IsNil)
-	c.Assert(len(nJSON), checker.Equals, 1)
+	var res string
+	for _, n := range nJSON {
+		// Find exact match
+		if n.Name == name {
+			res = n.ID
+		}
+	}
+	c.Assert(res, checker.Not(checker.Equals), "")
 
-	return nJSON[0].ID
+	return res
 }
 
 func getNetworkResource(c *check.C, id string) *types.NetworkResource {
diff --git a/integration-cli/docker_api_resize_test.go b/integration-cli/docker_api_resize_test.go
index 4a07fc7..8ecf540a 100644
--- a/integration-cli/docker_api_resize_test.go
+++ b/integration-cli/docker_api_resize_test.go
@@ -1,9 +1,12 @@
 package main
 
 import (
+	"context"
 	"net/http"
 	"strings"
 
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
@@ -12,10 +15,15 @@
 func (s *DockerSuite) TestResizeAPIResponse(c *check.C) {
 	out := runSleepingContainer(c, "-d")
 	cleanedContainerID := strings.TrimSpace(out)
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusOK)
+	options := types.ResizeOptions{
+		Height: 40,
+		Width:  40,
+	}
+	err = cli.ContainerResize(context.Background(), cleanedContainerID, options)
 	c.Assert(err, check.IsNil)
 }
 
@@ -24,8 +32,8 @@
 	cleanedContainerID := strings.TrimSpace(out)
 
 	endpoint := "/containers/" + cleanedContainerID + "/resize?h=foo&w=bar"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
+	res, _, err := request.Post(endpoint)
+	c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest)
 	c.Assert(err, check.IsNil)
 }
 
@@ -36,10 +44,15 @@
 	// make sure the exited container is not running
 	dockerCmd(c, "wait", cleanedContainerID)
 
-	endpoint := "/containers/" + cleanedContainerID + "/resize?h=40&w=40"
-	status, body, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, check.Equals, http.StatusInternalServerError)
-	c.Assert(err, check.IsNil)
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(getErrorMessage(c, body), checker.Contains, "is not running", check.Commentf("resize should fail with message 'Container is not running'"))
+	options := types.ResizeOptions{
+		Height: 40,
+		Width:  40,
+	}
+
+	err = cli.ContainerResize(context.Background(), cleanedContainerID, options)
+	c.Assert(err.Error(), checker.Contains, "is not running")
 }
diff --git a/integration-cli/docker_api_session_test.go b/integration-cli/docker_api_session_test.go
index e1ad880..f1c4489 100644
--- a/integration-cli/docker_api_session_test.go
+++ b/integration-cli/docker_api_session_test.go
@@ -5,7 +5,6 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/go-check/check"
 )
 
@@ -29,7 +28,7 @@
 	res, body, err := request.Post("/session")
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
-	buf, err := testutil.ReadBody(body)
+	buf, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	out := string(buf)
@@ -41,7 +40,7 @@
 	})
 	c.Assert(err, checker.IsNil)
 	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
-	buf, err = testutil.ReadBody(body)
+	buf, err = request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 
 	out = string(buf)
diff --git a/integration-cli/docker_api_stats_test.go b/integration-cli/docker_api_stats_test.go
index f1cb5bb..2e8515a 100644
--- a/integration-cli/docker_api_stats_test.go
+++ b/integration-cli/docker_api_stats_test.go
@@ -13,9 +13,11 @@
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/versions"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 var expectedNetworkInterfaceStats = strings.Split("rx_bytes rx_dropped rx_errors rx_packets tx_bytes tx_dropped tx_errors tx_packets", " ")
@@ -260,14 +262,16 @@
 
 func (s *DockerSuite) TestAPIStatsContainerNotFound(c *check.C) {
 	testRequires(c, DaemonIsLinux)
-
-	status, _, err := request.SockRequest("GET", "/containers/nonexistent/stats", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	defer cli.Close()
 
-	status, _, err = request.SockRequest("GET", "/containers/nonexistent/stats?stream=0", nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound)
+	expected := "No such container: nonexistent"
+
+	_, err = cli.ContainerStats(context.Background(), "nonexistent", true)
+	c.Assert(err.Error(), checker.Contains, expected)
+	_, err = cli.ContainerStats(context.Background(), "nonexistent", false)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestAPIStatsNoStreamConnectedContainers(c *check.C) {
diff --git a/integration-cli/docker_api_swarm_config_test.go b/integration-cli/docker_api_swarm_config_test.go
index fab65cc..c01d80f 100644
--- a/integration-cli/docker_api_swarm_config_test.go
+++ b/integration-cli/docker_api_swarm_config_test.go
@@ -3,12 +3,10 @@
 package main
 
 import (
-	"fmt"
-	"net/http"
-
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSwarmSuite) TestAPISwarmConfigsEmptyList(c *check.C) {
@@ -52,9 +50,13 @@
 	c.Assert(config.ID, checker.Equals, id, check.Commentf("config: %v", config))
 
 	d.DeleteConfig(c, config.ID)
-	status, out, err := d.SockRequest("GET", "/configs/"+id, nil)
+
+	cli, err := d.NewClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("config delete: %s", string(out)))
+	defer cli.Close()
+
+	_, _, err = cli.ConfigInspectWithRaw(context.Background(), id)
+	c.Assert(err.Error(), checker.Contains, "No such config")
 }
 
 func (s *DockerSwarmSuite) TestAPISwarmConfigsUpdate(c *check.C) {
@@ -110,9 +112,12 @@
 	config = d.GetConfig(c, id)
 	config.Spec.Data = []byte("TESTINGDATA2")
 
-	url := fmt.Sprintf("/configs/%s/update?version=%d", config.ID, config.Version.Index)
-	status, out, err := d.SockRequest("POST", url, config.Spec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(out)))
+	expected := "only updates to Labels are allowed"
+
+	err = cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
diff --git a/integration-cli/docker_api_swarm_secret_test.go b/integration-cli/docker_api_swarm_secret_test.go
index cb82af8..c30e223 100644
--- a/integration-cli/docker_api_swarm_secret_test.go
+++ b/integration-cli/docker_api_swarm_secret_test.go
@@ -3,12 +3,12 @@
 package main
 
 import (
-	"fmt"
 	"net/http"
 
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSwarmSuite) TestAPISwarmSecretsEmptyList(c *check.C) {
@@ -59,16 +59,17 @@
 	c.Assert(secret.ID, checker.Equals, id, check.Commentf("secret: %v", secret))
 
 	d.DeleteSecret(c, secret.ID)
-	status, out, err := d.SockRequest("GET", "/secrets/"+id, nil)
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("secret delete: %s", string(out)))
 
-	// delete non-existing secret, daemon should return a status code of 404
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	_, _, err = cli.SecretInspectWithRaw(context.Background(), id)
+	c.Assert(err.Error(), checker.Contains, "No such secret")
+
 	id = "non-existing"
-	status, out, err = d.SockRequest("DELETE", "/secrets/"+id, nil)
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("secret delete: %s", string(out)))
-
+	err = cli.SecretRemove(context.Background(), id)
+	c.Assert(err.Error(), checker.Contains, "No such secret: non-existing")
 }
 
 func (s *DockerSwarmSuite) TestAPISwarmSecretsUpdate(c *check.C) {
@@ -124,9 +125,12 @@
 	secret = d.GetSecret(c, id)
 	secret.Spec.Data = []byte("TESTINGDATA2")
 
-	url := fmt.Sprintf("/secrets/%s/update?version=%d", secret.ID, secret.Version.Index)
-	status, out, err := d.SockRequest("POST", url, secret.Spec)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(out)))
+	expected := "only updates to Labels are allowed"
+
+	err = cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec)
+	c.Assert(err.Error(), checker.Contains, expected)
 }
diff --git a/integration-cli/docker_api_swarm_service_test.go b/integration-cli/docker_api_swarm_service_test.go
index 2ec56cc..845453d 100644
--- a/integration-cli/docker_api_swarm_service_test.go
+++ b/integration-cli/docker_api_swarm_service_test.go
@@ -9,6 +9,7 @@
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/api/types/swarm/runtime"
 	"github.com/docker/docker/integration-cli/checker"
@@ -64,14 +65,22 @@
 	id := d.CreateService(c, simpleTestService, setInstances(instances))
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
 
-	// insertDefaults inserts UpdateConfig when service is fetched by ID
-	_, out, err := d.SockRequest("GET", "/services/"+id+"?insertDefaults=true", nil)
-	c.Assert(err, checker.IsNil, check.Commentf("%s", out))
-	c.Assert(string(out), checker.Contains, "UpdateConfig")
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	options := types.ServiceInspectOptions{InsertDefaults: true}
 
 	// insertDefaults inserts UpdateConfig when service is fetched by ID
-	_, out, err = d.SockRequest("GET", "/services/top?insertDefaults=true", nil)
-	c.Assert(err, checker.IsNil, check.Commentf("%s", out))
+	resp, _, err := cli.ServiceInspectWithRaw(context.Background(), id, options)
+	out := fmt.Sprintf("%+v", resp)
+	c.Assert(err, checker.IsNil)
+	c.Assert(out, checker.Contains, "UpdateConfig")
+
+	// insertDefaults inserts UpdateConfig when service is fetched by ID
+	resp, _, err = cli.ServiceInspectWithRaw(context.Background(), "top", options)
+	out = fmt.Sprintf("%+v", resp)
+	c.Assert(err, checker.IsNil)
 	c.Assert(string(out), checker.Contains, "UpdateConfig")
 
 	service := d.GetService(c, id)
@@ -177,7 +186,7 @@
 
 	// Roll back to the previous version. This uses the CLI because
 	// rollback used to be a client-side operation.
-	out, err := daemons[0].Cmd("service", "update", "--rollback", id)
+	out, err := daemons[0].Cmd("service", "update", "--detach", "--rollback", id)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// first batch
@@ -195,7 +204,7 @@
 	// service image at start
 	image1 := "busybox:latest"
 	// target image in update
-	image2 := "testhealth"
+	image2 := "testhealth:latest"
 
 	// service started from this image won't pass health check
 	_, _, err := d.BuildImageWithOut(image2,
@@ -286,7 +295,7 @@
 
 	// Roll back to the previous version. This uses the CLI because
 	// rollback is a client-side operation.
-	out, err := d.Cmd("service", "update", "--rollback", id)
+	out, err := d.Cmd("service", "update", "--detach", "--rollback", id)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// first batch
@@ -331,7 +340,7 @@
 
 	// Roll back to the previous version. This uses the CLI because
 	// rollback used to be a client-side operation.
-	out, err := daemons[0].Cmd("service", "update", "--rollback", id)
+	out, err := daemons[0].Cmd("service", "update", "--detach", "--rollback", id)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
@@ -603,7 +612,8 @@
 
 // Test plugins deployed via swarm services
 func (s *DockerSwarmSuite) TestAPISwarmServicesPlugin(c *check.C) {
-	testRequires(c, DaemonIsLinux, IsAmd64)
+	testRequires(c, ExperimentalDaemon, DaemonIsLinux, IsAmd64)
+
 	reg := setupRegistry(c, false, "", "")
 	defer reg.Close()
 
diff --git a/integration-cli/docker_api_swarm_test.go b/integration-cli/docker_api_swarm_test.go
index 9d24757..8f8b8eb 100644
--- a/integration-cli/docker_api_swarm_test.go
+++ b/integration-cli/docker_api_swarm_test.go
@@ -23,8 +23,10 @@
 	"github.com/docker/docker/api/types/swarm"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/daemon"
+	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/swarmkit/ca"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 var defaultReconciliationTimeout = 30 * time.Second
@@ -228,17 +230,20 @@
 	node := d1.GetNode(c, d1.NodeID)
 	node.Spec.Role = swarm.NodeRoleWorker
 	url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index)
-	status, out, err := d1.SockRequest("POST", url, node.Spec)
+	res, body, err := request.DoOnHost(d1.Sock(), url, request.Method("POST"), request.JSONBody(node.Spec))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(out)))
+	b, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest, check.Commentf("output: %q", string(b)))
+
 	// The warning specific to demoting the last manager is best-effort and
 	// won't appear until the Role field of the demoted manager has been
 	// updated.
 	// Yes, I know this looks silly, but checker.Matches is broken, since
 	// it anchors the regexp contrary to the documentation, and this makes
 	// it impossible to match something that includes a line break.
-	if !strings.Contains(string(out), "last manager of the swarm") {
-		c.Assert(string(out), checker.Contains, "this would result in a loss of quorum")
+	if !strings.Contains(string(b), "last manager of the swarm") {
+		c.Assert(string(b), checker.Contains, "this would result in a loss of quorum")
 	}
 	info, err = d1.SwarmInfo()
 	c.Assert(err, checker.IsNil)
@@ -362,9 +367,11 @@
 	var service swarm.Service
 	simpleTestService(&service)
 	service.Spec.Name = "top2"
-	status, out, err := d1.SockRequest("POST", "/services/create", service.Spec)
+	cli, err := d1.NewClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError, check.Commentf("deadline exceeded", string(out)))
+	defer cli.Close()
+	_, err = cli.ServiceCreate(context.Background(), service.Spec, types.ServiceCreateOptions{})
+	c.Assert(err.Error(), checker.Contains, "deadline exceeded")
 
 	d2.Start(c)
 
@@ -505,17 +512,17 @@
 	req := swarm.InitRequest{
 		ListenAddr: "",
 	}
-	status, _, err := d.SockRequest("POST", "/swarm/init", req)
+	res, _, err := request.DoOnHost(d.Sock(), "/swarm/init", request.Method("POST"), request.JSONBody(req))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 
 	req2 := swarm.JoinRequest{
 		ListenAddr:  "0.0.0.0:2377",
 		RemoteAddrs: []string{""},
 	}
-	status, _, err = d.SockRequest("POST", "/swarm/join", req2)
+	res, _, err = request.DoOnHost(d.Sock(), "/swarm/join", request.Method("POST"), request.JSONBody(req2))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 }
 
 func (s *DockerSwarmSuite) TestAPISwarmForceNewCluster(c *check.C) {
@@ -836,10 +843,11 @@
 	instances = 5
 
 	setInstances(instances)(service)
-	url := fmt.Sprintf("/services/%s/update?version=%d", service.Spec.Name, service.Version.Index)
-	status, out, err := d.SockRequest("POST", url, service.Spec)
+	cli, err := d.NewClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
+	defer cli.Close()
+	_, err = cli.ServiceUpdate(context.Background(), service.Spec.Name, service.Version, service.Spec, types.ServiceUpdateOptions{})
+	c.Assert(err, checker.IsNil)
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
 }
 
@@ -867,51 +875,31 @@
 // This test makes sure the fixes correctly output scopes instead.
 func (s *DockerSwarmSuite) TestAPIDuplicateNetworks(c *check.C) {
 	d := s.AddDaemon(c, true, true)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
 	name := "foo"
-	networkCreateRequest := types.NetworkCreateRequest{
-		Name: name,
-		NetworkCreate: types.NetworkCreate{
-			CheckDuplicate: false,
-		},
+	networkCreate := types.NetworkCreate{
+		CheckDuplicate: false,
 	}
 
-	var n1 types.NetworkCreateResponse
-	networkCreateRequest.NetworkCreate.Driver = "bridge"
+	networkCreate.Driver = "bridge"
 
-	status, out, err := d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(out)))
+	n1, err := cli.NetworkCreate(context.Background(), name, networkCreate)
+	c.Assert(err, checker.IsNil)
 
-	c.Assert(json.Unmarshal(out, &n1), checker.IsNil)
+	networkCreate.Driver = "overlay"
 
-	var n2 types.NetworkCreateResponse
-	networkCreateRequest.NetworkCreate.Driver = "overlay"
+	n2, err := cli.NetworkCreate(context.Background(), name, networkCreate)
+	c.Assert(err, checker.IsNil)
 
-	status, out, err = d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(out)))
-
-	c.Assert(json.Unmarshal(out, &n2), checker.IsNil)
-
-	var r1 types.NetworkResource
-
-	status, out, err = d.SockRequest("GET", "/networks/"+n1.ID, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(out)))
-
-	c.Assert(json.Unmarshal(out, &r1), checker.IsNil)
-
+	r1, err := cli.NetworkInspect(context.Background(), n1.ID, types.NetworkInspectOptions{})
+	c.Assert(err, checker.IsNil)
 	c.Assert(r1.Scope, checker.Equals, "local")
 
-	var r2 types.NetworkResource
-
-	status, out, err = d.SockRequest("GET", "/networks/"+n2.ID, nil)
-	c.Assert(err, checker.IsNil, check.Commentf(string(out)))
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(out)))
-
-	c.Assert(json.Unmarshal(out, &r2), checker.IsNil)
-
+	r2, err := cli.NetworkInspect(context.Background(), n2.ID, types.NetworkInspectOptions{})
+	c.Assert(err, checker.IsNil)
 	c.Assert(r2.Scope, checker.Equals, "swarm")
 }
 
diff --git a/integration-cli/docker_api_test.go b/integration-cli/docker_api_test.go
index 1af77ea..af189b9 100644
--- a/integration-cli/docker_api_test.go
+++ b/integration-cli/docker_api_test.go
@@ -4,17 +4,13 @@
 	"fmt"
 	"io/ioutil"
 	"net/http"
-	"net/http/httptest"
 	"runtime"
 	"strconv"
 	"strings"
 
 	"github.com/docker/docker/api"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
 )
 
@@ -60,29 +56,12 @@
 	c.Assert(strings.TrimSpace(string(content)), checker.Contains, expected)
 }
 
-func (s *DockerSuite) TestAPIDockerAPIVersion(c *check.C) {
-	var svrVersion string
-
-	server := httptest.NewServer(http.HandlerFunc(
-		func(w http.ResponseWriter, r *http.Request) {
-			w.Header().Set("API-Version", api.DefaultVersion)
-			url := r.URL.Path
-			svrVersion = url
-		}))
-	defer server.Close()
-
-	// Test using the env var first
-	result := cli.Docker(cli.Args("-H="+server.URL[7:], "version"), cli.WithEnvironmentVariables(appendBaseEnv(false, "DOCKER_API_VERSION=xxx")...))
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: "API version:  xxx", ExitCode: 1})
-	c.Assert(svrVersion, check.Equals, "/vxxx/version", check.Commentf("%s", result.Compare(icmd.Success)))
-}
-
 func (s *DockerSuite) TestAPIErrorJSON(c *check.C) {
 	httpResp, body, err := request.Post("/containers/create", request.JSONBody(struct{}{}))
 	c.Assert(err, checker.IsNil)
-	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusBadRequest)
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Equals, "application/json")
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(getErrorMessage(c, b), checker.Equals, "Config cannot be empty in order to create a container")
 }
@@ -93,9 +72,9 @@
 	testRequires(c, DaemonIsLinux)
 	httpResp, body, err := request.Post("/v1.23/containers/create", request.JSONBody(struct{}{}))
 	c.Assert(err, checker.IsNil)
-	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusBadRequest)
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Contains, "text/plain")
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(string(b)), checker.Equals, "Config cannot be empty in order to create a container")
 }
@@ -106,7 +85,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusNotFound)
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Equals, "application/json")
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(getErrorMessage(c, b), checker.Equals, "page not found")
 }
@@ -116,7 +95,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(httpResp.StatusCode, checker.Equals, http.StatusNotFound)
 	c.Assert(httpResp.Header.Get("Content-Type"), checker.Contains, "text/plain")
-	b, err := testutil.ReadBody(body)
+	b, err := request.ReadBody(body)
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(string(b)), checker.Equals, "page not found")
 }
diff --git a/integration-cli/docker_api_update_unix_test.go b/integration-cli/docker_api_update_unix_test.go
index 1af6ed1..e2e1b09 100644
--- a/integration-cli/docker_api_update_unix_test.go
+++ b/integration-cli/docker_api_update_unix_test.go
@@ -5,9 +5,11 @@
 import (
 	"strings"
 
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestAPIUpdateContainer(c *check.C) {
@@ -16,12 +18,19 @@
 	testRequires(c, swapMemorySupport)
 
 	name := "apiUpdateContainer"
-	hostConfig := map[string]interface{}{
-		"Memory":     314572800,
-		"MemorySwap": 524288000,
+	updateConfig := container.UpdateConfig{
+		Resources: container.Resources{
+			Memory:     314572800,
+			MemorySwap: 524288000,
+		},
 	}
 	dockerCmd(c, "run", "-d", "--name", name, "-m", "200M", "busybox", "top")
-	_, _, err := request.SockRequest("POST", "/containers/"+name+"/update", hostConfig, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, check.IsNil)
+	defer cli.Close()
+
+	_, err = cli.ContainerUpdate(context.Background(), name, updateConfig)
+
 	c.Assert(err, check.IsNil)
 
 	c.Assert(inspectField(c, name, "HostConfig.Memory"), checker.Equals, "314572800")
diff --git a/integration-cli/docker_api_version_test.go b/integration-cli/docker_api_version_test.go
deleted file mode 100644
index 5f919de..0000000
--- a/integration-cli/docker_api_version_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package main
-
-import (
-	"encoding/json"
-	"net/http"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/dockerversion"
-	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
-	"github.com/go-check/check"
-)
-
-func (s *DockerSuite) TestGetVersion(c *check.C) {
-	status, body, err := request.SockRequest("GET", "/version", nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
-	c.Assert(err, checker.IsNil)
-
-	var v types.Version
-
-	c.Assert(json.Unmarshal(body, &v), checker.IsNil)
-
-	c.Assert(v.Version, checker.Equals, dockerversion.Version, check.Commentf("Version mismatch"))
-}
diff --git a/integration-cli/docker_api_volumes_test.go b/integration-cli/docker_api_volumes_test.go
index f354856..65a9652 100644
--- a/integration-cli/docker_api_volumes_test.go
+++ b/integration-cli/docker_api_volumes_test.go
@@ -1,96 +1,96 @@
 package main
 
 import (
-	"encoding/json"
 	"fmt"
-	"net/http"
 	"path/filepath"
 	"strings"
 	"time"
 
-	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
 	volumetypes "github.com/docker/docker/api/types/volume"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestVolumesAPIList(c *check.C) {
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
-	dockerCmd(c, "run", "-v", prefix+"/foo", "busybox")
+	cid, _ := dockerCmd(c, "run", "-d", "-v", prefix+"/foo", "busybox")
 
-	status, b, err := request.SockRequest("GET", "/volumes", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	var volumes volumetypes.VolumesListOKBody
-	c.Assert(json.Unmarshal(b, &volumes), checker.IsNil)
+	container, err := cli.ContainerInspect(context.Background(), strings.TrimSpace(cid))
+	c.Assert(err, checker.IsNil)
+	vname := container.Mounts[0].Name
 
-	c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
+	volumes, err := cli.VolumeList(context.Background(), filters.Args{})
+	c.Assert(err, checker.IsNil)
+
+	found := false
+	for _, vol := range volumes.Volumes {
+		if vol.Name == vname {
+			found = true
+			break
+		}
+	}
+	c.Assert(found, checker.Equals, true)
 }
 
 func (s *DockerSuite) TestVolumesAPICreate(c *check.C) {
 	config := volumetypes.VolumesCreateBody{
 		Name: "test",
 	}
-	status, b, err := request.SockRequest("POST", "/volumes/create", config, daemonHost())
-	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated, check.Commentf(string(b)))
 
-	var vol types.Volume
-	err = json.Unmarshal(b, &vol)
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	vol, err := cli.VolumeCreate(context.Background(), config)
+	c.Assert(err, check.IsNil)
 
 	c.Assert(filepath.Base(filepath.Dir(vol.Mountpoint)), checker.Equals, config.Name)
 }
 
 func (s *DockerSuite) TestVolumesAPIRemove(c *check.C) {
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
-	dockerCmd(c, "run", "-v", prefix+"/foo", "--name=test", "busybox")
+	cid, _ := dockerCmd(c, "run", "-d", "-v", prefix+"/foo", "--name=test", "busybox")
 
-	status, b, err := request.SockRequest("GET", "/volumes", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK)
+	defer cli.Close()
 
-	var volumes volumetypes.VolumesListOKBody
-	c.Assert(json.Unmarshal(b, &volumes), checker.IsNil)
-	c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
-
-	v := volumes.Volumes[0]
-	status, _, err = request.SockRequest("DELETE", "/volumes/"+v.Name, nil, daemonHost())
+	container, err := cli.ContainerInspect(context.Background(), strings.TrimSpace(cid))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusConflict, check.Commentf("Should not be able to remove a volume that is in use"))
+	vname := container.Mounts[0].Name
+
+	err = cli.VolumeRemove(context.Background(), vname, false)
+	c.Assert(err.Error(), checker.Contains, "volume is in use")
 
 	dockerCmd(c, "rm", "-f", "test")
-	status, data, err := request.SockRequest("DELETE", "/volumes/"+v.Name, nil, daemonHost())
+	err = cli.VolumeRemove(context.Background(), vname, false)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent, check.Commentf(string(data)))
-
 }
 
 func (s *DockerSuite) TestVolumesAPIInspect(c *check.C) {
 	config := volumetypes.VolumesCreateBody{
 		Name: "test",
 	}
+
 	// sampling current time minus a minute so to now have false positive in case of delays
 	now := time.Now().Truncate(time.Minute)
-	status, b, err := request.SockRequest("POST", "/volumes/create", config, daemonHost())
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	_, err = cli.VolumeCreate(context.Background(), config)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusCreated, check.Commentf(string(b)))
 
-	status, b, err = request.SockRequest("GET", "/volumes", nil, daemonHost())
+	vol, err := cli.VolumeInspect(context.Background(), config.Name)
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(b)))
-
-	var volumes volumetypes.VolumesListOKBody
-	c.Assert(json.Unmarshal(b, &volumes), checker.IsNil)
-	c.Assert(len(volumes.Volumes), checker.Equals, 1, check.Commentf("\n%v", volumes.Volumes))
-
-	var vol types.Volume
-	status, b, err = request.SockRequest("GET", "/volumes/"+config.Name, nil, daemonHost())
-	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(b)))
-	c.Assert(json.Unmarshal(b, &vol), checker.IsNil)
 	c.Assert(vol.Name, checker.Equals, config.Name)
 
 	// comparing CreatedAt field time for the new volume to now. Removing a minute from both to avoid false positive
diff --git a/integration-cli/docker_cli_attach_test.go b/integration-cli/docker_cli_attach_test.go
index ff319c0..db43beb 100644
--- a/integration-cli/docker_cli_attach_test.go
+++ b/integration-cli/docker_cli_attach_test.go
@@ -11,8 +11,8 @@
 	"time"
 
 	"github.com/docker/docker/integration-cli/cli"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 const attachWait = 5 * time.Second
@@ -168,7 +168,7 @@
 	dockerCmd(c, "pause", "test")
 
 	result := dockerCmdWithResult("attach", "test")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		Error:    "exit status 1",
 		ExitCode: 1,
 		Err:      "You cannot attach to a paused container, unpause it first",
diff --git a/integration-cli/docker_cli_attach_unix_test.go b/integration-cli/docker_cli_attach_unix_test.go
index 78f55e0..e40d7cf 100644
--- a/integration-cli/docker_cli_attach_unix_test.go
+++ b/integration-cli/docker_cli_attach_unix_test.go
@@ -173,7 +173,7 @@
 	c.Assert(running, checker.Equals, "true", check.Commentf("expected container to still be running"))
 
 	go func() {
-		dockerCmd(c, "kill", id)
+		dockerCmdWithResult("kill", id)
 	}()
 
 	select {
@@ -225,7 +225,7 @@
 	c.Assert(running, checker.Equals, "true", check.Commentf("expected container to still be running"))
 
 	go func() {
-		dockerCmd(c, "kill", id)
+		dockerCmdWithResult("kill", id)
 	}()
 
 	select {
diff --git a/integration-cli/docker_cli_authz_plugin_v2_test.go b/integration-cli/docker_cli_authz_plugin_v2_test.go
index 0143f1c..30026f7 100644
--- a/integration-cli/docker_cli_authz_plugin_v2_test.go
+++ b/integration-cli/docker_cli_authz_plugin_v2_test.go
@@ -4,7 +4,6 @@
 
 import (
 	"fmt"
-	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/daemon"
@@ -31,7 +30,7 @@
 }
 
 func (s *DockerAuthzV2Suite) SetUpTest(c *check.C) {
-	testRequires(c, DaemonIsLinux, Network)
+	testRequires(c, DaemonIsLinux, Network, SameHostDaemon)
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
 	})
@@ -47,13 +46,14 @@
 
 func (s *DockerAuthzV2Suite) TestAuthZPluginAllowNonVolumeRequest(c *check.C) {
 	testRequires(c, DaemonIsLinux, IsAmd64, Network)
+
 	// Install authz plugin
 	_, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", authzPluginNameWithTag)
 	c.Assert(err, checker.IsNil)
 	// start the daemon with the plugin and load busybox, --net=none build fails otherwise
 	// because it needs to pull busybox
 	s.d.Restart(c, "--authorization-plugin="+authzPluginNameWithTag)
-	c.Assert(s.d.LoadBusybox(), check.IsNil)
+	s.d.LoadBusybox(c)
 
 	// defer disabling the plugin
 	defer func() {
@@ -65,14 +65,8 @@
 	}()
 
 	// Ensure docker run command and accompanying docker ps are successful
-	out, err := s.d.Cmd("run", "-d", "busybox", "top")
+	_, err = s.d.Cmd("run", "-d", "busybox", "top")
 	c.Assert(err, check.IsNil)
-
-	id := strings.TrimSpace(out)
-
-	out, err = s.d.Cmd("ps")
-	c.Assert(err, check.IsNil)
-	c.Assert(assertContainerList(out, []string{id}), check.Equals, true)
 }
 
 func (s *DockerAuthzV2Suite) TestAuthZPluginDisable(c *check.C) {
@@ -83,7 +77,7 @@
 	// start the daemon with the plugin and load busybox, --net=none build fails otherwise
 	// because it needs to pull busybox
 	s.d.Restart(c, "--authorization-plugin="+authzPluginNameWithTag)
-	c.Assert(s.d.LoadBusybox(), check.IsNil)
+	s.d.LoadBusybox(c)
 
 	// defer removing the plugin
 	defer func() {
diff --git a/integration-cli/docker_cli_authz_unix_test.go b/integration-cli/docker_cli_authz_unix_test.go
index 959292f..8a1bd02 100644
--- a/integration-cli/docker_cli_authz_unix_test.go
+++ b/integration-cli/docker_cli_authz_unix_test.go
@@ -64,6 +64,7 @@
 }
 
 func (s *DockerAuthzSuite) SetUpTest(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
 	})
@@ -209,7 +210,7 @@
 	s.d.Start(c, "--authorization-plugin="+testAuthZPlugin)
 	s.ctrl.reqRes.Allow = true
 	s.ctrl.resRes.Allow = true
-	c.Assert(s.d.LoadBusybox(), check.IsNil)
+	s.d.LoadBusybox(c)
 
 	// Ensure command successful
 	out, err := s.d.Cmd("run", "-d", "busybox", "top")
@@ -218,12 +219,6 @@
 	id := strings.TrimSpace(out)
 	assertURIRecorded(c, s.ctrl.requestsURIs, "/containers/create")
 	assertURIRecorded(c, s.ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", id))
-
-	out, err = s.d.Cmd("ps")
-	c.Assert(err, check.IsNil)
-	c.Assert(assertContainerList(out, []string{id}), check.Equals, true)
-	c.Assert(s.ctrl.psRequestCnt, check.Equals, 1)
-	c.Assert(s.ctrl.psResponseCnt, check.Equals, 1)
 }
 
 func (s *DockerAuthzSuite) TestAuthZPluginTls(c *check.C) {
@@ -322,7 +317,7 @@
 	s.d.Start(c, "--authorization-plugin="+testAuthZPlugin)
 	s.ctrl.reqRes.Allow = true
 	s.ctrl.resRes.Allow = true
-	c.Assert(s.d.LoadBusybox(), check.IsNil)
+	s.d.LoadBusybox(c)
 
 	startTime := strconv.FormatInt(daemonTime(c).Unix(), 10)
 	// Add another command to to enable event pipelining
@@ -418,7 +413,7 @@
 	s.d.Start(c, "--authorization-plugin="+testAuthZPlugin, "--authorization-plugin="+testAuthZPlugin)
 	s.ctrl.reqRes.Allow = true
 	s.ctrl.resRes.Allow = true
-	c.Assert(s.d.LoadBusybox(), check.IsNil)
+	s.d.LoadBusybox(c)
 
 	tmp, err := ioutil.TempDir("", "test-authz-load-import")
 	c.Assert(err, check.IsNil)
@@ -445,7 +440,7 @@
 	s.d.Start(c, "--debug", "--authorization-plugin="+testAuthZPlugin)
 	s.ctrl.reqRes.Allow = true
 	s.ctrl.resRes.Allow = true
-	c.Assert(s.d.LoadBusybox(), check.IsNil)
+	s.d.LoadBusybox(c)
 
 	daemonURL, err := url.Parse(s.d.Sock())
 
diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go
index 5a3d3ef..f6ab192 100644
--- a/integration-cli/docker_cli_build_test.go
+++ b/integration-cli/docker_cli_build_test.go
@@ -25,10 +25,9 @@
 	"github.com/docker/docker/integration-cli/cli/build/fakestorage"
 	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/stringutils"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
-	"github.com/opencontainers/go-digest"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	digest "github.com/opencontainers/go-digest"
 )
 
 func (s *DockerSuite) TestBuildJSONEmptyRun(c *check.C) {
@@ -1174,12 +1173,13 @@
 	containerCountBefore := getContainerCount(c)
 	name := "testbuildforcerm"
 
-	buildImage(name, cli.WithFlags("--force-rm"), build.WithBuildContext(c,
-		build.WithFile("Dockerfile", `FROM `+minimalBaseImage()+`
+	r := buildImage(name, cli.WithFlags("--force-rm"), build.WithBuildContext(c,
+		build.WithFile("Dockerfile", `FROM busybox
 	RUN true
-	RUN thiswillfail`))).Assert(c, icmd.Expected{
-		ExitCode: 1,
-	})
+	RUN thiswillfail`)))
+	if r.ExitCode != 1 && r.ExitCode != 127 { // different on Linux / Windows
+		c.Fatalf("Wrong exit code")
+	}
 
 	containerCountAfter := getContainerCount(c)
 	if containerCountBefore != containerCountAfter {
@@ -1526,7 +1526,7 @@
 	if err != nil {
 		c.Fatalf("failed to list contents of tmp dir: %s", err)
 	}
-	if err = testutil.CompareDirectoryEntries(entries, entriesFinal); err != nil {
+	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
 		c.Fatalf("context should have been deleted, but wasn't")
 	}
 
@@ -1550,12 +1550,31 @@
 	if err != nil {
 		c.Fatalf("failed to list contents of tmp dir: %s", err)
 	}
-	if err = testutil.CompareDirectoryEntries(entries, entriesFinal); err != nil {
+	if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
 		c.Fatalf("context should have been deleted, but wasn't")
 	}
 
 }
 
+// compareDirectoryEntries compares two sets of FileInfo (usually taken from a directory)
+// and returns an error if different.
+func compareDirectoryEntries(e1 []os.FileInfo, e2 []os.FileInfo) error {
+	var (
+		e1Entries = make(map[string]struct{})
+		e2Entries = make(map[string]struct{})
+	)
+	for _, e := range e1 {
+		e1Entries[e.Name()] = struct{}{}
+	}
+	for _, e := range e2 {
+		e2Entries[e.Name()] = struct{}{}
+	}
+	if !reflect.DeepEqual(e1Entries, e2Entries) {
+		return fmt.Errorf("entries differ")
+	}
+	return nil
+}
+
 func (s *DockerSuite) TestBuildCmd(c *check.C) {
 	name := "testbuildcmd"
 	expected := "[/bin/echo Hello World]"
@@ -3848,7 +3867,7 @@
 		filepath.Join(ctx, "dockerfile2"),
 	} {
 		result := dockerCmdWithResult("build", "-t", name, "--no-cache", "-f", dockerfilePath, ".")
-		c.Assert(result, icmd.Matches, icmd.Expected{
+		result.Assert(c, icmd.Expected{
 			Err:      "must be within the build context",
 			ExitCode: 1,
 		})
@@ -4052,7 +4071,7 @@
 	if err != nil {
 		c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
 	}
-	selfCgroupPaths := testutil.ParseCgroupPaths(string(data))
+	selfCgroupPaths := ParseCgroupPaths(string(data))
 	_, found := selfCgroupPaths["memory"]
 	if !found {
 		c.Fatalf("unable to find self memory cgroup path. CgroupsPath: %v", selfCgroupPaths)
@@ -4524,7 +4543,6 @@
 }
 
 func (s *DockerSuite) TestBuildBuildTimeArgExpansion(c *check.C) {
-	testRequires(c, DaemonIsLinux) // Windows does not support ARG
 	imgName := "bldvarstest"
 
 	wdVar := "WDIR"
@@ -4541,6 +4559,10 @@
 	userVal := "testUser"
 	volVar := "VOL"
 	volVal := "/testVol/"
+	if DaemonIsWindows() {
+		volVal = "C:\\testVol"
+		wdVal = "C:\\tmp"
+	}
 
 	buildImageSuccessfully(c, imgName,
 		cli.WithFlags(
@@ -4576,7 +4598,7 @@
 	)
 
 	res := inspectField(c, imgName, "Config.WorkingDir")
-	c.Check(res, check.Equals, filepath.ToSlash(wdVal))
+	c.Check(filepath.ToSlash(res), check.Equals, filepath.ToSlash(wdVal))
 
 	var resArr []string
 	inspectFieldAndUnmarshall(c, imgName, "Config.Env", &resArr)
diff --git a/integration-cli/docker_cli_build_unix_test.go b/integration-cli/docker_cli_build_unix_test.go
index 11c6823..91a329f 100644
--- a/integration-cli/docker_cli_build_unix_test.go
+++ b/integration-cli/docker_cli_build_unix_test.go
@@ -12,32 +12,33 @@
 	"path/filepath"
 	"regexp"
 	"strings"
+	"syscall"
 	"time"
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build/fakecontext"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
-	"github.com/docker/go-units"
+	units "github.com/docker/go-units"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
 	testRequires(c, cpuCfsQuota)
 	name := "testbuildresourceconstraints"
+	buildLabel := "DockerSuite.TestBuildResourceConstraintsAreUsed"
 
 	ctx := fakecontext.New(c, "", fakecontext.WithDockerfile(`
 	FROM hello-world:frozen
 	RUN ["/hello"]
 	`))
 	cli.Docker(
-		cli.Args("build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "-t", name, "."),
+		cli.Args("build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "--ulimit", "nofile=42", "--label="+buildLabel, "-t", name, "."),
 		cli.InDir(ctx.Dir),
 	).Assert(c, icmd.Success)
 
-	out := cli.DockerCmd(c, "ps", "-lq").Combined()
+	out := cli.DockerCmd(c, "ps", "-lq", "--filter", "label="+buildLabel).Combined()
 	cID := strings.TrimSpace(out)
 
 	type hostConfig struct {
@@ -191,7 +192,7 @@
 	}
 
 	// Get the exit status of `docker build`, check it exited because killed.
-	if err := buildCmd.Wait(); err != nil && !testutil.IsKilled(err) {
+	if err := buildCmd.Wait(); err != nil && !isKilled(err) {
 		c.Fatalf("wait failed during build run: %T %s", err, err)
 	}
 
@@ -202,3 +203,17 @@
 		// ignore, done
 	}
 }
+
+func isKilled(err error) bool {
+	if exitErr, ok := err.(*exec.ExitError); ok {
+		status, ok := exitErr.Sys().(syscall.WaitStatus)
+		if !ok {
+			return false
+		}
+		// status.ExitStatus() is required on Windows because it does not
+		// implement Signal() nor Signaled(). Just check it had a bad exit
+		// status could mean it was killed (and in tests we do kill)
+		return (status.Signaled() && status.Signal() == os.Kill) || status.ExitStatus() != 0
+	}
+	return false
+}
diff --git a/integration-cli/docker_cli_by_digest_test.go b/integration-cli/docker_cli_by_digest_test.go
index c7115c8..0c68271 100644
--- a/integration-cli/docker_cli_by_digest_test.go
+++ b/integration-cli/docker_cli_by_digest_test.go
@@ -407,6 +407,8 @@
 }
 
 func (s *DockerRegistrySuite) TestPsListContainersFilterAncestorImageByDigest(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
+
 	digest, err := setupImage(c)
 	c.Assert(err, checker.IsNil, check.Commentf("error setting up image"))
 
@@ -438,7 +440,7 @@
 
 	// Valid imageReference
 	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageReference)
-	checkPsAncestorFilterOutput(c, out, imageReference, expectedIDs)
+	checkPsAncestorFilterOutput(c, RemoveOutputForExistingElements(out, existingContainers), imageReference, expectedIDs)
 }
 
 func (s *DockerRegistrySuite) TestDeleteImageByIDOnlyPulledByDigest(c *check.C) {
diff --git a/integration-cli/docker_cli_commit_test.go b/integration-cli/docker_cli_commit_test.go
index b054c79..58a50ce 100644
--- a/integration-cli/docker_cli_commit_test.go
+++ b/integration-cli/docker_cli_commit_test.go
@@ -122,7 +122,7 @@
 	imageID = strings.TrimSpace(imageID)
 
 	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
-	prefix = strings.ToUpper(prefix) // Force C: as that's how WORKDIR is normalised on Windows
+	prefix = strings.ToUpper(prefix) // Force C: as that's how WORKDIR is normalized on Windows
 	expected := map[string]string{
 		"Config.ExposedPorts": "map[8080/tcp:{}]",
 		"Config.Env":          "[DEBUG=true test=1 PATH=/foo]",
diff --git a/integration-cli/docker_cli_config_ls_test.go b/integration-cli/docker_cli_config_ls_test.go
index 5c07012..5f002bc 100644
--- a/integration-cli/docker_cli_config_ls_test.go
+++ b/integration-cli/docker_cli_config_ls_test.go
@@ -11,6 +11,7 @@
 )
 
 func (s *DockerSwarmSuite) TestConfigList(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	d := s.AddDaemon(c, true, true)
 
 	testName0 := "test0"
diff --git a/integration-cli/docker_cli_config_test.go b/integration-cli/docker_cli_config_test.go
deleted file mode 100644
index 46fe456..0000000
--- a/integration-cli/docker_cli_config_test.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package main
-
-import (
-	"io/ioutil"
-	"net/http"
-	"net/http/httptest"
-	"os"
-	"path/filepath"
-	"runtime"
-
-	"github.com/docker/docker/api"
-	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/pkg/homedir"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
-	"github.com/go-check/check"
-)
-
-func (s *DockerSuite) TestConfigHTTPHeader(c *check.C) {
-	testRequires(c, UnixCli) // Can't set/unset HOME on windows right now
-	// We either need a level of Go that supports Unsetenv (for cases
-	// when HOME/USERPROFILE isn't set), or we need to be able to use
-	// os/user but user.Current() only works if we aren't statically compiling
-
-	var headers map[string][]string
-
-	server := httptest.NewServer(http.HandlerFunc(
-		func(w http.ResponseWriter, r *http.Request) {
-			w.Header().Set("API-Version", api.DefaultVersion)
-			headers = r.Header
-		}))
-	defer server.Close()
-
-	homeKey := homedir.Key()
-	homeVal := homedir.Get()
-	tmpDir, err := ioutil.TempDir("", "fake-home")
-	c.Assert(err, checker.IsNil)
-	defer os.RemoveAll(tmpDir)
-
-	dotDocker := filepath.Join(tmpDir, ".docker")
-	os.Mkdir(dotDocker, 0600)
-	tmpCfg := filepath.Join(dotDocker, "config.json")
-
-	defer func() { os.Setenv(homeKey, homeVal) }()
-	os.Setenv(homeKey, tmpDir)
-
-	data := `{
-		"HttpHeaders": { "MyHeader": "MyValue" }
-	}`
-
-	err = ioutil.WriteFile(tmpCfg, []byte(data), 0600)
-	c.Assert(err, checker.IsNil)
-
-	result := icmd.RunCommand(dockerBinary, "-H="+server.URL[7:], "ps")
-	result.Assert(c, icmd.Expected{
-		ExitCode: 1,
-		Error:    "exit status 1",
-	})
-
-	c.Assert(headers["User-Agent"], checker.NotNil, check.Commentf("Missing User-Agent"))
-
-	c.Assert(headers["User-Agent"][0], checker.Equals, "Docker-Client/"+os.Getenv("DOCKER_CLI_VERSION")+" ("+runtime.GOOS+")", check.Commentf("Badly formatted User-Agent,out:%v", result.Combined()))
-
-	c.Assert(headers["Myheader"], checker.NotNil)
-	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("Missing/bad header,out:%v", result.Combined()))
-
-}
-
-func (s *DockerSuite) TestConfigDir(c *check.C) {
-	cDir, err := ioutil.TempDir("", "fake-home")
-	c.Assert(err, checker.IsNil)
-	defer os.RemoveAll(cDir)
-
-	// First make sure pointing to empty dir doesn't generate an error
-	dockerCmd(c, "--config", cDir, "ps")
-
-	// Test with env var too
-	icmd.RunCmd(icmd.Cmd{
-		Command: []string{dockerBinary, "ps"},
-		Env:     appendBaseEnv(true, "DOCKER_CONFIG="+cDir),
-	}).Assert(c, icmd.Success)
-
-	// Start a server so we can check to see if the config file was
-	// loaded properly
-	var headers map[string][]string
-
-	server := httptest.NewServer(http.HandlerFunc(
-		func(w http.ResponseWriter, r *http.Request) {
-			headers = r.Header
-		}))
-	defer server.Close()
-
-	// Create a dummy config file in our new config dir
-	data := `{
-		"HttpHeaders": { "MyHeader": "MyValue" }
-	}`
-
-	tmpCfg := filepath.Join(cDir, "config.json")
-	err = ioutil.WriteFile(tmpCfg, []byte(data), 0600)
-	c.Assert(err, checker.IsNil, check.Commentf("Err creating file"))
-
-	env := appendBaseEnv(false)
-
-	icmd.RunCmd(icmd.Cmd{
-		Command: []string{dockerBinary, "--config", cDir, "-H=" + server.URL[7:], "ps"},
-		Env:     env,
-	}).Assert(c, icmd.Expected{
-		ExitCode: 1,
-		Error:    "exit status 1",
-	})
-	c.Assert(headers["Myheader"], checker.NotNil)
-	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps3 - Missing header"))
-
-	// Reset headers and try again using env var this time
-	headers = map[string][]string{}
-	icmd.RunCmd(icmd.Cmd{
-		Command: []string{dockerBinary, "--config", cDir, "-H=" + server.URL[7:], "ps"},
-		Env:     append(env, "DOCKER_CONFIG="+cDir),
-	}).Assert(c, icmd.Expected{
-		ExitCode: 1,
-	})
-	c.Assert(headers["Myheader"], checker.NotNil)
-	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps4 - Missing header"))
-
-	// FIXME(vdemeester) should be a unit test
-	// Reset headers and make sure flag overrides the env var
-	headers = map[string][]string{}
-	icmd.RunCmd(icmd.Cmd{
-		Command: []string{dockerBinary, "--config", cDir, "-H=" + server.URL[7:], "ps"},
-		Env:     append(env, "DOCKER_CONFIG=MissingDir"),
-	}).Assert(c, icmd.Expected{
-		ExitCode: 1,
-	})
-	c.Assert(headers["Myheader"], checker.NotNil)
-	c.Assert(headers["Myheader"][0], checker.Equals, "MyValue", check.Commentf("ps5 - Missing header"))
-
-	// FIXME(vdemeester) should be a unit test
-	// Reset headers and make sure flag overrides the env var.
-	// Almost same as previous but make sure the "MissingDir" isn't
-	// ignore - we don't want to default back to the env var.
-	headers = map[string][]string{}
-	icmd.RunCmd(icmd.Cmd{
-		Command: []string{dockerBinary, "--config", "MissingDir", "-H=" + server.URL[7:], "ps"},
-		Env:     append(env, "DOCKER_CONFIG="+cDir),
-	}).Assert(c, icmd.Expected{
-		ExitCode: 1,
-		Error:    "exit status 1",
-	})
-
-	c.Assert(headers["Myheader"], checker.IsNil, check.Commentf("ps6 - Headers shouldn't be the expected value"))
-}
diff --git a/integration-cli/docker_cli_cp_from_container_test.go b/integration-cli/docker_cli_cp_from_container_test.go
index 116f246..687aec8 100644
--- a/integration-cli/docker_cli_cp_from_container_test.go
+++ b/integration-cli/docker_cli_cp_from_container_test.go
@@ -64,19 +64,17 @@
 	// Try with a file source.
 	srcPath := containerCpPath(containerID, "/file1")
 	dstPath := cpPath(tmpDir, "notExists", "file1")
+	_, dstStatErr := os.Lstat(filepath.Dir(dstPath))
+	c.Assert(os.IsNotExist(dstStatErr), checker.True)
 
 	err := runDockerCp(c, srcPath, dstPath, nil)
-	c.Assert(err, checker.NotNil)
-
-	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
+	c.Assert(err.Error(), checker.Contains, dstStatErr.Error())
 
 	// Try with a directory source.
 	srcPath = containerCpPath(containerID, "/dir1")
 
 	err = runDockerCp(c, srcPath, dstPath, nil)
-	c.Assert(err, checker.NotNil)
-
-	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
+	c.Assert(err.Error(), checker.Contains, dstStatErr.Error())
 }
 
 // Test for error when DST ends in a trailing
diff --git a/integration-cli/docker_cli_cp_test.go b/integration-cli/docker_cli_cp_test.go
index f7ed459..59248d0 100644
--- a/integration-cli/docker_cli_cp_test.go
+++ b/integration-cli/docker_cli_cp_test.go
@@ -11,9 +11,8 @@
 	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 const (
@@ -548,7 +547,7 @@
 	// failed to set up container
 	c.Assert(strings.TrimSpace(out), checker.Equals, "0")
 
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "cp", containerID+":/test", "-"),
 		exec.Command("tar", "-vtf", "-"))
 
diff --git a/integration-cli/docker_cli_cp_to_container_test.go b/integration-cli/docker_cli_cp_to_container_test.go
index 97e9aa1..57a850c 100644
--- a/integration-cli/docker_cli_cp_to_container_test.go
+++ b/integration-cli/docker_cli_cp_to_container_test.go
@@ -2,6 +2,7 @@
 
 import (
 	"os"
+	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
@@ -30,11 +31,11 @@
 
 	srcPath := cpPath(tmpDir, "file1")
 	dstPath := containerCpPath(containerID, "file1")
+	_, srcStatErr := os.Stat(srcPath)
+	c.Assert(os.IsNotExist(srcStatErr), checker.True)
 
 	err := runDockerCp(c, srcPath, dstPath, nil)
-	c.Assert(err, checker.NotNil)
-
-	c.Assert(isCpNotExist(err), checker.True, check.Commentf("expected IsNotExist error, but got %T: %s", err, err))
+	c.Assert(strings.ToLower(err.Error()), checker.Contains, strings.ToLower(srcStatErr.Error()))
 }
 
 // Test for error when SRC ends in a trailing
diff --git a/integration-cli/docker_cli_cp_utils_test.go b/integration-cli/docker_cli_cp_utils_test.go
index 48aff90..402a87e 100644
--- a/integration-cli/docker_cli_cp_utils_test.go
+++ b/integration-cli/docker_cli_cp_utils_test.go
@@ -193,9 +193,7 @@
 
 	args := []string{"cp"}
 
-	for _, param := range params {
-		args = append(args, param)
-	}
+	args = append(args, params...)
 
 	args = append(args, src, dst)
 
@@ -231,7 +229,7 @@
 }
 
 func isCpNotExist(err error) bool {
-	return strings.Contains(err.Error(), "no such file or directory") || strings.Contains(err.Error(), "cannot find the file specified")
+	return strings.Contains(strings.ToLower(err.Error()), "could not find the file")
 }
 
 func isCpDirNotExist(err error) bool {
diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go
index d4eb985..f5fe0da 100644
--- a/integration-cli/docker_cli_create_test.go
+++ b/integration-cli/docker_cli_create_test.go
@@ -14,9 +14,9 @@
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build/fakecontext"
 	"github.com/docker/docker/pkg/stringid"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/docker/go-connections/nat"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 // Make sure we can create a simple container with some args
diff --git a/integration-cli/docker_cli_daemon_plugins_test.go b/integration-cli/docker_cli_daemon_plugins_test.go
index 66c9f6e..10aa514 100644
--- a/integration-cli/docker_cli_daemon_plugins_test.go
+++ b/integration-cli/docker_cli_daemon_plugins_test.go
@@ -9,8 +9,8 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/pkg/mount"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go
index 6a98cab..ccf5054 100644
--- a/integration-cli/docker_cli_daemon_test.go
+++ b/integration-cli/docker_cli_daemon_test.go
@@ -34,12 +34,11 @@
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/stringid"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	units "github.com/docker/go-units"
 	"github.com/docker/libnetwork/iptables"
 	"github.com/docker/libtrust"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/kr/pty"
 	"golang.org/x/sys/unix"
 )
@@ -202,7 +201,7 @@
 	testRequires(c, Devicemapper)
 	s.d.Start(c)
 
-	oldBasesizeBytes := s.d.GetBaseDeviceSize(c)
+	oldBasesizeBytes := getBaseDeviceSize(c, s.d)
 	var newBasesizeBytes int64 = 1073741824 //1GB in bytes
 
 	if newBasesizeBytes < oldBasesizeBytes {
@@ -222,7 +221,7 @@
 	testRequires(c, Devicemapper)
 	s.d.Start(c)
 
-	oldBasesizeBytes := s.d.GetBaseDeviceSize(c)
+	oldBasesizeBytes := getBaseDeviceSize(c, s.d)
 
 	var newBasesizeBytes int64 = 53687091200 //50GB in bytes
 
@@ -233,13 +232,31 @@
 	err := s.d.RestartWithError("--storage-opt", fmt.Sprintf("dm.basesize=%d", newBasesizeBytes))
 	c.Assert(err, check.IsNil, check.Commentf("we should have been able to start the daemon with increased base device size: %v", err))
 
-	basesizeAfterRestart := s.d.GetBaseDeviceSize(c)
+	basesizeAfterRestart := getBaseDeviceSize(c, s.d)
 	newBasesize, err := convertBasesize(newBasesizeBytes)
 	c.Assert(err, check.IsNil, check.Commentf("Error in converting base device size: %v", err))
 	c.Assert(newBasesize, check.Equals, basesizeAfterRestart, check.Commentf("Basesize passed is not equal to Basesize set"))
 	s.d.Stop(c)
 }
 
+func getBaseDeviceSize(c *check.C, d *daemon.Daemon) int64 {
+	info := d.Info(c)
+	for _, statusLine := range info.DriverStatus {
+		key, value := statusLine[0], statusLine[1]
+		if key == "Base Device Size" {
+			return parseDeviceSize(c, value)
+		}
+	}
+	c.Fatal("failed to parse Base Device Size from info")
+	return int64(0)
+}
+
+func parseDeviceSize(c *check.C, raw string) int64 {
+	size, err := units.RAMInBytes(strings.TrimSpace(raw))
+	c.Assert(err, check.IsNil)
+	return size
+}
+
 func convertBasesize(basesizeBytes int64) (int64, error) {
 	basesize := units.HumanSize(float64(basesizeBytes))
 	basesize = strings.Trim(basesize, " ")[:len(basesize)-3]
@@ -817,7 +834,7 @@
 
 	// Start daemon with docker0 bridge
 	result := icmd.RunCommand("ifconfig", defaultNetworkBridge)
-	c.Assert(result, icmd.Matches, icmd.Success)
+	result.Assert(c, icmd.Success)
 
 	s.d.Restart(c, fmt.Sprintf("--cluster-store=%s", discoveryBackend))
 }
@@ -1808,7 +1825,7 @@
 	defer s.d.Stop(c)
 
 	// pull a repository large enough to fill the mount point
-	pullOut, err := s.d.Cmd("pull", "registry:2")
+	pullOut, err := s.d.Cmd("pull", "debian:stretch")
 	c.Assert(err, checker.NotNil, check.Commentf(pullOut))
 	c.Assert(pullOut, checker.Contains, "no space left on device")
 }
@@ -1883,7 +1900,7 @@
 
 	out, err := s.d.Cmd("run", "--name", name, "busybox", "cat", "/proc/self/cgroup")
 	c.Assert(err, checker.IsNil)
-	cgroupPaths := testutil.ParseCgroupPaths(string(out))
+	cgroupPaths := ParseCgroupPaths(string(out))
 	c.Assert(len(cgroupPaths), checker.Not(checker.Equals), 0, check.Commentf("unexpected output - %q", string(out)))
 	out, err = s.d.Cmd("inspect", "-f", "{{.Id}}", name)
 	c.Assert(err, checker.IsNil)
@@ -2088,7 +2105,7 @@
 		ctrBinary,
 		"--address", "unix:///var/run/docker/libcontainerd/docker-containerd.sock",
 		"containers", "resume", cid)
-	t.Assert(result, icmd.Matches, icmd.Success)
+	result.Assert(t, icmd.Success)
 
 	// Give time to containerd to process the command if we don't
 	// the resume event might be received after we do the inspect
@@ -2142,9 +2159,9 @@
 }
 
 func (s *DockerDaemonSuite) TestDaemonStartWithoutColors(c *check.C) {
-	testRequires(c, DaemonIsLinux, NotPpc64le)
+	testRequires(c, DaemonIsLinux)
 
-	infoLog := "\x1b[34mINFO\x1b"
+	infoLog := "\x1b[36mINFO\x1b"
 
 	b := bytes.NewBuffer(nil)
 	done := make(chan bool)
@@ -2192,7 +2209,7 @@
 }
 
 func (s *DockerDaemonSuite) TestDaemonDebugLog(c *check.C) {
-	testRequires(c, DaemonIsLinux, NotPpc64le)
+	testRequires(c, DaemonIsLinux)
 
 	debugLog := "\x1b[37mDEBU\x1b"
 
@@ -2985,6 +3002,167 @@
 	c.Assert(strings.TrimSpace(out), check.Equals, fmt.Sprintf("%v", size))
 }
 
+// this is used to test both "private" and "shareable" daemon default ipc modes
+func testDaemonIpcPrivateShareable(d *daemon.Daemon, c *check.C, mustExist bool) {
+	name := "test-ipcmode"
+	_, err := d.Cmd("run", "-d", "--name", name, "busybox", "top")
+	c.Assert(err, checker.IsNil)
+
+	// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
+	cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
+	mm, err := d.Cmd("exec", "-i", name, "sh", "-c", cmd)
+	c.Assert(err, checker.IsNil)
+	c.Assert(mm, checker.Matches, "^[0-9]+:[0-9]+$")
+
+	exists, err := testIpcCheckDevExists(mm)
+	c.Assert(err, checker.IsNil)
+	c.Logf("[testDaemonIpcPrivateShareable] ipcdev: %v, exists: %v, mustExist: %v\n", mm, exists, mustExist)
+	c.Assert(exists, checker.Equals, mustExist)
+}
+
+// TestDaemonIpcModeShareable checks that --default-ipc-mode shareable works as intended.
+func (s *DockerDaemonSuite) TestDaemonIpcModeShareable(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+
+	s.d.StartWithBusybox(c, "--default-ipc-mode", "shareable")
+	testDaemonIpcPrivateShareable(s.d, c, true)
+}
+
+// TestDaemonIpcModePrivate checks that --default-ipc-mode private works as intended.
+func (s *DockerDaemonSuite) TestDaemonIpcModePrivate(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+
+	s.d.StartWithBusybox(c, "--default-ipc-mode", "private")
+	testDaemonIpcPrivateShareable(s.d, c, false)
+}
+
+// used to check if an IpcMode given in config works as intended
+func testDaemonIpcFromConfig(s *DockerDaemonSuite, c *check.C, mode string, mustExist bool) {
+	f, err := ioutil.TempFile("", "test-daemon-ipc-config")
+	c.Assert(err, checker.IsNil)
+	defer os.Remove(f.Name())
+
+	config := `{"default-ipc-mode": "` + mode + `"}`
+	_, err = f.WriteString(config)
+	c.Assert(f.Close(), checker.IsNil)
+	c.Assert(err, checker.IsNil)
+
+	s.d.StartWithBusybox(c, "--config-file", f.Name())
+	testDaemonIpcPrivateShareable(s.d, c, mustExist)
+}
+
+// TestDaemonIpcModePrivateFromConfig checks that "default-ipc-mode: private" config works as intended.
+func (s *DockerDaemonSuite) TestDaemonIpcModePrivateFromConfig(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+	testDaemonIpcFromConfig(s, c, "private", false)
+}
+
+// TestDaemonIpcModeShareableFromConfig checks that "default-ipc-mode: shareable" config works as intended.
+func (s *DockerDaemonSuite) TestDaemonIpcModeShareableFromConfig(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+	testDaemonIpcFromConfig(s, c, "shareable", true)
+}
+
+func testDaemonStartIpcMode(c *check.C, from, mode string, valid bool) {
+	d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
+		Experimental: testEnv.ExperimentalDaemon(),
+	})
+	c.Logf("Checking IpcMode %s set from %s\n", mode, from)
+	var serr error
+	switch from {
+	case "config":
+		f, err := ioutil.TempFile("", "test-daemon-ipc-config")
+		c.Assert(err, checker.IsNil)
+		defer os.Remove(f.Name())
+		config := `{"default-ipc-mode": "` + mode + `"}`
+		_, err = f.WriteString(config)
+		c.Assert(f.Close(), checker.IsNil)
+		c.Assert(err, checker.IsNil)
+
+		serr = d.StartWithError("--config-file", f.Name())
+	case "cli":
+		serr = d.StartWithError("--default-ipc-mode", mode)
+	default:
+		c.Fatalf("testDaemonStartIpcMode: invalid 'from' argument")
+	}
+	if serr == nil {
+		d.Stop(c)
+	}
+
+	if valid {
+		c.Assert(serr, check.IsNil)
+	} else {
+		c.Assert(serr, check.NotNil)
+		icmd.RunCommand("grep", "-E", "IPC .* is (invalid|not supported)", d.LogFileName()).Assert(c, icmd.Success)
+	}
+}
+
+// TestDaemonStartWithIpcModes checks that daemon starts fine given correct
+// arguments for default IPC mode, and bails out with incorrect ones.
+// Both CLI option (--default-ipc-mode) and config parameter are tested.
+func (s *DockerDaemonSuite) TestDaemonStartWithIpcModes(c *check.C) {
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
+
+	ipcModes := []struct {
+		mode  string
+		valid bool
+	}{
+		{"private", true},
+		{"shareable", true},
+
+		{"host", false},
+		{"container:123", false},
+		{"nosuchmode", false},
+	}
+
+	for _, from := range []string{"config", "cli"} {
+		for _, m := range ipcModes {
+			testDaemonStartIpcMode(c, from, m.mode, m.valid)
+		}
+	}
+}
+
+// TestDaemonRestartIpcMode makes sure a container keeps its ipc mode
+// (derived from daemon default) even after the daemon is restarted
+// with a different default ipc mode.
+func (s *DockerDaemonSuite) TestDaemonRestartIpcMode(c *check.C) {
+	f, err := ioutil.TempFile("", "test-daemon-ipc-config-restart")
+	c.Assert(err, checker.IsNil)
+	file := f.Name()
+	defer os.Remove(file)
+	c.Assert(f.Close(), checker.IsNil)
+
+	config := []byte(`{"default-ipc-mode": "private"}`)
+	c.Assert(ioutil.WriteFile(file, config, 0644), checker.IsNil)
+	s.d.StartWithBusybox(c, "--config-file", file)
+
+	// check the container is created with private ipc mode as per daemon default
+	name := "ipc1"
+	_, err = s.d.Cmd("run", "-d", "--name", name, "--restart=always", "busybox", "top")
+	c.Assert(err, checker.IsNil)
+	m, err := s.d.InspectField(name, ".HostConfig.IpcMode")
+	c.Assert(err, check.IsNil)
+	c.Assert(m, checker.Equals, "private")
+
+	// restart the daemon with shareable default ipc mode
+	config = []byte(`{"default-ipc-mode": "shareable"}`)
+	c.Assert(ioutil.WriteFile(file, config, 0644), checker.IsNil)
+	s.d.Restart(c, "--config-file", file)
+
+	// check the container is still having private ipc mode
+	m, err = s.d.InspectField(name, ".HostConfig.IpcMode")
+	c.Assert(err, check.IsNil)
+	c.Assert(m, checker.Equals, "private")
+
+	// check a new container is created with shareable ipc mode as per new daemon default
+	name = "ipc2"
+	_, err = s.d.Cmd("run", "-d", "--name", name, "busybox", "top")
+	c.Assert(err, checker.IsNil)
+	m, err = s.d.InspectField(name, ".HostConfig.IpcMode")
+	c.Assert(err, check.IsNil)
+	c.Assert(m, checker.Equals, "shareable")
+}
+
 // TestFailedPluginRemove makes sure that a failed plugin remove does not block
 // the daemon from starting
 func (s *DockerDaemonSuite) TestFailedPluginRemove(c *check.C) {
diff --git a/integration-cli/docker_cli_events_test.go b/integration-cli/docker_cli_events_test.go
index 0bbc986..e179a0e 100644
--- a/integration-cli/docker_cli_events_test.go
+++ b/integration-cli/docker_cli_events_test.go
@@ -6,21 +6,21 @@
 	"fmt"
 	"io"
 	"io/ioutil"
-	"net/http"
 	"os"
 	"os/exec"
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api/types"
 	eventtypes "github.com/docker/docker/api/types/events"
+	"github.com/docker/docker/client"
 	eventstestutils "github.com/docker/docker/daemon/events/testutils"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
-	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestEventsTimestampFormats(c *check.C) {
@@ -36,7 +36,7 @@
 	// List of available time formats to --since
 	unixTs := func(t time.Time) string { return fmt.Sprintf("%v", t.Unix()) }
 	rfc3339 := func(t time.Time) string { return t.Format(time.RFC3339) }
-	duration := func(t time.Time) string { return time.Now().Sub(t).String() }
+	duration := func(t time.Time) string { return time.Since(t).String() }
 
 	// --since=$start must contain only the 'untag' event
 	for _, f := range []func(time.Time) string{unixTs, rfc3339, duration} {
@@ -69,7 +69,7 @@
 		Command: []string{dockerBinary, "events", "--since=1"},
 		Timeout: time.Millisecond * 2500,
 	})
-	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
+	result.Assert(c, icmd.Expected{Timeout: true})
 
 	events := strings.Split(result.Stdout(), "\n")
 	nEvents := len(events)
@@ -230,7 +230,7 @@
 	cleanedContainerID := strings.TrimSpace(out)
 
 	since := daemonUnixTime(c)
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "export", cleanedContainerID),
 		exec.Command(dockerBinary, "import", "-"),
 	)
@@ -263,7 +263,7 @@
 	dockerCmd(c, "load", "-i", "saveimg.tar")
 
 	result := icmd.RunCommand("rm", "-rf", "saveimg.tar")
-	c.Assert(result, icmd.Matches, icmd.Success)
+	result.Assert(c, icmd.Success)
 
 	out, _ = dockerCmd(c, "images", "-q", "--no-trunc", myImageName)
 	imageID := strings.TrimSpace(out)
@@ -499,9 +499,15 @@
 	cID := strings.TrimSpace(out)
 	c.Assert(waitRun(cID), checker.IsNil)
 
-	endpoint := "/containers/" + cID + "/resize?h=80&w=24"
-	status, _, err := request.SockRequest("POST", endpoint, nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	options := types.ResizeOptions{
+		Height: 80,
+		Width:  24,
+	}
+	err = cli.ContainerResize(context.Background(), cID, options)
 	c.Assert(err, checker.IsNil)
 
 	dockerCmd(c, "stop", cID)
@@ -781,7 +787,7 @@
 func (s *DockerSuite) TestEventsFormatBadFunc(c *check.C) {
 	// make sure it fails immediately, without receiving any event
 	result := dockerCmdWithResult("events", "--format", "{{badFuncString .}}")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		Error:    "exit status 64",
 		ExitCode: 64,
 		Err:      "Error parsing format: template: :1: function \"badFuncString\" not defined",
@@ -791,7 +797,7 @@
 func (s *DockerSuite) TestEventsFormatBadField(c *check.C) {
 	// make sure it fails immediately, without receiving any event
 	result := dockerCmdWithResult("events", "--format", "{{.badFieldString}}")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		Error:    "exit status 64",
 		ExitCode: 64,
 		Err:      "Error parsing format: template: :1:2: executing \"\" at <.badFieldString>: can't evaluate field badFieldString in type *events.Message",
diff --git a/integration-cli/docker_cli_events_unix_test.go b/integration-cli/docker_cli_events_unix_test.go
index 1f87d5f..afac998 100644
--- a/integration-cli/docker_cli_events_unix_test.go
+++ b/integration-cli/docker_cli_events_unix_test.go
@@ -97,7 +97,7 @@
 	}()
 
 	c.Assert(waitRun("oomTrue"), checker.IsNil)
-	defer dockerCmd(c, "kill", "oomTrue")
+	defer dockerCmdWithResult("kill", "oomTrue")
 	containerID := inspectField(c, "oomTrue", "Id")
 
 	testActions := map[string]chan bool{
@@ -428,7 +428,32 @@
 	out, err = s.d.Cmd("events", "--since=0", "--until", daemonUnixTime(c))
 	c.Assert(err, checker.IsNil)
 
-	c.Assert(out, checker.Contains, fmt.Sprintf("daemon reload %s (allow-nondistributable-artifacts=[], cluster-advertise=, cluster-store=, cluster-store-opts={}, debug=true, default-runtime=runc, default-shm-size=67108864, insecure-registries=[], labels=[\"bar=foo\"], live-restore=false, max-concurrent-downloads=1, max-concurrent-uploads=5, name=%s, registry-mirrors=[], runtimes=runc:{docker-runc []}, shutdown-timeout=10)", daemonID, daemonName))
+	// only check for values known (daemon ID/name) or explicitly set above,
+	// otherwise just check for names being present.
+	expectedSubstrings := []string{
+		" daemon reload " + daemonID + " ",
+		"(allow-nondistributable-artifacts=[",
+		" cluster-advertise=, ",
+		" cluster-store=, ",
+		" cluster-store-opts={",
+		" debug=true, ",
+		" default-ipc-mode=",
+		" default-runtime=",
+		" default-shm-size=",
+		" insecure-registries=[",
+		" labels=[\"bar=foo\"], ",
+		" live-restore=",
+		" max-concurrent-downloads=1, ",
+		" max-concurrent-uploads=5, ",
+		" name=" + daemonName,
+		" registry-mirrors=[",
+		" runtimes=",
+		" shutdown-timeout=10)",
+	}
+
+	for _, s := range expectedSubstrings {
+		c.Assert(out, checker.Contains, s)
+	}
 }
 
 func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) {
diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go
index be228ab..4442ca2 100644
--- a/integration-cli/docker_cli_exec_test.go
+++ b/integration-cli/docker_cli_exec_test.go
@@ -5,7 +5,6 @@
 import (
 	"bufio"
 	"fmt"
-	"net/http"
 	"os"
 	"os/exec"
 	"reflect"
@@ -15,12 +14,13 @@
 	"sync"
 	"time"
 
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
-	"github.com/docker/docker/integration-cli/request"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestExec(c *check.C) {
@@ -133,7 +133,7 @@
 	runSleepingContainer(c, "-d", "--name", "top")
 
 	result := icmd.RunCommand(dockerBinary, "exec", "top", "sh", "-c", "exit 23")
-	c.Assert(result, icmd.Matches, icmd.Expected{ExitCode: 23, Error: "exit status 23"})
+	result.Assert(c, icmd.Expected{ExitCode: 23, Error: "exit status 23"})
 }
 
 func (s *DockerSuite) TestExecPausedContainer(c *check.C) {
@@ -357,16 +357,21 @@
 	}
 
 	// But we should still be able to query the execID
-	sc, body, _ := request.SockRequest("GET", "/exec/"+execID+"/json", nil, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(sc, checker.Equals, http.StatusOK, check.Commentf("received status != 200 OK: %d\n%s", sc, body))
+	_, err = cli.ContainerExecInspect(context.Background(), execID)
+	c.Assert(err, checker.IsNil)
 
 	// Now delete the container and then an 'inspect' on the exec should
 	// result in a 404 (not 'container not running')
 	out, ec := dockerCmd(c, "rm", "-f", id)
 	c.Assert(ec, checker.Equals, 0, check.Commentf("error removing container: %s", out))
-	sc, body, _ = request.SockRequest("GET", "/exec/"+execID+"/json", nil, daemonHost())
-	c.Assert(sc, checker.Equals, http.StatusNotFound, check.Commentf("received status != 404: %d\n%s", sc, body))
+
+	_, err = cli.ContainerExecInspect(context.Background(), execID)
+	expected := "No such exec instance"
+	c.Assert(err.Error(), checker.Contains, expected)
 }
 
 func (s *DockerSuite) TestLinksPingLinkedContainersOnRename(c *check.C) {
diff --git a/integration-cli/docker_cli_experimental_test.go b/integration-cli/docker_cli_experimental_test.go
deleted file mode 100644
index 0a496fd..0000000
--- a/integration-cli/docker_cli_experimental_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package main
-
-import (
-	"strings"
-
-	"github.com/docker/docker/integration-cli/checker"
-	"github.com/go-check/check"
-)
-
-func (s *DockerSuite) TestExperimentalVersionTrue(c *check.C) {
-	testExperimentalInVersion(c, ExperimentalDaemon, "*true")
-}
-
-func (s *DockerSuite) TestExperimentalVersionFalse(c *check.C) {
-	testExperimentalInVersion(c, NotExperimentalDaemon, "*false")
-}
-
-func testExperimentalInVersion(c *check.C, requirement func() bool, expectedValue string) {
-	testRequires(c, requirement)
-	out, _ := dockerCmd(c, "version")
-	for _, line := range strings.Split(out, "\n") {
-		if strings.HasPrefix(strings.TrimSpace(line), "Experimental:") {
-			c.Assert(line, checker.Matches, expectedValue)
-			return
-		}
-	}
-
-	c.Fatal(`"Experimental" not found in version output`)
-}
diff --git a/integration-cli/docker_cli_export_import_test.go b/integration-cli/docker_cli_export_import_test.go
index fe117b9..45f29d5 100644
--- a/integration-cli/docker_cli_export_import_test.go
+++ b/integration-cli/docker_cli_export_import_test.go
@@ -5,8 +5,8 @@
 	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 // export an image and try to import it into a new one
diff --git a/integration-cli/docker_cli_external_graphdriver_unix_test.go b/integration-cli/docker_cli_external_graphdriver_unix_test.go
index 16023c9..8e766bc 100644
--- a/integration-cli/docker_cli_external_graphdriver_unix_test.go
+++ b/integration-cli/docker_cli_external_graphdriver_unix_test.go
@@ -198,12 +198,13 @@
 			return
 		}
 
+		// TODO @gupta-ak: Figure out what to do here.
 		dir, err := driver.Get(req.ID, req.MountLabel)
 		if err != nil {
 			respond(w, err)
 			return
 		}
-		respond(w, &graphDriverResponse{Dir: dir})
+		respond(w, &graphDriverResponse{Dir: dir.Path()})
 	})
 
 	mux.HandleFunc("/GraphDriver.Put", func(w http.ResponseWriter, r *http.Request) {
diff --git a/integration-cli/docker_cli_external_volume_driver_unix_test.go b/integration-cli/docker_cli_external_volume_driver_unix_test.go
index 5fe417c..2e2de97 100644
--- a/integration-cli/docker_cli_external_volume_driver_unix_test.go
+++ b/integration-cli/docker_cli_external_volume_driver_unix_test.go
@@ -50,6 +50,7 @@
 }
 
 func (s *DockerExternalVolumeSuite) SetUpTest(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
 	})
diff --git a/integration-cli/docker_cli_health_test.go b/integration-cli/docker_cli_health_test.go
index 0f78a41..20b2bc2 100644
--- a/integration-cli/docker_cli_health_test.go
+++ b/integration-cli/docker_cli_health_test.go
@@ -39,6 +39,8 @@
 func (s *DockerSuite) TestHealth(c *check.C) {
 	testRequires(c, DaemonIsLinux) // busybox doesn't work on Windows
 
+	existingContainers := ExistingContainerIDs(c)
+
 	imageName := "testhealth"
 	buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox
 		RUN echo OK > /status
@@ -49,9 +51,10 @@
 
 	// No health status before starting
 	name := "test_health"
-	dockerCmd(c, "create", "--name", name, imageName)
-	out, _ := dockerCmd(c, "ps", "-a", "--format={{.Status}}")
-	c.Check(out, checker.Equals, "Created\n")
+	cid, _ := dockerCmd(c, "create", "--name", name, imageName)
+	out, _ := dockerCmd(c, "ps", "-a", "--format={{.ID}} {{.Status}}")
+	out = RemoveOutputForExistingElements(out, existingContainers)
+	c.Check(out, checker.Equals, cid[:12]+" Created\n")
 
 	// Inspect the options
 	out, _ = dockerCmd(c, "inspect",
diff --git a/integration-cli/docker_cli_help_test.go b/integration-cli/docker_cli_help_test.go
deleted file mode 100644
index d1dcd8c..0000000
--- a/integration-cli/docker_cli_help_test.go
+++ /dev/null
@@ -1,319 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"runtime"
-	"strings"
-	"unicode"
-
-	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/cli"
-	"github.com/docker/docker/pkg/homedir"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
-	"github.com/go-check/check"
-)
-
-func (s *DockerSuite) TestHelpTextVerify(c *check.C) {
-	// FIXME(vdemeester) should be a unit test, probably using golden files ?
-	testRequires(c, DaemonIsLinux)
-
-	// Make sure main help text fits within 80 chars and that
-	// on non-windows system we use ~ when possible (to shorten things).
-	// Test for HOME set to its default value and set to "/" on linux
-	// Yes on windows setting up an array and looping (right now) isn't
-	// necessary because we just have one value, but we'll need the
-	// array/loop on linux so we might as well set it up so that we can
-	// test any number of home dirs later on and all we need to do is
-	// modify the array - the rest of the testing infrastructure should work
-	homes := []string{homedir.Get()}
-
-	// Non-Windows machines need to test for this special case of $HOME
-	if runtime.GOOS != "windows" {
-		homes = append(homes, "/")
-	}
-
-	homeKey := homedir.Key()
-	baseEnvs := appendBaseEnv(true)
-
-	// Remove HOME env var from list so we can add a new value later.
-	for i, env := range baseEnvs {
-		if strings.HasPrefix(env, homeKey+"=") {
-			baseEnvs = append(baseEnvs[:i], baseEnvs[i+1:]...)
-			break
-		}
-	}
-
-	for _, home := range homes {
-
-		// Dup baseEnvs and add our new HOME value
-		newEnvs := make([]string, len(baseEnvs)+1)
-		copy(newEnvs, baseEnvs)
-		newEnvs[len(newEnvs)-1] = homeKey + "=" + home
-
-		scanForHome := runtime.GOOS != "windows" && home != "/"
-
-		// Check main help text to make sure its not over 80 chars
-		result := icmd.RunCmd(icmd.Cmd{
-			Command: []string{dockerBinary, "help"},
-			Env:     newEnvs,
-		})
-		result.Assert(c, icmd.Success)
-		lines := strings.Split(result.Combined(), "\n")
-		for _, line := range lines {
-			// All lines should not end with a space
-			c.Assert(line, checker.Not(checker.HasSuffix), " ", check.Commentf("Line should not end with a space"))
-
-			if scanForHome && strings.Contains(line, `=`+home) {
-				c.Fatalf("Line should use '%q' instead of %q:\n%s", homedir.GetShortcutString(), home, line)
-			}
-			if runtime.GOOS != "windows" {
-				i := strings.Index(line, homedir.GetShortcutString())
-				if i >= 0 && i != len(line)-1 && line[i+1] != '/' {
-					c.Fatalf("Main help should not have used home shortcut:\n%s", line)
-				}
-			}
-		}
-
-		// Make sure each cmd's help text fits within 90 chars and that
-		// on non-windows system we use ~ when possible (to shorten things).
-		// Pull the list of commands from the "Commands:" section of docker help
-		// FIXME(vdemeester) Why re-run help ?
-		//helpCmd = exec.Command(dockerBinary, "help")
-		//helpCmd.Env = newEnvs
-		//out, _, err = runCommandWithOutput(helpCmd)
-		//c.Assert(err, checker.IsNil, check.Commentf(out))
-		i := strings.Index(result.Combined(), "Commands:")
-		c.Assert(i, checker.GreaterOrEqualThan, 0, check.Commentf("Missing 'Commands:' in:\n%s", result.Combined()))
-
-		cmds := []string{}
-		// Grab all chars starting at "Commands:"
-		helpOut := strings.Split(result.Combined()[i:], "\n")
-		// Skip first line, it is just "Commands:"
-		helpOut = helpOut[1:]
-
-		// Create the list of commands we want to test
-		cmdsToTest := []string{}
-		for _, cmd := range helpOut {
-			// Stop on blank line or non-indented line
-			if cmd == "" || !unicode.IsSpace(rune(cmd[0])) {
-				break
-			}
-
-			// Grab just the first word of each line
-			cmd = strings.Split(strings.TrimSpace(cmd), " ")[0]
-			cmds = append(cmds, cmd) // Saving count for later
-
-			cmdsToTest = append(cmdsToTest, cmd)
-		}
-
-		// Add some 'two word' commands - would be nice to automatically
-		// calculate this list - somehow
-		cmdsToTest = append(cmdsToTest, "volume create")
-		cmdsToTest = append(cmdsToTest, "volume inspect")
-		cmdsToTest = append(cmdsToTest, "volume ls")
-		cmdsToTest = append(cmdsToTest, "volume rm")
-		cmdsToTest = append(cmdsToTest, "network connect")
-		cmdsToTest = append(cmdsToTest, "network create")
-		cmdsToTest = append(cmdsToTest, "network disconnect")
-		cmdsToTest = append(cmdsToTest, "network inspect")
-		cmdsToTest = append(cmdsToTest, "network ls")
-		cmdsToTest = append(cmdsToTest, "network rm")
-
-		if testEnv.ExperimentalDaemon() {
-			cmdsToTest = append(cmdsToTest, "checkpoint create")
-			cmdsToTest = append(cmdsToTest, "checkpoint ls")
-			cmdsToTest = append(cmdsToTest, "checkpoint rm")
-		}
-
-		// Divide the list of commands into go routines and  run the func testcommand on the commands in parallel
-		// to save runtime of test
-
-		errChan := make(chan error)
-
-		for index := 0; index < len(cmdsToTest); index++ {
-			go func(index int) {
-				errChan <- testCommand(cmdsToTest[index], newEnvs, scanForHome, home)
-			}(index)
-		}
-
-		for index := 0; index < len(cmdsToTest); index++ {
-			err := <-errChan
-			if err != nil {
-				c.Fatal(err)
-			}
-		}
-	}
-}
-
-func (s *DockerSuite) TestHelpExitCodesHelpOutput(c *check.C) {
-	// Test to make sure the exit code and output (stdout vs stderr) of
-	// various good and bad cases are what we expect
-
-	// docker : stdout=all, stderr=empty, rc=0
-	out := cli.DockerCmd(c).Combined()
-	// Be really pick
-	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker'\n"))
-
-	// docker help: stdout=all, stderr=empty, rc=0
-	out = cli.DockerCmd(c, "help").Combined()
-	// Be really pick
-	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker help'\n"))
-
-	// docker --help: stdout=all, stderr=empty, rc=0
-	out = cli.DockerCmd(c, "--help").Combined()
-	// Be really pick
-	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker --help'\n"))
-
-	// docker inspect busybox: stdout=all, stderr=empty, rc=0
-	// Just making sure stderr is empty on valid cmd
-	out = cli.DockerCmd(c, "inspect", "busybox").Combined()
-	// Be really pick
-	c.Assert(out, checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker inspect busyBox'\n"))
-
-	// docker rm: stdout=empty, stderr=all, rc!=0
-	// testing the min arg error msg
-	cli.Docker(cli.Args("rm")).Assert(c, icmd.Expected{
-		ExitCode: 1,
-		Error:    "exit status 1",
-		Out:      "",
-		// Should not contain full help text but should contain info about
-		// # of args and Usage line
-		Err: "requires at least 1 argument",
-	})
-
-	// docker rm NoSuchContainer: stdout=empty, stderr=all, rc=0
-	// testing to make sure no blank line on error
-	result := cli.Docker(cli.Args("rm", "NoSuchContainer")).Assert(c, icmd.Expected{
-		ExitCode: 1,
-		Error:    "exit status 1",
-		Out:      "",
-	})
-	// Be really picky
-	c.Assert(len(result.Stderr()), checker.Not(checker.Equals), 0)
-	c.Assert(result.Stderr(), checker.Not(checker.HasSuffix), "\n\n", check.Commentf("Should not have a blank line at the end of 'docker rm'\n"))
-
-	// docker BadCmd: stdout=empty, stderr=all, rc=0
-	cli.Docker(cli.Args("BadCmd")).Assert(c, icmd.Expected{
-		ExitCode: 1,
-		Error:    "exit status 1",
-		Out:      "",
-		Err:      "docker: 'BadCmd' is not a docker command.\nSee 'docker --help'\n",
-	})
-}
-
-func testCommand(cmd string, newEnvs []string, scanForHome bool, home string) error {
-
-	args := strings.Split(cmd+" --help", " ")
-
-	// Check the full usage text
-	result := icmd.RunCmd(icmd.Cmd{
-		Command: append([]string{dockerBinary}, args...),
-		Env:     newEnvs,
-	})
-	err := result.Error
-	out := result.Stdout()
-	stderr := result.Stderr()
-	if len(stderr) != 0 {
-		return fmt.Errorf("Error on %q help. non-empty stderr:%q\n", cmd, stderr)
-	}
-	if strings.HasSuffix(out, "\n\n") {
-		return fmt.Errorf("Should not have blank line on %q\n", cmd)
-	}
-	if !strings.Contains(out, "--help") {
-		return fmt.Errorf("All commands should mention '--help'. Command '%v' did not.\n", cmd)
-	}
-
-	if err != nil {
-		return fmt.Errorf(out)
-	}
-
-	// Check each line for lots of stuff
-	lines := strings.Split(out, "\n")
-	for _, line := range lines {
-		i := strings.Index(line, "~")
-		if i >= 0 && i != len(line)-1 && line[i+1] != '/' {
-			return fmt.Errorf("Help for %q should not have used ~:\n%s", cmd, line)
-		}
-
-		// Options should NOT end with a period
-		if strings.HasPrefix(line, "  -") && strings.HasSuffix(line, ".") {
-			return fmt.Errorf("Help for %q should not end with a period: %s", cmd, line)
-		}
-
-		// Options should NOT end with a space
-		if strings.HasSuffix(line, " ") {
-			return fmt.Errorf("Help for %q should not end with a space: %s", cmd, line)
-		}
-
-	}
-
-	// For each command make sure we generate an error
-	// if we give a bad arg
-	args = strings.Split(cmd+" --badArg", " ")
-
-	out, _, err = dockerCmdWithError(args...)
-	if err == nil {
-		return fmt.Errorf(out)
-	}
-
-	// Be really picky
-	if strings.HasSuffix(stderr, "\n\n") {
-		return fmt.Errorf("Should not have a blank line at the end of 'docker rm'\n")
-	}
-
-	// Now make sure that each command will print a short-usage
-	// (not a full usage - meaning no opts section) if we
-	// are missing a required arg or pass in a bad arg
-
-	// These commands will never print a short-usage so don't test
-	noShortUsage := map[string]string{
-		"images":        "",
-		"login":         "",
-		"logout":        "",
-		"network":       "",
-		"stats":         "",
-		"volume create": "",
-	}
-
-	if _, ok := noShortUsage[cmd]; !ok {
-		// skipNoArgs are ones that we don't want to try w/o
-		// any args. Either because it'll hang the test or
-		// lead to incorrect test result (like false negative).
-		// Whatever the reason, skip trying to run w/o args and
-		// jump to trying with a bogus arg.
-		skipNoArgs := map[string]struct{}{
-			"daemon": {},
-			"events": {},
-			"load":   {},
-		}
-
-		var result *icmd.Result
-		if _, ok := skipNoArgs[cmd]; !ok {
-			result = dockerCmdWithResult(strings.Split(cmd, " ")...)
-		}
-
-		// If its ok w/o any args then try again with an arg
-		if result == nil || result.ExitCode == 0 {
-			result = dockerCmdWithResult(strings.Split(cmd+" badArg", " ")...)
-		}
-
-		if err := result.Compare(icmd.Expected{
-			Out:      icmd.None,
-			Err:      "\nUsage:",
-			ExitCode: 1,
-		}); err != nil {
-			return err
-		}
-
-		stderr := result.Stderr()
-		// Shouldn't have full usage
-		if strings.Contains(stderr, "--help=false") {
-			return fmt.Errorf("Should not have full usage on %q:%v", result.Cmd.Args, stderr)
-		}
-		if strings.HasSuffix(stderr, "\n\n") {
-			return fmt.Errorf("Should not have a blank line on %q\n%v", result.Cmd.Args, stderr)
-		}
-	}
-
-	return nil
-}
diff --git a/integration-cli/docker_cli_images_test.go b/integration-cli/docker_cli_images_test.go
index dccbe12..2a1152e 100644
--- a/integration-cli/docker_cli_images_test.go
+++ b/integration-cli/docker_cli_images_test.go
@@ -13,8 +13,8 @@
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/pkg/stringid"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestImagesEnsureImageIsListed(c *check.C) {
diff --git a/integration-cli/docker_cli_import_test.go b/integration-cli/docker_cli_import_test.go
index 711f39b..eb0fe2c 100644
--- a/integration-cli/docker_cli_import_test.go
+++ b/integration-cli/docker_cli_import_test.go
@@ -11,9 +11,8 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestImportDisplay(c *check.C) {
@@ -21,7 +20,7 @@
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "true")
 	cleanedContainerID := strings.TrimSpace(out)
 
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "export", cleanedContainerID),
 		exec.Command(dockerBinary, "import", "-"),
 	)
@@ -139,5 +138,5 @@
 	image := strings.TrimSpace(result.Stdout())
 
 	result = cli.DockerCmd(c, "run", "--rm", image, "true")
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: icmd.None})
+	result.Assert(c, icmd.Expected{Out: icmd.None})
 }
diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go
index d75974d..b6f8673 100644
--- a/integration-cli/docker_cli_info_test.go
+++ b/integration-cli/docker_cli_info_test.go
@@ -135,42 +135,48 @@
 func (s *DockerSuite) TestInfoDisplaysRunningContainers(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 
+	existing := existingContainerStates(c)
+
 	dockerCmd(c, "run", "-d", "busybox", "top")
 	out, _ := dockerCmd(c, "info")
-	c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 1))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 0))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 0))
+	c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", existing["Containers"]+1))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", existing["ContainersRunning"]+1))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", existing["ContainersPaused"]))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", existing["ContainersStopped"]))
 }
 
 func (s *DockerSuite) TestInfoDisplaysPausedContainers(c *check.C) {
 	testRequires(c, IsPausable)
 
+	existing := existingContainerStates(c)
+
 	out := runSleepingContainer(c, "-d")
 	cleanedContainerID := strings.TrimSpace(out)
 
 	dockerCmd(c, "pause", cleanedContainerID)
 
 	out, _ = dockerCmd(c, "info")
-	c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 0))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 1))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 0))
+	c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", existing["Containers"]+1))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", existing["ContainersRunning"]))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", existing["ContainersPaused"]+1))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", existing["ContainersStopped"]))
 }
 
 func (s *DockerSuite) TestInfoDisplaysStoppedContainers(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 
+	existing := existingContainerStates(c)
+
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "top")
 	cleanedContainerID := strings.TrimSpace(out)
 
 	dockerCmd(c, "stop", cleanedContainerID)
 
 	out, _ = dockerCmd(c, "info")
-	c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 0))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 0))
-	c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 1))
+	c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", existing["Containers"]+1))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", existing["ContainersRunning"]))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", existing["ContainersPaused"]))
+	c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", existing["ContainersStopped"]+1))
 }
 
 func (s *DockerSuite) TestInfoDebug(c *check.C) {
@@ -237,3 +243,16 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(out, checker.Contains, "WARNING: labels with duplicate keys and conflicting values have been deprecated")
 }
+
+func existingContainerStates(c *check.C) map[string]int {
+	out, _ := dockerCmd(c, "info", "--format", "{{json .}}")
+	var m map[string]interface{}
+	err := json.Unmarshal([]byte(out), &m)
+	c.Assert(err, checker.IsNil)
+	res := map[string]int{}
+	res["Containers"] = int(m["Containers"].(float64))
+	res["ContainersRunning"] = int(m["ContainersRunning"].(float64))
+	res["ContainersPaused"] = int(m["ContainersPaused"].(float64))
+	res["ContainersStopped"] = int(m["ContainersStopped"].(float64))
+	return res
+}
diff --git a/integration-cli/docker_cli_inspect_test.go b/integration-cli/docker_cli_inspect_test.go
index 96e2ee4..13eb2d3 100644
--- a/integration-cli/docker_cli_inspect_test.go
+++ b/integration-cli/docker_cli_inspect_test.go
@@ -11,8 +11,8 @@
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/integration-cli/checker"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func checkValidGraphDriver(c *check.C, name string) {
@@ -463,6 +463,5 @@
 	// This test should work on both Windows and Linux
 	out, _, err := dockerCmdWithError("inspect", "FooBar")
 	c.Assert(err, checker.NotNil)
-	c.Assert(out, checker.Contains, "Error: No such object: FooBar")
-	c.Assert(err.Error(), checker.Contains, "Error: No such object: FooBar")
+	c.Assert(out, checker.Contains, "no such image: FooBar")
 }
diff --git a/integration-cli/docker_cli_kill_test.go b/integration-cli/docker_cli_kill_test.go
index 3273ecf..0a5aac5 100644
--- a/integration-cli/docker_cli_kill_test.go
+++ b/integration-cli/docker_cli_kill_test.go
@@ -1,16 +1,15 @@
 package main
 
 import (
-	"fmt"
-	"net/http"
 	"strings"
 	"time"
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/request"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestKillContainer(c *check.C) {
@@ -131,8 +130,9 @@
 	testRequires(c, DaemonIsLinux) // Windows only supports 1.25 or later
 	runSleepingContainer(c, "--name", "docker-kill-test-api", "-d")
 	dockerCmd(c, "stop", "docker-kill-test-api")
-
-	status, _, err := request.SockRequest("POST", fmt.Sprintf("/v1.19/containers/%s/kill", "docker-kill-test-api"), nil, daemonHost())
+	cli, err := request.NewEnvClientWithVersion("v1.19")
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusNoContent)
+	defer cli.Close()
+	err = cli.ContainerKill(context.Background(), "docker-kill-test-api", "SIGKILL")
+	c.Assert(err, check.IsNil)
 }
diff --git a/integration-cli/docker_cli_links_test.go b/integration-cli/docker_cli_links_test.go
index b43c6d1..0b4f30c 100644
--- a/integration-cli/docker_cli_links_test.go
+++ b/integration-cli/docker_cli_links_test.go
@@ -4,10 +4,10 @@
 	"encoding/json"
 	"fmt"
 	"regexp"
+	"sort"
 	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/docker/runconfig"
 	"github.com/go-check/check"
 )
@@ -28,7 +28,7 @@
 	// an invalid container target should produce an error
 	c.Assert(err, checker.NotNil, check.Commentf("out: %s", out))
 	// an invalid container target should produce an error
-	c.Assert(out, checker.Contains, "Could not get container")
+	c.Assert(out, checker.Contains, "could not get container")
 }
 
 func (s *DockerSuite) TestLinksPingLinkedContainers(c *check.C) {
@@ -90,40 +90,41 @@
 
 func (s *DockerSuite) TestLinksInspectLinksStarted(c *check.C) {
 	testRequires(c, DaemonIsLinux)
-	var (
-		expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
-		result   []string
-	)
 	dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "top")
 	links := inspectFieldJSON(c, "testinspectlink", "HostConfig.Links")
 
+	var result []string
 	err := json.Unmarshal([]byte(links), &result)
 	c.Assert(err, checker.IsNil)
 
-	output := testutil.ConvertSliceOfStringsToMap(result)
-
-	c.Assert(output, checker.DeepEquals, expected)
+	var expected = []string{
+		"/container1:/testinspectlink/alias1",
+		"/container2:/testinspectlink/alias2",
+	}
+	sort.Strings(result)
+	c.Assert(result, checker.DeepEquals, expected)
 }
 
 func (s *DockerSuite) TestLinksInspectLinksStopped(c *check.C) {
 	testRequires(c, DaemonIsLinux)
-	var (
-		expected = map[string]struct{}{"/container1:/testinspectlink/alias1": {}, "/container2:/testinspectlink/alias2": {}}
-		result   []string
-	)
+
 	dockerCmd(c, "run", "-d", "--name", "container1", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name", "container2", "busybox", "top")
 	dockerCmd(c, "run", "-d", "--name", "testinspectlink", "--link", "container1:alias1", "--link", "container2:alias2", "busybox", "true")
 	links := inspectFieldJSON(c, "testinspectlink", "HostConfig.Links")
 
+	var result []string
 	err := json.Unmarshal([]byte(links), &result)
 	c.Assert(err, checker.IsNil)
 
-	output := testutil.ConvertSliceOfStringsToMap(result)
-
-	c.Assert(output, checker.DeepEquals, expected)
+	var expected = []string{
+		"/container1:/testinspectlink/alias1",
+		"/container2:/testinspectlink/alias2",
+	}
+	sort.Strings(result)
+	c.Assert(result, checker.DeepEquals, expected)
 }
 
 func (s *DockerSuite) TestLinksNotStartedParentNotFail(c *check.C) {
diff --git a/integration-cli/docker_cli_logs_test.go b/integration-cli/docker_cli_logs_test.go
index a8b8f90..f75da18 100644
--- a/integration-cli/docker_cli_logs_test.go
+++ b/integration-cli/docker_cli_logs_test.go
@@ -10,10 +10,9 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
-	"github.com/docker/docker/pkg/jsonlog"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
+	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 // This used to work, it test a log of PageSize-1 (gh#4851)
@@ -56,7 +55,7 @@
 
 	for _, l := range lines {
 		if l != "" {
-			_, err := time.Parse(jsonlog.RFC3339NanoFixed+" ", ts.FindString(l))
+			_, err := time.Parse(jsonmessage.RFC3339NanoFixed+" ", ts.FindString(l))
 			c.Assert(err, checker.IsNil, check.Commentf("Failed to parse timestamp from %v", l))
 			// ensure we have padded 0's
 			c.Assert(l[29], checker.Equals, uint8('Z'))
@@ -215,14 +214,15 @@
 func (s *DockerSuite) TestLogsFollowSlowStdoutConsumer(c *check.C) {
 	// TODO Windows: Fix this test for TP5.
 	testRequires(c, DaemonIsLinux)
-	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", `usleep 600000;yes X | head -c 200000`)
+	expected := 150000
+	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", fmt.Sprintf("usleep 600000; yes X | head -c %d", expected))
 
 	id := strings.TrimSpace(out)
 
 	stopSlowRead := make(chan bool)
 
 	go func() {
-		exec.Command(dockerBinary, "wait", id).Run()
+		dockerCmd(c, "wait", id)
 		stopSlowRead <- true
 	}()
 
@@ -232,18 +232,42 @@
 	c.Assert(logCmd.Start(), checker.IsNil)
 
 	// First read slowly
-	bytes1, err := testutil.ConsumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
+	bytes1, err := ConsumeWithSpeed(stdout, 10, 50*time.Millisecond, stopSlowRead)
 	c.Assert(err, checker.IsNil)
 
 	// After the container has finished we can continue reading fast
-	bytes2, err := testutil.ConsumeWithSpeed(stdout, 32*1024, 0, nil)
+	bytes2, err := ConsumeWithSpeed(stdout, 32*1024, 0, nil)
 	c.Assert(err, checker.IsNil)
 
+	c.Assert(logCmd.Wait(), checker.IsNil)
+
 	actual := bytes1 + bytes2
-	expected := 200000
 	c.Assert(actual, checker.Equals, expected)
 }
 
+// ConsumeWithSpeed reads chunkSize bytes from reader before sleeping
+// for interval duration. Returns total read bytes. Send true to the
+// stop channel to return before reading to EOF on the reader.
+func ConsumeWithSpeed(reader io.Reader, chunkSize int, interval time.Duration, stop chan bool) (n int, err error) {
+	buffer := make([]byte, chunkSize)
+	for {
+		var readBytes int
+		readBytes, err = reader.Read(buffer)
+		n += readBytes
+		if err != nil {
+			if err == io.EOF {
+				err = nil
+			}
+			return
+		}
+		select {
+		case <-stop:
+			return
+		case <-time.After(interval):
+		}
+	}
+}
+
 func (s *DockerSuite) TestLogsFollowGoroutinesWithStdout(c *check.C) {
 	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "while true; do echo hello; sleep 2; done")
 	id := strings.TrimSpace(out)
@@ -266,6 +290,7 @@
 	c.Assert(<-chErr, checker.IsNil)
 	c.Assert(cmd.Process.Kill(), checker.IsNil)
 	r.Close()
+	cmd.Wait()
 	// NGoroutines is not updated right away, so we need to wait before failing
 	c.Assert(waitForGoroutines(nroutines), checker.IsNil)
 }
@@ -281,6 +306,7 @@
 	c.Assert(cmd.Start(), checker.IsNil)
 	time.Sleep(200 * time.Millisecond)
 	c.Assert(cmd.Process.Kill(), checker.IsNil)
+	cmd.Wait()
 
 	// NGoroutines is not updated right away, so we need to wait before failing
 	c.Assert(waitForGoroutines(nroutines), checker.IsNil)
diff --git a/integration-cli/docker_cli_netmode_test.go b/integration-cli/docker_cli_netmode_test.go
index deb8f69..abf1ff2 100644
--- a/integration-cli/docker_cli_netmode_test.go
+++ b/integration-cli/docker_cli_netmode_test.go
@@ -1,6 +1,8 @@
 package main
 
 import (
+	"strings"
+
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/runconfig"
 	"github.com/go-check/check"
@@ -47,7 +49,7 @@
 	c.Assert(out, checker.Contains, "Invalid network mode: invalid container format container:<name|id>")
 
 	out, _ = dockerCmdWithFail(c, "run", "--net=weird", "busybox", "ps")
-	c.Assert(out, checker.Contains, "network weird not found")
+	c.Assert(strings.ToLower(out), checker.Contains, "no such network")
 }
 
 func (s *DockerSuite) TestConflictContainerNetworkAndLinks(c *check.C) {
diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go
index 05cc078..4762e39 100644
--- a/integration-cli/docker_cli_network_unix_test.go
+++ b/integration-cli/docker_cli_network_unix_test.go
@@ -10,7 +10,6 @@
 	"net/http"
 	"net/http/httptest"
 	"os"
-	"path/filepath"
 	"strings"
 	"time"
 
@@ -20,7 +19,6 @@
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/daemon"
 	"github.com/docker/docker/pkg/stringid"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/libnetwork/driverapi"
 	remoteapi "github.com/docker/libnetwork/drivers/remote/api"
@@ -28,6 +26,7 @@
 	remoteipam "github.com/docker/libnetwork/ipams/remote/api"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/vishvananda/netlink"
 	"golang.org/x/sys/unix"
 )
@@ -288,39 +287,6 @@
 	}
 }
 
-func (s *DockerSuite) TestNetworkLsFormat(c *check.C) {
-	testRequires(c, DaemonIsLinux)
-	out, _ := dockerCmd(c, "network", "ls", "--format", "{{.Name}}")
-	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
-
-	expected := []string{"bridge", "host", "none"}
-	var names []string
-	names = append(names, lines...)
-	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
-}
-
-func (s *DockerSuite) TestNetworkLsFormatDefaultFormat(c *check.C) {
-	testRequires(c, DaemonIsLinux)
-
-	config := `{
-		"networksFormat": "{{ .Name }} default"
-}`
-	d, err := ioutil.TempDir("", "integration-cli-")
-	c.Assert(err, checker.IsNil)
-	defer os.RemoveAll(d)
-
-	err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
-	c.Assert(err, checker.IsNil)
-
-	out, _ := dockerCmd(c, "--config", d, "network", "ls")
-	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
-
-	expected := []string{"bridge default", "host default", "none default"}
-	var names []string
-	names = append(names, lines...)
-	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
-}
-
 func (s *DockerNetworkSuite) TestDockerNetworkCreatePredefined(c *check.C) {
 	predefined := []string{"bridge", "host", "none", "default"}
 	for _, net := range predefined {
@@ -351,6 +317,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkLsFilter(c *check.C) {
+	testRequires(c, OnlyDefaultNetworks)
 	testNet := "testnet1"
 	testLabel := "foo"
 	testValue := "bar"
@@ -482,7 +449,7 @@
 
 func (s *DockerSuite) TestDockerInspectMultipleNetwork(c *check.C) {
 	result := dockerCmdWithResult("network", "inspect", "host", "none")
-	c.Assert(result, icmd.Matches, icmd.Success)
+	result.Assert(c, icmd.Success)
 
 	networkResources := []types.NetworkResource{}
 	err := json.Unmarshal([]byte(result.Stdout()), &networkResources)
@@ -494,7 +461,7 @@
 	// non-existent network was not at the beginning of the inspect list
 	// This should print an error, return an exitCode 1 and print the host network
 	result := dockerCmdWithResult("network", "inspect", "host", "nonexistent")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		ExitCode: 1,
 		Err:      "Error: No such network: nonexistent",
 		Out:      "host",
@@ -508,7 +475,7 @@
 	// Only one non-existent network to inspect
 	// Should print an error and return an exitCode, nothing else
 	result = dockerCmdWithResult("network", "inspect", "nonexistent")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		ExitCode: 1,
 		Err:      "Error: No such network: nonexistent",
 		Out:      "[]",
@@ -517,7 +484,7 @@
 	// non-existent network was at the beginning of the inspect list
 	// Should not fail fast, and still print host network but print an error
 	result = dockerCmdWithResult("network", "inspect", "nonexistent", "host")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		ExitCode: 1,
 		Err:      "Error: No such network: nonexistent",
 		Out:      "host",
@@ -624,6 +591,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkIPAMMultipleNetworks(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	// test0 bridge network
 	dockerCmd(c, "network", "create", "--subnet=192.168.0.0/16", "test1")
 	assertNwIsAvailable(c, "test1")
@@ -664,6 +632,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkCustomIPAM(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	// Create a bridge network using custom ipam driver
 	dockerCmd(c, "network", "create", "--ipam-driver", dummyIPAMDriver, "br0")
 	assertNwIsAvailable(c, "br0")
@@ -679,6 +648,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkIPAMOptions(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	// Create a bridge network using custom ipam driver and options
 	dockerCmd(c, "network", "create", "--ipam-driver", dummyIPAMDriver, "--ipam-opt", "opt1=drv1", "--ipam-opt", "opt2=drv2", "br0")
 	assertNwIsAvailable(c, "br0")
@@ -690,6 +660,22 @@
 	c.Assert(opts["opt2"], checker.Equals, "drv2")
 }
 
+func (s *DockerNetworkSuite) TestDockerNetworkNullIPAMDriver(c *check.C) {
+	testRequires(c, SameHostDaemon)
+	// Create a network with null ipam driver
+	_, _, err := dockerCmdWithError("network", "create", "-d", dummyNetworkDriver, "--ipam-driver", "null", "test000")
+	c.Assert(err, check.IsNil)
+	assertNwIsAvailable(c, "test000")
+
+	// Verify the inspect data contains the default subnet provided by the null
+	// ipam driver and no gateway, as the null ipam driver does not provide one
+	nr := getNetworkResource(c, "test000")
+	c.Assert(nr.IPAM.Driver, checker.Equals, "null")
+	c.Assert(len(nr.IPAM.Config), checker.Equals, 1)
+	c.Assert(nr.IPAM.Config[0].Subnet, checker.Equals, "0.0.0.0/0")
+	c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "")
+}
+
 func (s *DockerNetworkSuite) TestDockerNetworkInspectDefault(c *check.C) {
 	nr := getNetworkResource(c, "none")
 	c.Assert(nr.Driver, checker.Equals, "null")
@@ -781,6 +767,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkDriverOptions(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, "-o", "opt1=drv1", "-o", "opt2=drv2", "testopt")
 	assertNwIsAvailable(c, "testopt")
 	gopts := remoteDriverNetworkRequest.Options[netlabel.GenericData]
@@ -966,6 +953,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkOverlayPortMapping(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	// Verify exposed ports are present in ps output when running a container on
 	// a network managed by a driver which does not provide the default gateway
 	// for the container
@@ -992,7 +980,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkDriverUngracefulRestart(c *check.C) {
-	testRequires(c, DaemonIsLinux, NotUserNamespace)
+	testRequires(c, DaemonIsLinux, NotUserNamespace, SameHostDaemon)
 	dnd := "dnd"
 	did := "did"
 
@@ -1033,6 +1021,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkMacInspect(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	// Verify endpoint MAC address is correctly populated in container's network settings
 	nwn := "ov"
 	ctn := "bb"
@@ -1098,6 +1087,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkMultipleNetworksGracefulDaemonRestart(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	cName := "bb"
 	nwList := []string{"nw1", "nw2", "nw3"}
 
@@ -1116,6 +1106,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkMultipleNetworksUngracefulDaemonRestart(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	cName := "cc"
 	nwList := []string{"nw1", "nw2", "nw3"}
 
@@ -1142,7 +1133,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkHostModeUngracefulDaemonRestart(c *check.C) {
-	testRequires(c, DaemonIsLinux, NotUserNamespace)
+	testRequires(c, DaemonIsLinux, NotUserNamespace, SameHostDaemon)
 	s.d.StartWithBusybox(c)
 
 	// Run a few containers on host network
@@ -1268,6 +1259,7 @@
 }
 
 func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnectToStoppedContainer(c *check.C) {
+	testRequires(c, SameHostDaemon)
 	dockerCmd(c, "network", "create", "test")
 	dockerCmd(c, "create", "--name=foo", "busybox", "top")
 	dockerCmd(c, "network", "connect", "test", "foo")
@@ -1795,7 +1787,7 @@
 // TestConntrackFlowsLeak covers the failure scenario of ticket: https://github.com/docker/docker/issues/8795
 // Validates that conntrack is correctly cleaned once a container is destroyed
 func (s *DockerNetworkSuite) TestConntrackFlowsLeak(c *check.C) {
-	testRequires(c, IsAmd64, DaemonIsLinux, Network)
+	testRequires(c, IsAmd64, DaemonIsLinux, Network, SameHostDaemon)
 
 	// Create a new network
 	cli.DockerCmd(c, "network", "create", "--subnet=192.168.10.0/24", "--gateway=192.168.10.1", "-o", "com.docker.network.bridge.host_binding_ipv4=192.168.10.1", "testbind")
diff --git a/integration-cli/docker_cli_plugins_logdriver_test.go b/integration-cli/docker_cli_plugins_logdriver_test.go
index d742566..8104b3b 100644
--- a/integration-cli/docker_cli_plugins_logdriver_test.go
+++ b/integration-cli/docker_cli_plugins_logdriver_test.go
@@ -1,14 +1,12 @@
 package main
 
 import (
-	"encoding/json"
-	"net/http"
 	"strings"
 
-	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
-	"github.com/docker/docker/integration-cli/request"
 	"github.com/go-check/check"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestPluginLogDriver(c *check.C) {
@@ -36,13 +34,14 @@
 	pluginName := "cpuguy83/docker-logdriver-test"
 
 	dockerCmd(c, "plugin", "install", pluginName)
-	status, body, err := request.SockRequest("GET", "/info", nil, daemonHost())
-	c.Assert(status, checker.Equals, http.StatusOK)
+
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	info, err := cli.Info(context.Background())
 	c.Assert(err, checker.IsNil)
 
-	var info types.Info
-	err = json.Unmarshal(body, &info)
-	c.Assert(err, checker.IsNil)
 	drivers := strings.Join(info.Plugins.Log, " ")
 	c.Assert(drivers, checker.Contains, "json-file")
 	c.Assert(drivers, checker.Not(checker.Contains), pluginName)
diff --git a/integration-cli/docker_cli_plugins_test.go b/integration-cli/docker_cli_plugins_test.go
index 38b4af8..13ae2b0 100644
--- a/integration-cli/docker_cli_plugins_test.go
+++ b/integration-cli/docker_cli_plugins_test.go
@@ -16,8 +16,8 @@
 	"github.com/docker/docker/integration-cli/daemon"
 	"github.com/docker/docker/integration-cli/fixtures/plugin"
 	"github.com/docker/docker/integration-cli/request"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"golang.org/x/net/context"
 )
 
@@ -462,7 +462,7 @@
 }
 
 func (s *DockerSuite) TestPluginUpgrade(c *check.C) {
-	testRequires(c, DaemonIsLinux, Network, SameHostDaemon, IsAmd64)
+	testRequires(c, DaemonIsLinux, Network, SameHostDaemon, IsAmd64, NotUserNamespace)
 	plugin := "cpuguy83/docker-volume-driver-plugin-local:latest"
 	pluginV2 := "cpuguy83/docker-volume-driver-plugin-local:v2"
 
diff --git a/integration-cli/docker_cli_port_test.go b/integration-cli/docker_cli_port_test.go
index bcb87f5..84058cd 100644
--- a/integration-cli/docker_cli_port_test.go
+++ b/integration-cli/docker_cli_port_test.go
@@ -5,6 +5,7 @@
 	"net"
 	"regexp"
 	"sort"
+	"strconv"
 	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
@@ -148,9 +149,8 @@
 
 	out, _ = dockerCmd(c, "port", ID)
 
-	err = assertPortList(c, out, []string{
-		"80/tcp -> 0.0.0.0:8000",
-		"80/udp -> 0.0.0.0:8000"})
+	// Running this test multiple times causes the TCP port to increment.
+	err = assertPortRange(c, out, []int{8000, 8080}, []int{8000, 8080})
 	// Port list is not correct
 	c.Assert(err, checker.IsNil)
 	dockerCmd(c, "rm", "-f", ID)
@@ -173,6 +173,38 @@
 	return nil
 }
 
+func assertPortRange(c *check.C, out string, expectedTcp, expectedUdp []int) error {
+	lines := strings.Split(strings.Trim(out, "\n "), "\n")
+
+	var validTcp, validUdp bool
+	for _, l := range lines {
+		// 80/tcp -> 0.0.0.0:8015
+		port, err := strconv.Atoi(strings.Split(l, ":")[1])
+		if err != nil {
+			return err
+		}
+		if strings.Contains(l, "tcp") && expectedTcp != nil {
+			if port < expectedTcp[0] || port > expectedTcp[1] {
+				return fmt.Errorf("tcp port (%d) not in range expected range %d-%d", port, expectedTcp[0], expectedTcp[1])
+			}
+			validTcp = true
+		}
+		if strings.Contains(l, "udp") && expectedUdp != nil {
+			if port < expectedUdp[0] || port > expectedUdp[1] {
+				return fmt.Errorf("udp port (%d) not in range expected range %d-%d", port, expectedUdp[0], expectedUdp[1])
+			}
+			validUdp = true
+		}
+	}
+	if !validTcp {
+		return fmt.Errorf("tcp port not found")
+	}
+	if !validUdp {
+		return fmt.Errorf("udp port not found")
+	}
+	return nil
+}
+
 func stopRemoveContainer(id string, c *check.C) {
 	dockerCmd(c, "rm", "-f", id)
 }
diff --git a/integration-cli/docker_cli_proxy_test.go b/integration-cli/docker_cli_proxy_test.go
index 3344985..bdb4772 100644
--- a/integration-cli/docker_cli_proxy_test.go
+++ b/integration-cli/docker_cli_proxy_test.go
@@ -5,8 +5,8 @@
 	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestCLIProxyDisableProxyUnixSock(c *check.C) {
diff --git a/integration-cli/docker_cli_prune_unix_test.go b/integration-cli/docker_cli_prune_unix_test.go
index bea4f4f..763a72d 100644
--- a/integration-cli/docker_cli_prune_unix_test.go
+++ b/integration-cli/docker_cli_prune_unix_test.go
@@ -19,13 +19,21 @@
 func pruneNetworkAndVerify(c *check.C, d *daemon.Swarm, kept, pruned []string) {
 	_, err := d.Cmd("network", "prune", "--force")
 	c.Assert(err, checker.IsNil)
-	out, err := d.Cmd("network", "ls", "--format", "{{.Name}}")
-	c.Assert(err, checker.IsNil)
+
 	for _, s := range kept {
-		c.Assert(out, checker.Contains, s)
+		waitAndAssert(c, defaultReconciliationTimeout, func(*check.C) (interface{}, check.CommentInterface) {
+			out, err := d.Cmd("network", "ls", "--format", "{{.Name}}")
+			c.Assert(err, checker.IsNil)
+			return out, nil
+		}, checker.Contains, s)
 	}
+
 	for _, s := range pruned {
-		c.Assert(out, checker.Not(checker.Contains), s)
+		waitAndAssert(c, defaultReconciliationTimeout, func(*check.C) (interface{}, check.CommentInterface) {
+			out, err := d.Cmd("network", "ls", "--format", "{{.Name}}")
+			c.Assert(err, checker.IsNil)
+			return out, nil
+		}, checker.Not(checker.Contains), s)
 	}
 }
 
@@ -46,7 +54,7 @@
 
 	serviceName := "testprunesvc"
 	replicas := 1
-	out, err := d.Cmd("service", "create", "--no-resolve-image",
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image",
 		"--name", serviceName,
 		"--replicas", strconv.Itoa(replicas),
 		"--network", "n3",
@@ -64,6 +72,7 @@
 	_, err = d.Cmd("service", "rm", serviceName)
 	c.Assert(err, checker.IsNil)
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 0)
+
 	pruneNetworkAndVerify(c, d, []string{}, []string{"n1", "n3"})
 }
 
diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go
index 98a20f4..bea1261 100644
--- a/integration-cli/docker_cli_ps_test.go
+++ b/integration-cli/docker_cli_ps_test.go
@@ -14,11 +14,13 @@
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/pkg/stringid"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestPsListContainersBase(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
+
 	out := runSleepingContainer(c, "-d")
 	firstID := strings.TrimSpace(out)
 
@@ -43,79 +45,79 @@
 
 	// all
 	out, _ = dockerCmd(c, "ps", "-a")
-	c.Assert(assertContainerList(out, []string{fourthID, thirdID, secondID, firstID}), checker.Equals, true, check.Commentf("ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), []string{fourthID, thirdID, secondID, firstID}), checker.Equals, true, check.Commentf("ALL: Container list is not in the correct order: \n%s", out))
 
 	// running
 	out, _ = dockerCmd(c, "ps")
-	c.Assert(assertContainerList(out, []string{fourthID, secondID, firstID}), checker.Equals, true, check.Commentf("RUNNING: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), []string{fourthID, secondID, firstID}), checker.Equals, true, check.Commentf("RUNNING: Container list is not in the correct order: \n%s", out))
 
 	// limit
 	out, _ = dockerCmd(c, "ps", "-n=2", "-a")
 	expected := []string{fourthID, thirdID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT & ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("LIMIT & ALL: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-n=2")
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("LIMIT: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("LIMIT: Container list is not in the correct order: \n%s", out))
 
 	// filter since
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-a")
 	expected = []string{fourthID, thirdID, secondID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter & ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter & ALL: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID)
 	expected = []string{fourthID, secondID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "since="+thirdID)
 	expected = []string{fourthID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
 
 	// filter before
 	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-a")
 	expected = []string{thirdID, secondID, firstID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter & ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("BEFORE filter & ALL: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID)
 	expected = []string{secondID, firstID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("BEFORE filter: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "before="+thirdID)
 	expected = []string{secondID, firstID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter: Container list is not in the correct order: \n%s", out))
 
 	// filter since & before
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-a")
 	expected = []string{thirdID, secondID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter & ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter & ALL: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID)
 	expected = []string{secondID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter: Container list is not in the correct order: \n%s", out))
 
 	// filter since & limit
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2", "-a")
 	expected = []string{fourthID, thirdID}
 
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-n=2")
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, LIMIT: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter, LIMIT: Container list is not in the correct order: \n%s", out))
 
 	// filter before & limit
 	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1", "-a")
 	expected = []string{thirdID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("BEFORE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "before="+fourthID, "-n=1")
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("BEFORE filter, LIMIT: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("BEFORE filter, LIMIT: Container list is not in the correct order: \n%s", out))
 
 	// filter since & filter before & limit
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1", "-a")
 	expected = []string{thirdID}
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter, LIMIT & ALL: Container list is not in the correct order: \n%s", out))
 
 	out, _ = dockerCmd(c, "ps", "-f", "since="+firstID, "-f", "before="+fourthID, "-n=1")
-	c.Assert(assertContainerList(out, expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter, LIMIT: Container list is not in the correct order: \n%s", out))
+	c.Assert(assertContainerList(RemoveOutputForExistingElements(out, existingContainers), expected), checker.Equals, true, check.Commentf("SINCE filter, BEFORE filter, LIMIT: Container list is not in the correct order: \n%s", out))
 
 }
 
@@ -185,6 +187,8 @@
 }
 
 func (s *DockerSuite) TestPsListContainersFilterStatus(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
+
 	// start exited container
 	out := cli.DockerCmd(c, "run", "-d", "busybox").Combined()
 	firstID := strings.TrimSpace(out)
@@ -199,16 +203,16 @@
 	// filter containers by exited
 	out = cli.DockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=exited").Combined()
 	containerOut := strings.TrimSpace(out)
-	c.Assert(containerOut, checker.Equals, firstID)
+	c.Assert(RemoveOutputForExistingElements(containerOut, existingContainers), checker.Equals, firstID)
 
 	out = cli.DockerCmd(c, "ps", "-a", "--no-trunc", "-q", "--filter=status=running").Combined()
 	containerOut = strings.TrimSpace(out)
-	c.Assert(containerOut, checker.Equals, secondID)
+	c.Assert(RemoveOutputForExistingElements(containerOut, existingContainers), checker.Equals, secondID)
 
 	result := cli.Docker(cli.Args("ps", "-a", "-q", "--filter=status=rubbish"), cli.WithTimeout(time.Second*60))
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		ExitCode: 1,
-		Err:      "Unrecognised filter value for status",
+		Err:      "Invalid filter 'status=rubbish'",
 	})
 
 	// Windows doesn't support pausing of containers
@@ -222,11 +226,12 @@
 
 		out = cli.DockerCmd(c, "ps", "--no-trunc", "-q", "--filter=status=paused").Combined()
 		containerOut = strings.TrimSpace(out)
-		c.Assert(containerOut, checker.Equals, pausedID)
+		c.Assert(RemoveOutputForExistingElements(containerOut, existingContainers), checker.Equals, pausedID)
 	}
 }
 
 func (s *DockerSuite) TestPsListContainersFilterHealth(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
 	// Test legacy no health check
 	out := runSleepingContainer(c, "--name=none_legacy")
 	containerID := strings.TrimSpace(out)
@@ -264,7 +269,7 @@
 	waitForHealthStatus(c, "passing_container", "starting", "healthy")
 
 	out = cli.DockerCmd(c, "ps", "-q", "--no-trunc", "--filter=health=healthy").Combined()
-	containerOut = strings.TrimSpace(out)
+	containerOut = strings.TrimSpace(RemoveOutputForExistingElements(out, existingContainers))
 	c.Assert(containerOut, checker.Equals, containerID, check.Commentf("Expected containerID %s, got %s for healthy filter, output: %q", containerID, containerOut, out))
 }
 
@@ -305,6 +310,8 @@
 // - Run containers for each of those image (busybox, images_ps_filter_test1, images_ps_filter_test2)
 // - Filter them out :P
 func (s *DockerSuite) TestPsListContainersFilterAncestorImage(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
+
 	// Build images
 	imageName1 := "images_ps_filter_test1"
 	buildImageSuccessfully(c, imageName1, build.WithDockerfile(`FROM busybox
@@ -367,12 +374,12 @@
 	var out string
 	for _, filter := range filterTestSuite {
 		out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+filter.filterName)
-		checkPsAncestorFilterOutput(c, out, filter.filterName, filter.expectedIDs)
+		checkPsAncestorFilterOutput(c, RemoveOutputForExistingElements(out, existingContainers), filter.filterName, filter.expectedIDs)
 	}
 
 	// Multiple ancestor filter
 	out, _ = dockerCmd(c, "ps", "-a", "-q", "--no-trunc", "--filter=ancestor="+imageName2, "--filter=ancestor="+imageName1Tagged)
-	checkPsAncestorFilterOutput(c, out, imageName2+","+imageName1Tagged, []string{fourthID, fifthID})
+	checkPsAncestorFilterOutput(c, RemoveOutputForExistingElements(out, existingContainers), imageName2+","+imageName1Tagged, []string{fourthID, fifthID})
 }
 
 func checkPsAncestorFilterOutput(c *check.C, out string, filterName string, expectedIDs []string) {
@@ -469,6 +476,9 @@
 func (s *DockerSuite) TestPsRightTagName(c *check.C) {
 	// TODO Investigate further why this fails on Windows to Windows CI
 	testRequires(c, DaemonIsLinux)
+
+	existingContainers := ExistingContainerNames(c)
+
 	tag := "asybox:shmatest"
 	dockerCmd(c, "tag", "busybox", tag)
 
@@ -490,6 +500,7 @@
 
 	out, _ = dockerCmd(c, "ps", "--no-trunc")
 	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	// skip header
 	lines = lines[1:]
 	c.Assert(lines, checker.HasLen, 3, check.Commentf("There should be 3 running container, got %d", len(lines)))
@@ -511,6 +522,7 @@
 func (s *DockerSuite) TestPsLinkedWithNoTrunc(c *check.C) {
 	// Problematic on Windows as it doesn't support links as of Jan 2016
 	testRequires(c, DaemonIsLinux)
+	existingContainers := ExistingContainerIDs(c)
 	runSleepingContainer(c, "--name=first")
 	runSleepingContainer(c, "--name=second", "--link=first:first")
 
@@ -518,6 +530,7 @@
 	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
 	// strip header
 	lines = lines[1:]
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	expected := []string{"second", "first,second/first"}
 	var names []string
 	for _, l := range lines {
@@ -581,12 +594,14 @@
 func (s *DockerSuite) TestPsFormatMultiNames(c *check.C) {
 	// Problematic on Windows as it doesn't support link as of Jan 2016
 	testRequires(c, DaemonIsLinux)
+	existingContainers := ExistingContainerNames(c)
 	//create 2 containers and link them
 	dockerCmd(c, "run", "--name=child", "-d", "busybox", "top")
 	dockerCmd(c, "run", "--name=parent", "--link=child:linkedone", "-d", "busybox", "top")
 
 	//use the new format capabilities to only list the names and --no-trunc to get all names
 	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}}", "--no-trunc")
+	out = RemoveOutputForExistingElements(out, existingContainers)
 	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
 	expected := []string{"parent", "child,parent/linkedone"}
 	var names []string
@@ -595,6 +610,7 @@
 
 	//now list without turning off truncation and make sure we only get the non-link names
 	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}}")
+	out = RemoveOutputForExistingElements(out, existingContainers)
 	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
 	expected = []string{"parent", "child"}
 	var truncNames []string
@@ -604,30 +620,22 @@
 
 // Test for GitHub issue #21772
 func (s *DockerSuite) TestPsNamesMultipleTime(c *check.C) {
+	existingContainers := ExistingContainerNames(c)
 	runSleepingContainer(c, "--name=test1")
 	runSleepingContainer(c, "--name=test2")
 
 	//use the new format capabilities to list the names twice
 	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Names}}")
 	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	expected := []string{"test2 test2", "test1 test1"}
 	var names []string
 	names = append(names, lines...)
 	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with names displayed twice: %v, got: %v", expected, names))
 }
 
-func (s *DockerSuite) TestPsFormatHeaders(c *check.C) {
-	// make sure no-container "docker ps" still prints the header row
-	out, _ := dockerCmd(c, "ps", "--format", "table {{.ID}}")
-	c.Assert(out, checker.Equals, "CONTAINER ID\n", check.Commentf(`Expected 'CONTAINER ID\n', got %v`, out))
-
-	// verify that "docker ps" with a container still prints the header row also
-	runSleepingContainer(c, "--name=test")
-	out, _ = dockerCmd(c, "ps", "--format", "table {{.Names}}")
-	c.Assert(out, checker.Equals, "NAMES\ntest\n", check.Commentf(`Expected 'NAMES\ntest\n', got %v`, out))
-}
-
 func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
 	config := `{
 		"psFormat": "default {{ .ID }}"
 }`
@@ -642,6 +650,7 @@
 	id := strings.TrimSpace(out)
 
 	out, _ = dockerCmd(c, "--config", d, "ps", "-q")
+	out = RemoveOutputForExistingElements(out, existingContainers)
 	c.Assert(id, checker.HasPrefix, strings.TrimSpace(out), check.Commentf("Expected to print only the container id, got %v\n", out))
 }
 
@@ -652,6 +661,8 @@
 	originalImageName := "busybox:TestPsImageIDAfterUpdate-original"
 	updatedImageName := "busybox:TestPsImageIDAfterUpdate-updated"
 
+	existingContainers := ExistingContainerIDs(c)
+
 	icmd.RunCommand(dockerBinary, "tag", "busybox:latest", originalImageName).Assert(c, icmd.Success)
 
 	originalImageID := getIDByName(c, originalImageName)
@@ -664,6 +675,7 @@
 	result.Assert(c, icmd.Success)
 
 	lines := strings.Split(strings.TrimSpace(string(result.Combined())), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	// skip header
 	lines = lines[1:]
 	c.Assert(len(lines), checker.Equals, 1)
@@ -680,6 +692,7 @@
 	result.Assert(c, icmd.Success)
 
 	lines = strings.Split(strings.TrimSpace(string(result.Combined())), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	// skip header
 	lines = lines[1:]
 	c.Assert(len(lines), checker.Equals, 1)
@@ -710,6 +723,8 @@
 }
 
 func (s *DockerSuite) TestPsShowMounts(c *check.C) {
+	existingContainers := ExistingContainerNames(c)
+
 	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
 
 	mp := prefix + slash + "test"
@@ -736,6 +751,7 @@
 	out, _ := dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}")
 
 	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	c.Assert(lines, checker.HasLen, 3)
 
 	fields := strings.Fields(lines[0])
@@ -755,6 +771,7 @@
 	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume=ps-volume-test")
 
 	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	c.Assert(lines, checker.HasLen, 1)
 
 	fields = strings.Fields(lines[0])
@@ -768,6 +785,7 @@
 	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+mp)
 
 	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	c.Assert(lines, checker.HasLen, 2)
 
 	fields = strings.Fields(lines[0])
@@ -779,6 +797,7 @@
 	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountSource)
 
 	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	c.Assert(lines, checker.HasLen, 1)
 
 	fields = strings.Fields(lines[0])
@@ -790,6 +809,7 @@
 	out, _ = dockerCmd(c, "ps", "--format", "{{.Names}} {{.Mounts}}", "--filter", "volume="+bindMountDestination)
 
 	lines = strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
 	c.Assert(lines, checker.HasLen, 1)
 
 	fields = strings.Fields(lines[0])
@@ -820,6 +840,8 @@
 }
 
 func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) {
+	existing := ExistingContainerIDs(c)
+
 	// TODO default network on Windows is not called "bridge", and creating a
 	// custom network fails on Windows fails with "Error response from daemon: plugin not found")
 	testRequires(c, DaemonIsLinux)
@@ -837,7 +859,7 @@
 	lines = lines[1:]
 
 	// ps output should have no containers
-	c.Assert(lines, checker.HasLen, 0)
+	c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 0)
 
 	// Filter docker ps on network bridge
 	out, _ = dockerCmd(c, "ps", "--filter", "network=bridge")
@@ -849,7 +871,7 @@
 	lines = lines[1:]
 
 	// ps output should have only one container
-	c.Assert(lines, checker.HasLen, 1)
+	c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 1)
 
 	// Making sure onbridgenetwork is on the output
 	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n"))
@@ -864,7 +886,7 @@
 	lines = lines[1:]
 
 	//ps output should have both the containers
-	c.Assert(lines, checker.HasLen, 2)
+	c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 2)
 
 	// Making sure onbridgenetwork and onnonenetwork is on the output
 	c.Assert(containerOut, checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n"))
@@ -885,11 +907,12 @@
 	containerOut = strings.TrimSpace(string(out))
 
 	lines = strings.Split(containerOut, "\n")
+
 	// skip header
 	lines = lines[1:]
 
 	// ps output should have only one container
-	c.Assert(lines, checker.HasLen, 1)
+	c.Assert(RemoveLinesForExistingElements(lines, existing), checker.HasLen, 1)
 
 	// Making sure onbridgenetwork is on the output
 	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n"))
@@ -927,13 +950,16 @@
 
 // Test case for 30291
 func (s *DockerSuite) TestPsFormatTemplateWithArg(c *check.C) {
+	existingContainers := ExistingContainerNames(c)
 	runSleepingContainer(c, "-d", "--name", "top", "--label", "some.label=label.foo-bar")
 	out, _ := dockerCmd(c, "ps", "--format", `{{.Names}} {{.Label "some.label"}}`)
+	out = RemoveOutputForExistingElements(out, existingContainers)
 	c.Assert(strings.TrimSpace(out), checker.Equals, "top label.foo-bar")
 }
 
 func (s *DockerSuite) TestPsListContainersFilterPorts(c *check.C) {
 	testRequires(c, DaemonIsLinux)
+	existingContainers := ExistingContainerIDs(c)
 
 	out, _ := dockerCmd(c, "run", "-d", "--publish=80", "busybox", "top")
 	id1 := strings.TrimSpace(out)
@@ -962,6 +988,30 @@
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), id2)
 
 	out, _ = dockerCmd(c, "ps", "--no-trunc", "-q", "--filter", "expose=8080/tcp")
+	out = RemoveOutputForExistingElements(out, existingContainers)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), id1)
 	c.Assert(strings.TrimSpace(out), checker.Equals, id2)
 }
+
+func (s *DockerSuite) TestPsNotShowLinknamesOfDeletedContainer(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+
+	existingContainers := ExistingContainerNames(c)
+
+	dockerCmd(c, "create", "--name=aaa", "busybox", "top")
+	dockerCmd(c, "create", "--name=bbb", "--link=aaa", "busybox", "top")
+
+	out, _ := dockerCmd(c, "ps", "--no-trunc", "-a", "--format", "{{.Names}}")
+	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+	lines = RemoveLinesForExistingElements(lines, existingContainers)
+	expected := []string{"bbb", "aaa,bbb/aaa"}
+	var names []string
+	names = append(names, lines...)
+	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with non-truncated names: %v, got: %v", expected, names))
+
+	dockerCmd(c, "rm", "bbb")
+
+	out, _ = dockerCmd(c, "ps", "--no-trunc", "-a", "--format", "{{.Names}}")
+	out = RemoveOutputForExistingElements(out, existingContainers)
+	c.Assert(strings.TrimSpace(out), checker.Equals, "aaa")
+}
diff --git a/integration-cli/docker_cli_pull_local_test.go b/integration-cli/docker_cli_pull_local_test.go
index a45e313..79b9390 100644
--- a/integration-cli/docker_cli_pull_local_test.go
+++ b/integration-cli/docker_cli_pull_local_test.go
@@ -15,8 +15,8 @@
 	"github.com/docker/distribution/manifest/schema2"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli/build"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/opencontainers/go-digest"
 )
 
diff --git a/integration-cli/docker_cli_pull_test.go b/integration-cli/docker_cli_pull_test.go
index fd91edb..56e518b 100644
--- a/integration-cli/docker_cli_pull_test.go
+++ b/integration-cli/docker_cli_pull_test.go
@@ -193,25 +193,26 @@
 // results in more images than a naked pull.
 func (s *DockerHubPullSuite) TestPullAllTagsFromCentralRegistry(c *check.C) {
 	testRequires(c, DaemonIsLinux)
-	s.Cmd(c, "pull", "busybox")
-	outImageCmd := s.Cmd(c, "images", "busybox")
+	s.Cmd(c, "pull", "dockercore/engine-pull-all-test-fixture")
+	outImageCmd := s.Cmd(c, "images", "dockercore/engine-pull-all-test-fixture")
 	splitOutImageCmd := strings.Split(strings.TrimSpace(outImageCmd), "\n")
 	c.Assert(splitOutImageCmd, checker.HasLen, 2)
 
-	s.Cmd(c, "pull", "--all-tags=true", "busybox")
-	outImageAllTagCmd := s.Cmd(c, "images", "busybox")
+	s.Cmd(c, "pull", "--all-tags=true", "dockercore/engine-pull-all-test-fixture")
+	outImageAllTagCmd := s.Cmd(c, "images", "dockercore/engine-pull-all-test-fixture")
 	linesCount := strings.Count(outImageAllTagCmd, "\n")
 	c.Assert(linesCount, checker.GreaterThan, 2, check.Commentf("pulling all tags should provide more than two images, got %s", outImageAllTagCmd))
 
-	// Verify that the line for 'busybox:latest' is left unchanged.
+	// Verify that the line for 'dockercore/engine-pull-all-test-fixture:latest' is left unchanged.
 	var latestLine string
 	for _, line := range strings.Split(outImageAllTagCmd, "\n") {
-		if strings.HasPrefix(line, "busybox") && strings.Contains(line, "latest") {
+		if strings.HasPrefix(line, "dockercore/engine-pull-all-test-fixture") && strings.Contains(line, "latest") {
 			latestLine = line
 			break
 		}
 	}
-	c.Assert(latestLine, checker.Not(checker.Equals), "", check.Commentf("no entry for busybox:latest found after pulling all tags"))
+	c.Assert(latestLine, checker.Not(checker.Equals), "", check.Commentf("no entry for dockercore/engine-pull-all-test-fixture:latest found after pulling all tags"))
+
 	splitLatest := strings.Fields(latestLine)
 	splitCurrent := strings.Fields(splitOutImageCmd[1])
 
@@ -227,7 +228,7 @@
 	splitCurrent[4] = ""
 	splitCurrent[5] = ""
 
-	c.Assert(splitLatest, checker.DeepEquals, splitCurrent, check.Commentf("busybox:latest was changed after pulling all tags"))
+	c.Assert(splitLatest, checker.DeepEquals, splitCurrent, check.Commentf("dockercore/engine-pull-all-test-fixture:latest was changed after pulling all tags"))
 }
 
 // TestPullClientDisconnect kills the client during a pull operation and verifies that the operation
@@ -273,7 +274,7 @@
 func (s *DockerSuite) TestPullLinuxImageFailsOnWindows(c *check.C) {
 	testRequires(c, DaemonIsWindows, Network)
 	_, _, err := dockerCmdWithError("pull", "ubuntu")
-	c.Assert(err.Error(), checker.Contains, "cannot be used on this platform")
+	c.Assert(err.Error(), checker.Contains, "no matching manifest")
 }
 
 // Regression test for https://github.com/docker/docker/issues/28892
diff --git a/integration-cli/docker_cli_pull_trusted_test.go b/integration-cli/docker_cli_pull_trusted_test.go
index d9628d9..60e1c3d 100644
--- a/integration-cli/docker_cli_pull_trusted_test.go
+++ b/integration-cli/docker_cli_pull_trusted_test.go
@@ -7,8 +7,8 @@
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerTrustSuite) TestTrustedPull(c *check.C) {
diff --git a/integration-cli/docker_cli_push_test.go b/integration-cli/docker_cli_push_test.go
index 2ae206d..94efa08 100644
--- a/integration-cli/docker_cli_push_test.go
+++ b/integration-cli/docker_cli_push_test.go
@@ -16,8 +16,8 @@
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 // Pushing an image to a private registry.
diff --git a/integration-cli/docker_cli_rename_test.go b/integration-cli/docker_cli_rename_test.go
index ea43022..de27759 100644
--- a/integration-cli/docker_cli_rename_test.go
+++ b/integration-cli/docker_cli_rename_test.go
@@ -5,8 +5,8 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/pkg/stringid"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestRenameStoppedContainer(c *check.C) {
@@ -63,12 +63,13 @@
 	c.Assert(name, checker.Equals, "/"+newName, check.Commentf("Failed to rename container %s", name))
 
 	result := dockerCmdWithResult("inspect", "-f={{.Name}}", "--type=container", "first_name")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		ExitCode: 1,
 		Err:      "No such container: first_name",
 	})
 }
 
+// TODO: move to unit test
 func (s *DockerSuite) TestRenameInvalidName(c *check.C) {
 	runSleepingContainer(c, "--name", "myname")
 
@@ -76,18 +77,6 @@
 	c.Assert(err, checker.NotNil, check.Commentf("Renaming container to invalid name should have failed: %s", out))
 	c.Assert(out, checker.Contains, "Invalid container name", check.Commentf("%v", err))
 
-	out, _, err = dockerCmdWithError("rename", "myname")
-	c.Assert(err, checker.NotNil, check.Commentf("Renaming container to invalid name should have failed: %s", out))
-	c.Assert(out, checker.Contains, "requires exactly 2 argument(s).", check.Commentf("%v", err))
-
-	out, _, err = dockerCmdWithError("rename", "myname", "")
-	c.Assert(err, checker.NotNil, check.Commentf("Renaming container to invalid name should have failed: %s", out))
-	c.Assert(out, checker.Contains, "may be empty", check.Commentf("%v", err))
-
-	out, _, err = dockerCmdWithError("rename", "", "newname")
-	c.Assert(err, checker.NotNil, check.Commentf("Renaming container with empty name should have failed: %s", out))
-	c.Assert(out, checker.Contains, "may be empty", check.Commentf("%v", err))
-
 	out, _ = dockerCmd(c, "ps", "-a")
 	c.Assert(out, checker.Contains, "myname", check.Commentf("Output of docker ps should have included 'myname': %s", out))
 }
diff --git a/integration-cli/docker_cli_rmi_test.go b/integration-cli/docker_cli_rmi_test.go
index afbc4c2..52c8837 100644
--- a/integration-cli/docker_cli_rmi_test.go
+++ b/integration-cli/docker_cli_rmi_test.go
@@ -9,8 +9,8 @@
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/pkg/stringid"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestRmiWithContainerFails(c *check.C) {
diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go
index 544cfdf..8198fde 100644
--- a/integration-cli/docker_cli_run_test.go
+++ b/integration-cli/docker_cli_run_test.go
@@ -21,21 +21,23 @@
 	"sync"
 	"time"
 
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
 	"github.com/docker/docker/integration-cli/cli/build/fakecontext"
 	"github.com/docker/docker/pkg/mount"
+	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringutils"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/docker/docker/runconfig"
 	"github.com/docker/go-connections/nat"
 	"github.com/docker/libnetwork/resolvconf"
 	"github.com/docker/libnetwork/types"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	libcontainerUser "github.com/opencontainers/runc/libcontainer/user"
+	"golang.org/x/net/context"
 )
 
 // "test123" should be printed by docker run
@@ -495,7 +497,7 @@
 func (s *DockerSuite) TestVolumesFromGetsProperMode(c *check.C) {
 	testRequires(c, SameHostDaemon)
 	prefix, slash := getPrefixAndSlashFromDaemonPlatform()
-	hostpath := testutil.RandomTmpDirPath("test", testEnv.DaemonPlatform())
+	hostpath := RandomTmpDirPath("test", testEnv.DaemonPlatform())
 	if err := os.MkdirAll(hostpath, 0755); err != nil {
 		c.Fatalf("Failed to create %s: %q", hostpath, err)
 	}
@@ -518,8 +520,8 @@
 
 // Test for GH#10618
 func (s *DockerSuite) TestRunNoDupVolumes(c *check.C) {
-	path1 := testutil.RandomTmpDirPath("test1", testEnv.DaemonPlatform())
-	path2 := testutil.RandomTmpDirPath("test2", testEnv.DaemonPlatform())
+	path1 := RandomTmpDirPath("test1", testEnv.DaemonPlatform())
+	path2 := RandomTmpDirPath("test2", testEnv.DaemonPlatform())
 
 	someplace := ":/someplace"
 	if testEnv.DaemonPlatform() == "windows" {
@@ -825,7 +827,7 @@
 	})
 	result.Assert(c, icmd.Success)
 
-	actualEnv := strings.Split(strings.TrimSpace(result.Combined()), "\n")
+	actualEnv := strings.Split(strings.TrimSuffix(result.Stdout(), "\n"), "\n")
 	sort.Strings(actualEnv)
 
 	goodEnv := []string{
@@ -1799,7 +1801,7 @@
 	}()
 
 	result = icmd.WaitOnCmd(60*time.Second, result)
-	c.Assert(result, icmd.Matches, icmd.Expected{ExitCode: 11})
+	result.Assert(c, icmd.Expected{ExitCode: 11})
 }
 
 // Test for #2267
@@ -2183,9 +2185,9 @@
 		c.Fatalf("Data was copied on volumes-from but shouldn't be:\n%q", out)
 	}
 
-	tmpDir := testutil.RandomTmpDirPath("docker_test_bind_mount_copy_data", testEnv.DaemonPlatform())
+	tmpDir := RandomTmpDirPath("docker_test_bind_mount_copy_data", testEnv.DaemonPlatform())
 	if out, _, err := dockerCmdWithError("run", "-v", tmpDir+":/foo", "dataimage", "ls", "-lh", "/foo/bar"); err == nil || !strings.Contains(out, "No such file or directory") {
-		c.Fatalf("Data was copied on bind-mount but shouldn't be:\n%q", out)
+		c.Fatalf("Data was copied on bind mount but shouldn't be:\n%q", out)
 	}
 }
 
@@ -2216,7 +2218,7 @@
 
 	out, err = inspectMountSourceField("dark_helmet", prefix+slash+`foo`)
 	c.Assert(err, check.IsNil)
-	if !strings.Contains(strings.ToLower(out), strings.ToLower(testEnv.VolumesConfigPath())) {
+	if !strings.Contains(strings.ToLower(out), strings.ToLower(testEnv.PlatformDefaults.VolumesConfigPath)) {
 		c.Fatalf("Volume was not defined for %s/foo\n%q", prefix, out)
 	}
 
@@ -2227,7 +2229,7 @@
 
 	out, err = inspectMountSourceField("dark_helmet", prefix+slash+"bar")
 	c.Assert(err, check.IsNil)
-	if !strings.Contains(strings.ToLower(out), strings.ToLower(testEnv.VolumesConfigPath())) {
+	if !strings.Contains(strings.ToLower(out), strings.ToLower(testEnv.PlatformDefaults.VolumesConfigPath)) {
 		c.Fatalf("Volume was not defined for %s/bar\n%q", prefix, out)
 	}
 }
@@ -2247,7 +2249,7 @@
 	if err := cont.Start(); err != nil {
 		c.Fatal(err)
 	}
-	n, err := testutil.ConsumeWithSpeed(stdout, 10000, 5*time.Millisecond, nil)
+	n, err := ConsumeWithSpeed(stdout, 10000, 5*time.Millisecond, nil)
 	if err != nil {
 		c.Fatal(err)
 	}
@@ -2814,23 +2816,27 @@
 
 // run container with --rm should remove container if exit code != 0
 func (s *DockerSuite) TestRunContainerWithRmFlagExitCodeNotEqualToZero(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
 	name := "flowers"
 	cli.Docker(cli.Args("run", "--name", name, "--rm", "busybox", "ls", "/notexists")).Assert(c, icmd.Expected{
 		ExitCode: 1,
 	})
 
 	out := cli.DockerCmd(c, "ps", "-q", "-a").Combined()
+	out = RemoveOutputForExistingElements(out, existingContainers)
 	if out != "" {
 		c.Fatal("Expected not to have containers", out)
 	}
 }
 
 func (s *DockerSuite) TestRunContainerWithRmFlagCannotStartContainer(c *check.C) {
+	existingContainers := ExistingContainerIDs(c)
 	name := "sparkles"
 	cli.Docker(cli.Args("run", "--name", name, "--rm", "busybox", "commandNotFound")).Assert(c, icmd.Expected{
 		ExitCode: 127,
 	})
 	out := cli.DockerCmd(c, "ps", "-q", "-a").Combined()
+	out = RemoveOutputForExistingElements(out, existingContainers)
 	if out != "" {
 		c.Fatal("Expected not to have containers", out)
 	}
@@ -3337,7 +3343,7 @@
 	if err != nil {
 		c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
 	}
-	cgroupPaths := testutil.ParseCgroupPaths(string(out))
+	cgroupPaths := ParseCgroupPaths(string(out))
 	if len(cgroupPaths) == 0 {
 		c.Fatalf("unexpected output - %q", string(out))
 	}
@@ -3377,7 +3383,7 @@
 		c.Fatalf("SECURITY: --cgroup-parent with ../../ relative paths cause files to be created in the host (this is bad) !!")
 	}
 
-	cgroupPaths := testutil.ParseCgroupPaths(string(out))
+	cgroupPaths := ParseCgroupPaths(string(out))
 	if len(cgroupPaths) == 0 {
 		c.Fatalf("unexpected output - %q", string(out))
 	}
@@ -3964,32 +3970,61 @@
 	dockerCmd(c, "run", "--rm", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
 	dockerCmd(c, "volume", "inspect", "test")
 	out, _ := dockerCmd(c, "volume", "ls", "-q")
-	c.Assert(strings.TrimSpace(out), checker.Equals, "test")
+	c.Assert(strings.TrimSpace(out), checker.Contains, "test")
 
 	dockerCmd(c, "run", "--name=test", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
 	dockerCmd(c, "rm", "-fv", "test")
 	dockerCmd(c, "volume", "inspect", "test")
 	out, _ = dockerCmd(c, "volume", "ls", "-q")
-	c.Assert(strings.TrimSpace(out), checker.Equals, "test")
+	c.Assert(strings.TrimSpace(out), checker.Contains, "test")
 }
 
 func (s *DockerSuite) TestRunNamedVolumesFromNotRemoved(c *check.C) {
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
 
 	dockerCmd(c, "volume", "create", "test")
-	dockerCmd(c, "run", "--name=parent", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
+	cid, _ := dockerCmd(c, "run", "-d", "--name=parent", "-v", "test:"+prefix+"/foo", "-v", prefix+"/bar", "busybox", "true")
 	dockerCmd(c, "run", "--name=child", "--volumes-from=parent", "busybox", "true")
 
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	container, err := cli.ContainerInspect(context.Background(), strings.TrimSpace(cid))
+	c.Assert(err, checker.IsNil)
+	var vname string
+	for _, v := range container.Mounts {
+		if v.Name != "test" {
+			vname = v.Name
+		}
+	}
+	c.Assert(vname, checker.Not(checker.Equals), "")
+
 	// Remove the parent so there are not other references to the volumes
 	dockerCmd(c, "rm", "-f", "parent")
 	// now remove the child and ensure the named volume (and only the named volume) still exists
 	dockerCmd(c, "rm", "-fv", "child")
 	dockerCmd(c, "volume", "inspect", "test")
 	out, _ := dockerCmd(c, "volume", "ls", "-q")
-	c.Assert(strings.TrimSpace(out), checker.Equals, "test")
+	c.Assert(strings.TrimSpace(out), checker.Contains, "test")
+	c.Assert(strings.TrimSpace(out), checker.Not(checker.Contains), vname)
 }
 
 func (s *DockerSuite) TestRunAttachFailedNoLeak(c *check.C) {
+	// TODO @msabansal - https://github.com/moby/moby/issues/35023. Duplicate
+	// port mappings are not errored out on RS3 builds. Temporarily disabling
+	// this test pending further investigation. Note we parse kernel.GetKernelVersion
+	// rather than system.GetOSVersion as test binaries aren't manifested, so would
+	// otherwise report build 9200.
+	if runtime.GOOS == "windows" {
+		v, err := kernel.GetKernelVersion()
+		c.Assert(err, checker.IsNil)
+		build, _ := strconv.Atoi(strings.Split(strings.SplitN(v.String(), " ", 3)[2][1:], ".")[0])
+		if build >= 16292 { // @jhowardmsft TODO - replace with final RS3 build and ==
+			c.Skip("Temporarily disabled on RS3 builds")
+		}
+	}
+
 	nroutines, err := getGoroutineNumber()
 	c.Assert(err, checker.IsNil)
 
@@ -4124,7 +4159,7 @@
 // Test that auto-remove is performed by the client on API versions that do not support daemon-side api-remove (API < 1.25)
 func (s *DockerSuite) TestRunRmPre125Api(c *check.C) {
 	name := "miss-me-when-im-gone"
-	envs := appendBaseEnv(false, "DOCKER_API_VERSION=1.24")
+	envs := appendBaseEnv(os.Getenv("DOCKER_TLS_VERIFY") != "", "DOCKER_API_VERSION=1.24")
 	cli.Docker(cli.Args("run", "--name="+name, "--rm", "busybox"), cli.WithEnvironmentVariables(envs...)).Assert(c, icmd.Success)
 
 	cli.Docker(cli.Inspect(name), cli.Format(".name")).Assert(c, icmd.Expected{
@@ -4610,10 +4645,7 @@
 
 // Verifies that running as local system is operating correctly on Windows
 func (s *DockerSuite) TestWindowsRunAsSystem(c *check.C) {
-	testRequires(c, DaemonIsWindows)
-	if testEnv.DaemonKernelVersionNumeric() < 15000 {
-		c.Skip("Requires build 15000 or later")
-	}
+	testRequires(c, DaemonIsWindowsAtLeastBuild(15000))
 	out, _ := dockerCmd(c, "run", "--net=none", `--user=nt authority\system`, "--hostname=XYZZY", minimalBaseImage(), "cmd", "/c", `@echo %USERNAME%`)
 	c.Assert(strings.TrimSpace(out), checker.Equals, "XYZZY$")
 }
diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go
index b3d1b07..dd32a72 100644
--- a/integration-cli/docker_cli_run_unix_test.go
+++ b/integration-cli/docker_cli_run_unix_test.go
@@ -4,6 +4,7 @@
 
 import (
 	"bufio"
+	"context"
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
@@ -16,6 +17,7 @@
 	"syscall"
 	"time"
 
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/cli/build"
@@ -23,8 +25,8 @@
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/sysinfo"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/kr/pty"
 )
 
@@ -675,7 +677,7 @@
 }
 
 func (s *DockerSuite) TestRunWithMemoryReservation(c *check.C) {
-	testRequires(c, memoryReservationSupport)
+	testRequires(c, SameHostDaemon, memoryReservationSupport)
 
 	file := "/sys/fs/cgroup/memory/memory.soft_limit_in_bytes"
 	out, _ := dockerCmd(c, "run", "--memory-reservation", "200M", "--name", "test", "busybox", "cat", file)
@@ -687,7 +689,7 @@
 
 func (s *DockerSuite) TestRunWithMemoryReservationInvalid(c *check.C) {
 	testRequires(c, memoryLimitSupport)
-	testRequires(c, memoryReservationSupport)
+	testRequires(c, SameHostDaemon, memoryReservationSupport)
 	out, _, err := dockerCmdWithError("run", "-m", "500M", "--memory-reservation", "800M", "busybox", "true")
 	c.Assert(err, check.NotNil)
 	expected := "Minimum memory limit can not be less than memory reservation limit"
@@ -1058,7 +1060,7 @@
 	testRequires(c, SameHostDaemon, seccompEnabled, IsAmd64)
 	ensureSyscallTest(c)
 
-	icmd.RunCommand(dockerBinary, "run", "syscall-test", "exit32-test", "id").Assert(c, icmd.Success)
+	icmd.RunCommand(dockerBinary, "run", "syscall-test", "exit32-test").Assert(c, icmd.Success)
 }
 
 // TestRunSeccompAllowSetrlimit checks that 'docker run debian:jessie ulimit -v 1048510' succeeds.
@@ -1399,7 +1401,7 @@
 
 // TestRunPIDsLimit makes sure the pids cgroup is set with --pids-limit
 func (s *DockerSuite) TestRunPIDsLimit(c *check.C) {
-	testRequires(c, pidsLimit)
+	testRequires(c, SameHostDaemon, pidsLimit)
 
 	file := "/sys/fs/cgroup/pids/pids.max"
 	out, _ := dockerCmd(c, "run", "--name", "skittles", "--pids-limit", "4", "busybox", "cat", file)
@@ -1563,14 +1565,18 @@
 	out, _ := dockerCmd(c, "run", "--cpus", "0.5", "--name", "test", "busybox", "sh", "-c", fmt.Sprintf("cat %s && cat %s", file1, file2))
 	c.Assert(strings.TrimSpace(out), checker.Equals, "50000\n100000")
 
-	out = inspectField(c, "test", "HostConfig.NanoCpus")
-	c.Assert(out, checker.Equals, "5e+08", check.Commentf("setting the Nano CPUs failed"))
+	clt, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	inspect, err := clt.ContainerInspect(context.Background(), "test")
+	c.Assert(err, checker.IsNil)
+	c.Assert(inspect.HostConfig.NanoCPUs, checker.Equals, int64(500000000))
+
 	out = inspectField(c, "test", "HostConfig.CpuQuota")
 	c.Assert(out, checker.Equals, "0", check.Commentf("CPU CFS quota should be 0"))
 	out = inspectField(c, "test", "HostConfig.CpuPeriod")
 	c.Assert(out, checker.Equals, "0", check.Commentf("CPU CFS period should be 0"))
 
-	out, _, err := dockerCmdWithError("run", "--cpus", "0.5", "--cpu-quota", "50000", "--cpu-period", "100000", "busybox", "sh")
+	out, _, err = dockerCmdWithError("run", "--cpus", "0.5", "--cpu-quota", "50000", "--cpu-period", "100000", "busybox", "sh")
 	c.Assert(err, check.NotNil)
 	c.Assert(out, checker.Contains, "Conflicting options: Nano CPUs and CPU Period cannot both be set")
 }
diff --git a/integration-cli/docker_cli_save_load_test.go b/integration-cli/docker_cli_save_load_test.go
index 3b14576..3e6dc2d 100644
--- a/integration-cli/docker_cli_save_load_test.go
+++ b/integration-cli/docker_cli_save_load_test.go
@@ -1,8 +1,10 @@
 package main
 
 import (
+	"archive/tar"
 	"encoding/json"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -15,10 +17,9 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli/build"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
-	"github.com/opencontainers/go-digest"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	digest "github.com/opencontainers/go-digest"
 )
 
 // save a repo using gz compression and try to load it using stdout
@@ -32,7 +33,7 @@
 
 	dockerCmd(c, "inspect", repoName)
 
-	repoTarball, _, err := testutil.RunCommandPipelineWithOutput(
+	repoTarball, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", repoName),
 		exec.Command("xz", "-c"),
 		exec.Command("gzip", "-c"))
@@ -61,7 +62,7 @@
 
 	dockerCmd(c, "inspect", repoName)
 
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", repoName),
 		exec.Command("xz", "-c"),
 		exec.Command("gzip", "-c"))
@@ -88,7 +89,7 @@
 	out, _ := dockerCmd(c, "images", "-q", "--no-trunc", repoName)
 	cleanedImageID := strings.TrimSpace(out)
 
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", fmt.Sprintf("%v:latest", repoName)),
 		exec.Command("tar", "t"),
 		exec.Command("grep", "-E", fmt.Sprintf("(^repositories$|%v)", cleanedImageID)))
@@ -107,7 +108,7 @@
 	c.Assert(err, checker.IsNil, check.Commentf("failed to marshal from %q: err %v", repoName, err))
 	c.Assert(len(data), checker.Not(checker.Equals), 0, check.Commentf("failed to marshal the data from %q", repoName))
 	tarTvTimeFormat := "2006-01-02 15:04"
-	out, _, err = testutil.RunCommandPipelineWithOutput(
+	out, err = RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", repoName),
 		exec.Command("tar", "tv"),
 		exec.Command("grep", "-E", fmt.Sprintf("%s %s", data[0].Created.Format(tarTvTimeFormat), digest.Digest(data[0].ID).Hex())))
@@ -165,7 +166,7 @@
 
 	before, _ := dockerCmd(c, "inspect", repoName)
 
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", repoName),
 		exec.Command(dockerBinary, "load"))
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
@@ -194,7 +195,7 @@
 	// Make two images
 	dockerCmd(c, "tag", "emptyfs:latest", fmt.Sprintf("%v-two:latest", repoName))
 
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", fmt.Sprintf("%v-one", repoName), fmt.Sprintf("%v-two:latest", repoName)),
 		exec.Command("tar", "xO", "repositories"),
 		exec.Command("grep", "-q", "-E", "(-one|-two)"),
@@ -226,7 +227,7 @@
 	deleteImages(repoName)
 
 	// create the archive
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", repoName, "busybox:latest"),
 		exec.Command("tar", "t"))
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save multiple images: %s, %v", out, err))
@@ -270,7 +271,7 @@
 	RUN adduser -D user && mkdir -p /opt/a/b && chown -R user:user /opt/a
 	RUN touch /opt/a/b/c && chown user:user /opt/a/b/c`))
 
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", name),
 		exec.Command("tar", "-xf", "-", "-C", extractionDirectory),
 	)
@@ -289,7 +290,7 @@
 			c.Assert(err, checker.IsNil, check.Commentf("failed to open %s: %s", layerPath, err))
 			defer f.Close()
 
-			entries, err := testutil.ListTar(f)
+			entries, err := listTar(f)
 			for _, e := range entries {
 				if !strings.Contains(e, "dev/") {
 					entriesSansDev = append(entriesSansDev, e)
@@ -308,6 +309,23 @@
 
 }
 
+func listTar(f io.Reader) ([]string, error) {
+	tr := tar.NewReader(f)
+	var entries []string
+
+	for {
+		th, err := tr.Next()
+		if err == io.EOF {
+			// end of tar archive
+			return entries, nil
+		}
+		if err != nil {
+			return entries, err
+		}
+		entries = append(entries, th.Name)
+	}
+}
+
 // Test loading a weird image where one of the layers is of zero size.
 // The layer.tar file is actually zero bytes, no padding or anything else.
 // See issue: 18170
@@ -365,7 +383,7 @@
 	id := inspectField(c, name, "Id")
 
 	// Test to make sure that save w/o name just shows imageID during load
-	out, _, err := testutil.RunCommandPipelineWithOutput(
+	out, err := RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", id),
 		exec.Command(dockerBinary, "load"))
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
@@ -376,7 +394,7 @@
 	c.Assert(out, checker.Contains, id)
 
 	// Test to make sure that save by name shows that name during load
-	out, _, err = testutil.RunCommandPipelineWithOutput(
+	out, err = RunCommandPipelineWithOutput(
 		exec.Command(dockerBinary, "save", name),
 		exec.Command(dockerBinary, "load"))
 	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
diff --git a/integration-cli/docker_cli_save_load_unix_test.go b/integration-cli/docker_cli_save_load_unix_test.go
index deb0616..fcbfd7e 100644
--- a/integration-cli/docker_cli_save_load_unix_test.go
+++ b/integration-cli/docker_cli_save_load_unix_test.go
@@ -13,8 +13,8 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli/build"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/kr/pty"
 )
 
diff --git a/integration-cli/docker_cli_service_create_test.go b/integration-cli/docker_cli_service_create_test.go
index 6fc92c2..ac7eff7 100644
--- a/integration-cli/docker_cli_service_create_test.go
+++ b/integration-cli/docker_cli_service_create_test.go
@@ -76,7 +76,7 @@
 	})
 	c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("secrets: %s", id))
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "--secret", testName, "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--secret", testName, "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName)
@@ -122,7 +122,7 @@
 	}
 
 	serviceName := "svc"
-	serviceCmd := []string{"service", "create", "--no-resolve-image", "--name", serviceName}
+	serviceCmd := []string{"service", "create", "--detach", "--no-resolve-image", "--name", serviceName}
 	serviceCmd = append(serviceCmd, secretFlags...)
 	serviceCmd = append(serviceCmd, "busybox", "top")
 	out, err := d.Cmd(serviceCmd...)
@@ -175,7 +175,7 @@
 	c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("secrets: %s", id))
 
 	serviceName := "svc"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "--secret", "source=mysecret,target=target1", "--secret", "source=mysecret,target=target2", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--secret", "source=mysecret,target=target1", "--secret", "source=mysecret,target=target2", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName)
@@ -224,7 +224,7 @@
 	})
 	c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("configs: %s", id))
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "--config", testName, "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--config", testName, "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Configs }}", serviceName)
@@ -269,7 +269,7 @@
 	}
 
 	serviceName := "svc"
-	serviceCmd := []string{"service", "create", "--no-resolve-image", "--name", serviceName}
+	serviceCmd := []string{"service", "create", "--detach", "--no-resolve-image", "--name", serviceName}
 	serviceCmd = append(serviceCmd, configFlags...)
 	serviceCmd = append(serviceCmd, "busybox", "top")
 	out, err := d.Cmd(serviceCmd...)
@@ -322,7 +322,7 @@
 	c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("configs: %s", id))
 
 	serviceName := "svc"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "--config", "source=myconfig,target=target1", "--config", "source=myconfig,target=target2", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--config", "source=myconfig,target=target1", "--config", "source=myconfig,target=target2", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Configs }}", serviceName)
diff --git a/integration-cli/docker_cli_service_logs_test.go b/integration-cli/docker_cli_service_logs_test.go
index d2ce36d..b17c948 100644
--- a/integration-cli/docker_cli_service_logs_test.go
+++ b/integration-cli/docker_cli_service_logs_test.go
@@ -12,8 +12,8 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/daemon"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 type logMessage struct {
@@ -31,7 +31,7 @@
 	}
 
 	for name, message := range services {
-		out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox",
+		out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox",
 			"sh", "-c", fmt.Sprintf("echo %s; tail -f /dev/null", message))
 		c.Assert(err, checker.IsNil)
 		c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
@@ -40,7 +40,7 @@
 	// make sure task has been deployed.
 	waitAndAssert(c, defaultReconciliationTimeout,
 		d.CheckRunningTaskImages, checker.DeepEquals,
-		map[string]int{"busybox": len(services)})
+		map[string]int{"busybox:latest": len(services)})
 
 	for name, message := range services {
 		out, err := d.Cmd("service", "logs", name)
@@ -74,7 +74,7 @@
 	name := "TestServiceLogsCompleteness"
 
 	// make a service that prints 6 lines
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "for line in $(seq 0 5); do echo log test $line; done; sleep 100000")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "for line in $(seq 0 5); do echo log test $line; done; sleep 100000")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -101,7 +101,7 @@
 	name := "TestServiceLogsTail"
 
 	// make a service that prints 6 lines
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "for line in $(seq 1 6); do echo log test $line; done; sleep 100000")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "for line in $(seq 1 6); do echo log test $line; done; sleep 100000")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -125,7 +125,7 @@
 
 	name := "TestServiceLogsSince"
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "for i in $(seq 1 3); do sleep .1; echo log$i; done; sleep 10000000")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "for i in $(seq 1 3); do sleep .1; echo log$i; done; sleep 10000000")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1)
@@ -159,7 +159,7 @@
 
 	name := "TestServiceLogsFollow"
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "while true; do echo log test; sleep 0.1; done")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", "while true; do echo log test; sleep 0.1; done")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -207,7 +207,7 @@
 
 	result := icmd.RunCmd(d.Command(
 		// create a service with the name
-		"service", "create", "--no-resolve-image", "--name", name,
+		"service", "create", "--detach", "--no-resolve-image", "--name", name,
 		// which has some number of replicas
 		fmt.Sprintf("--replicas=%v", replicas),
 		// which has this the task id as an environment variable templated in
@@ -259,7 +259,7 @@
 
 	result := icmd.RunCmd(d.Command(
 		// create a service
-		"service", "create", "--no-resolve-image",
+		"service", "create", "--detach", "--no-resolve-image",
 		// name it $name
 		"--name", name,
 		// use a TTY
@@ -287,7 +287,7 @@
 	result = icmd.RunCmd(cmd)
 	// for some reason there is carriage return in the output. i think this is
 	// just expected.
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: "out\r\nerr\r\n"})
+	result.Assert(c, icmd.Expected{Out: "out\r\nerr\r\n"})
 }
 
 func (s *DockerSwarmSuite) TestServiceLogsNoHangDeletedContainer(c *check.C) {
@@ -297,7 +297,7 @@
 
 	result := icmd.RunCmd(d.Command(
 		// create a service
-		"service", "create", "--no-resolve-image",
+		"service", "create", "--detach", "--no-resolve-image",
 		// name it $name
 		"--name", name,
 		// busybox image, shell string
@@ -307,7 +307,7 @@
 	))
 
 	// confirm that the command succeeded
-	c.Assert(result, icmd.Matches, icmd.Expected{})
+	result.Assert(c, icmd.Expected{})
 	// get the service id
 	id := strings.TrimSpace(result.Stdout())
 	c.Assert(id, checker.Not(checker.Equals), "")
@@ -322,9 +322,9 @@
 	containerID := strings.TrimSpace(result.Stdout())
 	c.Assert(containerID, checker.Not(checker.Equals), "")
 	result = icmd.RunCmd(d.Command("stop", containerID))
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: containerID})
+	result.Assert(c, icmd.Expected{Out: containerID})
 	result = icmd.RunCmd(d.Command("rm", containerID))
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: containerID})
+	result.Assert(c, icmd.Expected{Out: containerID})
 
 	// run logs. use tail 2 to make sure we don't try to get a bunch of logs
 	// somehow and slow down execution time
@@ -336,7 +336,7 @@
 	// then, assert that the result matches expected. if the command timed out,
 	// if the command is timed out, result.Timeout will be true, but the
 	// Expected defaults to false
-	c.Assert(result, icmd.Matches, icmd.Expected{})
+	result.Assert(c, icmd.Expected{})
 }
 
 func (s *DockerSwarmSuite) TestServiceLogsDetails(c *check.C) {
@@ -346,7 +346,7 @@
 
 	result := icmd.RunCmd(d.Command(
 		// create a service
-		"service", "create", "--no-resolve-image",
+		"service", "create", "--detach", "--no-resolve-image",
 		// name it $name
 		"--name", name,
 		// add an environment variable
@@ -376,12 +376,12 @@
 	// in this case, we should get details and we should get log message, but
 	// there will also be context as details (which will fall after the detail
 	// we inserted in alphabetical order
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: "asdf=test1"})
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: "LogLine"})
+	result.Assert(c, icmd.Expected{Out: "asdf=test1"})
+	result.Assert(c, icmd.Expected{Out: "LogLine"})
 
 	// call service logs with details. this time, don't pass raw
 	result = icmd.RunCmd(d.Command("service", "logs", "--details", id))
 	// in this case, we should get details space logmessage as well. the context
 	// is part of the pretty part of the logline
-	c.Assert(result, icmd.Matches, icmd.Expected{Out: "asdf=test1 LogLine"})
+	result.Assert(c, icmd.Expected{Out: "asdf=test1 LogLine"})
 }
diff --git a/integration-cli/docker_cli_service_scale_test.go b/integration-cli/docker_cli_service_scale_test.go
index 8fb84fe..41b49d6 100644
--- a/integration-cli/docker_cli_service_scale_test.go
+++ b/integration-cli/docker_cli_service_scale_test.go
@@ -14,11 +14,11 @@
 	d := s.AddDaemon(c, true, true)
 
 	service1Name := "TestService1"
-	service1Args := append([]string{"service", "create", "--no-resolve-image", "--name", service1Name, defaultSleepImage}, sleepCommandForDaemonPlatform()...)
+	service1Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service1Name, defaultSleepImage}, sleepCommandForDaemonPlatform()...)
 
 	// global mode
 	service2Name := "TestService2"
-	service2Args := append([]string{"service", "create", "--no-resolve-image", "--name", service2Name, "--mode=global", defaultSleepImage}, sleepCommandForDaemonPlatform()...)
+	service2Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service2Name, "--mode=global", defaultSleepImage}, sleepCommandForDaemonPlatform()...)
 
 	// Create services
 	out, err := d.Cmd(service1Args...)
diff --git a/integration-cli/docker_cli_service_update_test.go b/integration-cli/docker_cli_service_update_test.go
index 086ae77..8f07170 100644
--- a/integration-cli/docker_cli_service_update_test.go
+++ b/integration-cli/docker_cli_service_update_test.go
@@ -15,7 +15,7 @@
 	d := s.AddDaemon(c, true, true)
 
 	serviceName := "TestServiceUpdatePort"
-	serviceArgs := append([]string{"service", "create", "--no-resolve-image", "--name", serviceName, "-p", "8080:8081", defaultSleepImage}, sleepCommandForDaemonPlatform()...)
+	serviceArgs := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "-p", "8080:8081", defaultSleepImage}, sleepCommandForDaemonPlatform()...)
 
 	// Create a service with a port mapping of 8080:8081.
 	out, err := d.Cmd(serviceArgs...)
@@ -23,7 +23,7 @@
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1)
 
 	// Update the service: changed the port mapping from 8080:8081 to 8082:8083.
-	_, err = d.Cmd("service", "update", "--publish-add", "8082:8083", "--publish-rm", "8081", serviceName)
+	_, err = d.Cmd("service", "update", "--detach", "--publish-add", "8082:8083", "--publish-rm", "8081", serviceName)
 	c.Assert(err, checker.IsNil)
 
 	// Inspect the service and verify port mapping
@@ -48,39 +48,39 @@
 
 func (s *DockerSwarmSuite) TestServiceUpdateLabel(c *check.C) {
 	d := s.AddDaemon(c, true, true)
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name=test", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name=test", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	service := d.GetService(c, "test")
 	c.Assert(service.Spec.Labels, checker.HasLen, 0)
 
 	// add label to empty set
-	out, err = d.Cmd("service", "update", "test", "--label-add", "foo=bar")
+	out, err = d.Cmd("service", "update", "--detach", "test", "--label-add", "foo=bar")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	service = d.GetService(c, "test")
 	c.Assert(service.Spec.Labels, checker.HasLen, 1)
 	c.Assert(service.Spec.Labels["foo"], checker.Equals, "bar")
 
 	// add label to non-empty set
-	out, err = d.Cmd("service", "update", "test", "--label-add", "foo2=bar")
+	out, err = d.Cmd("service", "update", "--detach", "test", "--label-add", "foo2=bar")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	service = d.GetService(c, "test")
 	c.Assert(service.Spec.Labels, checker.HasLen, 2)
 	c.Assert(service.Spec.Labels["foo2"], checker.Equals, "bar")
 
-	out, err = d.Cmd("service", "update", "test", "--label-rm", "foo2")
+	out, err = d.Cmd("service", "update", "--detach", "test", "--label-rm", "foo2")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	service = d.GetService(c, "test")
 	c.Assert(service.Spec.Labels, checker.HasLen, 1)
 	c.Assert(service.Spec.Labels["foo2"], checker.Equals, "")
 
-	out, err = d.Cmd("service", "update", "test", "--label-rm", "foo")
+	out, err = d.Cmd("service", "update", "--detach", "test", "--label-rm", "foo")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	service = d.GetService(c, "test")
 	c.Assert(service.Spec.Labels, checker.HasLen, 0)
 	c.Assert(service.Spec.Labels["foo"], checker.Equals, "")
 
 	// now make sure we can add again
-	out, err = d.Cmd("service", "update", "test", "--label-add", "foo=bar")
+	out, err = d.Cmd("service", "update", "--detach", "test", "--label-add", "foo=bar")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	service = d.GetService(c, "test")
 	c.Assert(service.Spec.Labels, checker.HasLen, 1)
@@ -100,11 +100,11 @@
 	testTarget := "testing"
 	serviceName := "test"
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// add secret
-	out, err = d.CmdRetryOutOfSequence("service", "update", "test", "--secret-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget))
+	out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--secret-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget))
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName)
@@ -119,7 +119,7 @@
 	c.Assert(refs[0].File.Name, checker.Equals, testTarget)
 
 	// remove
-	out, err = d.CmdRetryOutOfSequence("service", "update", "test", "--secret-rm", testName)
+	out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--secret-rm", testName)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName)
@@ -142,11 +142,11 @@
 	testTarget := "/testing"
 	serviceName := "test"
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// add config
-	out, err = d.CmdRetryOutOfSequence("service", "update", "test", "--config-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget))
+	out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--config-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget))
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Configs }}", serviceName)
@@ -161,7 +161,7 @@
 	c.Assert(refs[0].File.Name, checker.Equals, testTarget)
 
 	// remove
-	out, err = d.CmdRetryOutOfSequence("service", "update", "test", "--config-rm", testName)
+	out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--config-rm", testName)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Configs }}", serviceName)
diff --git a/integration-cli/docker_cli_stack_test.go b/integration-cli/docker_cli_stack_test.go
deleted file mode 100644
index 91fe4d7..0000000
--- a/integration-cli/docker_cli_stack_test.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// +build !windows
-
-package main
-
-import (
-	"encoding/json"
-	"io/ioutil"
-	"os"
-	"sort"
-	"strings"
-
-	"github.com/docker/docker/api/types/swarm"
-	"github.com/docker/docker/integration-cli/checker"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
-	"github.com/go-check/check"
-)
-
-var cleanSpaces = func(s string) string {
-	lines := strings.Split(s, "\n")
-	for i, line := range lines {
-		spaceIx := strings.Index(line, " ")
-		if spaceIx > 0 {
-			lines[i] = line[:spaceIx+1] + strings.TrimLeft(line[spaceIx:], " ")
-		}
-	}
-	return strings.Join(lines, "\n")
-}
-
-func (s *DockerSwarmSuite) TestStackRemoveUnknown(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	stackArgs := append([]string{"stack", "remove", "UNKNOWN_STACK"})
-
-	out, err := d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, check.Equals, "Nothing found in stack: UNKNOWN_STACK\n")
-}
-
-func (s *DockerSwarmSuite) TestStackPSUnknown(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	stackArgs := append([]string{"stack", "ps", "UNKNOWN_STACK"})
-
-	out, err := d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, check.Equals, "Nothing found in stack: UNKNOWN_STACK\n")
-}
-
-func (s *DockerSwarmSuite) TestStackServicesUnknown(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	stackArgs := append([]string{"stack", "services", "UNKNOWN_STACK"})
-
-	out, err := d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, check.Equals, "Nothing found in stack: UNKNOWN_STACK\n")
-}
-
-func (s *DockerSwarmSuite) TestStackDeployComposeFile(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	testStackName := "testdeploy"
-	stackArgs := []string{
-		"stack", "deploy",
-		"--compose-file", "fixtures/deploy/default.yaml",
-		testStackName,
-	}
-	out, err := d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil, check.Commentf(out))
-
-	out, err = d.Cmd("stack", "ls")
-	c.Assert(err, checker.IsNil)
-	c.Assert(cleanSpaces(out), check.Equals, "NAME SERVICES\n"+"testdeploy 2\n")
-
-	out, err = d.Cmd("stack", "rm", testStackName)
-	c.Assert(err, checker.IsNil)
-	out, err = d.Cmd("stack", "ls")
-	c.Assert(err, checker.IsNil)
-	c.Assert(cleanSpaces(out), check.Equals, "NAME SERVICES\n")
-}
-
-func (s *DockerSwarmSuite) TestStackDeployWithSecretsTwice(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	out, err := d.Cmd("secret", "create", "outside", "fixtures/secrets/default")
-	c.Assert(err, checker.IsNil, check.Commentf(out))
-
-	testStackName := "testdeploy"
-	stackArgs := []string{
-		"stack", "deploy",
-		"--compose-file", "fixtures/deploy/secrets.yaml",
-		testStackName,
-	}
-	out, err = d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil, check.Commentf(out))
-
-	out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", "testdeploy_web")
-	c.Assert(err, checker.IsNil)
-
-	var refs []swarm.SecretReference
-	c.Assert(json.Unmarshal([]byte(out), &refs), checker.IsNil)
-	c.Assert(refs, checker.HasLen, 3)
-
-	sort.Sort(sortSecrets(refs))
-	c.Assert(refs[0].SecretName, checker.Equals, "outside")
-	c.Assert(refs[1].SecretName, checker.Equals, "testdeploy_special")
-	c.Assert(refs[1].File.Name, checker.Equals, "special")
-	c.Assert(refs[2].SecretName, checker.Equals, "testdeploy_super")
-	c.Assert(refs[2].File.Name, checker.Equals, "foo.txt")
-	c.Assert(refs[2].File.Mode, checker.Equals, os.FileMode(0400))
-
-	// Deploy again to ensure there are no errors when secret hasn't changed
-	out, err = d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil, check.Commentf(out))
-}
-
-func (s *DockerSwarmSuite) TestStackRemove(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	stackName := "testdeploy"
-	stackArgs := []string{
-		"stack", "deploy",
-		"--compose-file", "fixtures/deploy/remove.yaml",
-		stackName,
-	}
-	result := icmd.RunCmd(d.Command(stackArgs...))
-	result.Assert(c, icmd.Expected{
-		Err: icmd.None,
-		Out: "Creating service testdeploy_web",
-	})
-
-	result = icmd.RunCmd(d.Command("service", "ls"))
-	result.Assert(c, icmd.Success)
-	c.Assert(
-		strings.Split(strings.TrimSpace(result.Stdout()), "\n"),
-		checker.HasLen, 2)
-
-	result = icmd.RunCmd(d.Command("stack", "rm", stackName))
-	result.Assert(c, icmd.Success)
-	stderr := result.Stderr()
-	c.Assert(stderr, checker.Contains, "Removing service testdeploy_web")
-	c.Assert(stderr, checker.Contains, "Removing network testdeploy_default")
-	c.Assert(stderr, checker.Contains, "Removing secret testdeploy_special")
-}
-
-type sortSecrets []swarm.SecretReference
-
-func (s sortSecrets) Len() int           { return len(s) }
-func (s sortSecrets) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s sortSecrets) Less(i, j int) bool { return s[i].SecretName < s[j].SecretName }
-
-// testDAB is the DAB JSON used for testing.
-// TODO: Use template/text and substitute "Image" with the result of
-// `docker inspect --format '{{index .RepoDigests 0}}' busybox:latest`
-const testDAB = `{
-    "Version": "0.1",
-    "Services": {
-	"srv1": {
-	    "Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
-	    "Command": ["top"]
-	},
-	"srv2": {
-	    "Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
-	    "Command": ["tail"],
-	    "Args": ["-f", "/dev/null"]
-	}
-    }
-}`
-
-func (s *DockerSwarmSuite) TestStackDeployWithDAB(c *check.C) {
-	testRequires(c, ExperimentalDaemon)
-	// setup
-	testStackName := "test"
-	testDABFileName := testStackName + ".dab"
-	defer os.RemoveAll(testDABFileName)
-	err := ioutil.WriteFile(testDABFileName, []byte(testDAB), 0444)
-	c.Assert(err, checker.IsNil)
-	d := s.AddDaemon(c, true, true)
-	// deploy
-	stackArgs := []string{
-		"stack", "deploy",
-		"--bundle-file", testDABFileName,
-		testStackName,
-	}
-	out, err := d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, checker.Contains, "Loading bundle from test.dab\n")
-	c.Assert(out, checker.Contains, "Creating service test_srv1\n")
-	c.Assert(out, checker.Contains, "Creating service test_srv2\n")
-	// ls
-	stackArgs = []string{"stack", "ls"}
-	out, err = d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil)
-	c.Assert(cleanSpaces(out), check.Equals, "NAME SERVICES\n"+"test 2\n")
-	// rm
-	stackArgs = []string{"stack", "rm", testStackName}
-	out, err = d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, checker.Contains, "Removing service test_srv1\n")
-	c.Assert(out, checker.Contains, "Removing service test_srv2\n")
-	// ls (empty)
-	stackArgs = []string{"stack", "ls"}
-	out, err = d.Cmd(stackArgs...)
-	c.Assert(err, checker.IsNil)
-	c.Assert(cleanSpaces(out), check.Equals, "NAME SERVICES\n")
-}
diff --git a/integration-cli/docker_cli_start_test.go b/integration-cli/docker_cli_start_test.go
index 2dd5fdf..13c1d8e 100644
--- a/integration-cli/docker_cli_start_test.go
+++ b/integration-cli/docker_cli_start_test.go
@@ -7,8 +7,8 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 // Regression test for https://github.com/docker/docker/issues/7843
@@ -103,7 +103,7 @@
 	// an error should have been shown that you cannot start paused container
 	c.Assert(err, checker.NotNil, check.Commentf("out: %s", out))
 	// an error should have been shown that you cannot start paused container
-	c.Assert(out, checker.Contains, "Cannot start a paused container, try unpause instead.")
+	c.Assert(out, checker.Contains, "cannot start a paused container, try unpause instead")
 }
 
 func (s *DockerSuite) TestStartMultipleContainers(c *check.C) {
diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go
index a0bb7a2..d1709ab 100644
--- a/integration-cli/docker_cli_swarm_test.go
+++ b/integration-cli/docker_cli_swarm_test.go
@@ -12,7 +12,6 @@
 	"net/http"
 	"net/http/httptest"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strings"
 	"time"
@@ -23,14 +22,14 @@
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/daemon"
-	"github.com/docker/docker/pkg/testutil"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
-	"github.com/docker/docker/pkg/testutil/tempfile"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/ipamapi"
 	remoteipam "github.com/docker/libnetwork/ipams/remote/api"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/fs"
+	"github.com/gotestyourself/gotestyourself/icmd"
 	"github.com/vishvananda/netlink"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) {
@@ -69,11 +68,11 @@
 	c.Assert(spec.CAConfig.ExternalCAs[1].CACert, checker.Equals, string(expected))
 
 	// passing an invalid external CA fails
-	tempFile := tempfile.NewTempFile(c, "testfile", "fakecert")
+	tempFile := fs.NewFile(c, "testfile", fs.WithContent("fakecert"))
 	defer tempFile.Remove()
 
 	result := cli.Docker(cli.Args("swarm", "update",
-		"--external-ca", fmt.Sprintf("protocol=cfssl,url=https://something.org,cacert=%s", tempFile.Name())),
+		"--external-ca", fmt.Sprintf("protocol=cfssl,url=https://something.org,cacert=%s", tempFile.Path())),
 		cli.Daemon(d.Daemon))
 	result.Assert(c, icmd.Expected{
 		ExitCode: 125,
@@ -90,11 +89,11 @@
 	}
 
 	// passing an invalid external CA fails
-	tempFile := tempfile.NewTempFile(c, "testfile", "fakecert")
+	tempFile := fs.NewFile(c, "testfile", fs.WithContent("fakecert"))
 	defer tempFile.Remove()
 
 	result := cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s",
-		"--external-ca", fmt.Sprintf("protocol=cfssl,url=https://somethingelse.org,cacert=%s", tempFile.Name())),
+		"--external-ca", fmt.Sprintf("protocol=cfssl,url=https://somethingelse.org,cacert=%s", tempFile.Path())),
 		cli.Daemon(d.Daemon))
 	result.Assert(c, icmd.Expected{
 		ExitCode: 125,
@@ -170,8 +169,10 @@
 
 func (s *DockerSwarmSuite) TestSwarmServiceTemplatingHostname(c *check.C) {
 	d := s.AddDaemon(c, true, true)
+	hostname, err := d.Cmd("node", "inspect", "--format", "{{.Description.Hostname}}", "self")
+	c.Assert(err, checker.IsNil, check.Commentf(hostname))
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--hostname", "{{.Service.Name}}-{{.Task.Slot}}", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "test", "--hostname", "{{.Service.Name}}-{{.Task.Slot}}-{{.Node.Hostname}}", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// make sure task has been deployed.
@@ -180,7 +181,7 @@
 	containers := d.ActiveContainers()
 	out, err = d.Cmd("inspect", "--type", "container", "--format", "{{.Config.Hostname}}", containers[0])
 	c.Assert(err, checker.IsNil, check.Commentf(out))
-	c.Assert(strings.Split(out, "\n")[0], checker.Equals, "test-1", check.Commentf("hostname with templating invalid"))
+	c.Assert(strings.Split(out, "\n")[0], checker.Equals, "test-1-"+strings.Split(hostname, "\n")[0], check.Commentf("hostname with templating invalid"))
 }
 
 // Test case for #24270
@@ -190,15 +191,15 @@
 	name1 := "redis-cluster-md5"
 	name2 := "redis-cluster"
 	name3 := "other-cluster"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name1, "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name1, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", name2, "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name2, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", name3, "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name3, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -248,7 +249,7 @@
 	d := s.AddDaemon(c, true, true)
 
 	name := "redis-cluster-md5"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--replicas=3", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--replicas=3", "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -275,17 +276,17 @@
 	d := s.AddDaemon(c, true, true)
 
 	name := "top"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--label", "x=y", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--label", "x=y", "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
-	out, err = d.Cmd("service", "update", "--publish-add", "80:80", name)
+	out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name)
 	c.Assert(err, checker.IsNil)
 
-	out, err = d.CmdRetryOutOfSequence("service", "update", "--publish-add", "80:80", name)
+	out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", name)
 	c.Assert(err, checker.IsNil)
 
-	out, err = d.CmdRetryOutOfSequence("service", "update", "--publish-add", "80:80", "--publish-add", "80:20", name)
+	out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name)
 	c.Assert(err, checker.NotNil)
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.EndpointSpec.Ports }}", name)
@@ -297,7 +298,7 @@
 	d := s.AddDaemon(c, true, true)
 
 	name := "top"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--user", "root:root", "--group", "wheel", "--group", "audio", "--group", "staff", "--group", "777", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--user", "root:root", "--group", "wheel", "--group", "audio", "--group", "staff", "--group", "777", "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -467,14 +468,17 @@
 	d := s.AddDaemon(c, true, true)
 
 	// Ingress network can be removed
-	out, _, err := testutil.RunCommandPipelineWithOutput(
-		exec.Command("echo", "Y"),
-		exec.Command("docker", "-H", d.Sock(), "network", "rm", "ingress"),
-	)
-	c.Assert(err, checker.IsNil, check.Commentf(out))
+	removeNetwork := func(name string) *icmd.Result {
+		return cli.Docker(
+			cli.Args("-H", d.Sock(), "network", "rm", name),
+			cli.WithStdin(strings.NewReader("Y")))
+	}
+
+	result := removeNetwork("ingress")
+	result.Assert(c, icmd.Success)
 
 	// And recreated
-	out, err = d.Cmd("network", "create", "-d", "overlay", "--ingress", "new-ingress")
+	out, err := d.Cmd("network", "create", "-d", "overlay", "--ingress", "new-ingress")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// But only one is allowed
@@ -483,36 +487,34 @@
 	c.Assert(strings.TrimSpace(out), checker.Contains, "is already present")
 
 	// It cannot be removed if it is being used
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "srv1", "-p", "9000:8000", "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv1", "-p", "9000:8000", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
-	out, _, err = testutil.RunCommandPipelineWithOutput(
-		exec.Command("echo", "Y"),
-		exec.Command("docker", "-H", d.Sock(), "network", "rm", "new-ingress"),
-	)
-	c.Assert(err, checker.NotNil)
-	c.Assert(strings.TrimSpace(out), checker.Contains, "ingress network cannot be removed because service")
+
+	result = removeNetwork("new-ingress")
+	result.Assert(c, icmd.Expected{
+		ExitCode: 1,
+		Err:      "ingress network cannot be removed because service",
+	})
 
 	// But it can be removed once no more services depend on it
-	out, err = d.Cmd("service", "update", "--publish-rm", "9000:8000", "srv1")
-	c.Assert(err, checker.IsNil, check.Commentf(out))
-	out, _, err = testutil.RunCommandPipelineWithOutput(
-		exec.Command("echo", "Y"),
-		exec.Command("docker", "-H", d.Sock(), "network", "rm", "new-ingress"),
-	)
+	out, err = d.Cmd("service", "update", "--detach", "--publish-rm", "9000:8000", "srv1")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
+	result = removeNetwork("new-ingress")
+	result.Assert(c, icmd.Success)
+
 	// A service which needs the ingress network cannot be created if no ingress is present
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "srv2", "-p", "500:500", "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv2", "-p", "500:500", "busybox", "top")
 	c.Assert(err, checker.NotNil)
 	c.Assert(strings.TrimSpace(out), checker.Contains, "no ingress network is present")
 
 	// An existing service cannot be updated to use the ingress nw if the nw is not present
-	out, err = d.Cmd("service", "update", "--publish-add", "9000:8000", "srv1")
+	out, err = d.Cmd("service", "update", "--detach", "--publish-add", "9000:8000", "srv1")
 	c.Assert(err, checker.NotNil)
 	c.Assert(strings.TrimSpace(out), checker.Contains, "no ingress network is present")
 
 	// But services which do not need routing mesh can be created regardless
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "srv3", "--endpoint-mode", "dnsrr", "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv3", "--endpoint-mode", "dnsrr", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 }
 
@@ -520,17 +522,16 @@
 	d := s.AddDaemon(c, true, true)
 
 	// Remove ingress network
-	out, _, err := testutil.RunCommandPipelineWithOutput(
-		exec.Command("echo", "Y"),
-		exec.Command("docker", "-H", d.Sock(), "network", "rm", "ingress"),
-	)
-	c.Assert(err, checker.IsNil, check.Commentf(out))
+	result := cli.Docker(
+		cli.Args("-H", d.Sock(), "network", "rm", "ingress"),
+		cli.WithStdin(strings.NewReader("Y")))
+	result.Assert(c, icmd.Success)
 
 	// Create a overlay network and launch a service on it
 	// Make sure nothing panics because ingress network is missing
-	out, err = d.Cmd("network", "create", "-d", "overlay", "another-network")
+	out, err := d.Cmd("network", "create", "-d", "overlay", "another-network")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "srv4", "--network", "another-network", "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv4", "--network", "another-network", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 }
 
@@ -540,7 +541,7 @@
 	d := s.AddDaemon(c, true, true)
 
 	name := "redis-cluster-md5"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--replicas=3", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--replicas=3", "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -574,7 +575,7 @@
 	c.Assert(out, checker.Not(checker.Contains), name+".3")
 
 	name = "redis-cluster-sha1"
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--mode=global", "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--mode=global", "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -603,7 +604,7 @@
 	bareID := strings.TrimSpace(out)[:12]
 	// Create a service
 	name := "busybox-top"
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -822,7 +823,7 @@
 	c.Assert(err, checker.IsNil)
 
 	name := "worker"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--env-file", path, "--env", "VAR1=B", "--env", "VAR1=C", "--env", "VAR2=", "--env", "VAR2", "--name", name, "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--env-file", path, "--env", "VAR1=B", "--env", "VAR1=C", "--env", "VAR2=", "--env", "VAR2", "--name", name, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
@@ -841,7 +842,7 @@
 
 	// Without --tty
 	expectedOutput := "none"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", ttyCheck)
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", ttyCheck)
 	c.Assert(err, checker.IsNil)
 
 	// Make sure task has been deployed.
@@ -864,7 +865,7 @@
 
 	// With --tty
 	expectedOutput = "TTY"
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--tty", "busybox", "sh", "-c", ttyCheck)
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--tty", "busybox", "sh", "-c", ttyCheck)
 	c.Assert(err, checker.IsNil)
 
 	// Make sure task has been deployed.
@@ -885,7 +886,7 @@
 
 	// Create a service
 	name := "top"
-	_, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "top")
+	_, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 
 	// Make sure task has been deployed.
@@ -895,7 +896,7 @@
 	c.Assert(err, checker.IsNil)
 	c.Assert(strings.TrimSpace(out), checker.Equals, "false")
 
-	_, err = d.Cmd("service", "update", "--tty", name)
+	_, err = d.Cmd("service", "update", "--detach", "--tty", name)
 	c.Assert(err, checker.IsNil)
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.TTY }}", name)
@@ -920,7 +921,7 @@
 
 	// Create a service
 	name := "top"
-	result = icmd.RunCmd(d.Command("service", "create", "--no-resolve-image", "--network", "foo", "--network", "bar", "--name", name, "busybox", "top"))
+	result = icmd.RunCmd(d.Command("service", "create", "--detach", "--no-resolve-image", "--network", "foo", "--network", "bar", "--name", name, "busybox", "top"))
 	result.Assert(c, icmd.Success)
 
 	// Make sure task has been deployed.
@@ -928,14 +929,14 @@
 		map[string]int{fooNetwork: 1, barNetwork: 1})
 
 	// Remove a network
-	result = icmd.RunCmd(d.Command("service", "update", "--network-rm", "foo", name))
+	result = icmd.RunCmd(d.Command("service", "update", "--detach", "--network-rm", "foo", name))
 	result.Assert(c, icmd.Success)
 
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskNetworks, checker.DeepEquals,
 		map[string]int{barNetwork: 1})
 
 	// Add a network
-	result = icmd.RunCmd(d.Command("service", "update", "--network-add", "baz", name))
+	result = icmd.RunCmd(d.Command("service", "update", "--detach", "--network-add", "baz", name))
 	result.Assert(c, icmd.Success)
 
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskNetworks, checker.DeepEquals,
@@ -947,7 +948,7 @@
 
 	// Create a service
 	name := "top"
-	_, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--dns=1.2.3.4", "--dns-search=example.com", "--dns-option=timeout:3", "busybox", "top")
+	_, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--dns=1.2.3.4", "--dns-search=example.com", "--dns-option=timeout:3", "busybox", "top")
 	c.Assert(err, checker.IsNil)
 
 	// Make sure task has been deployed.
@@ -974,13 +975,13 @@
 
 	// Create a service
 	name := "top"
-	_, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "busybox", "top")
+	_, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 
 	// Make sure task has been deployed.
 	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1)
 
-	_, err = d.Cmd("service", "update", "--dns-add=1.2.3.4", "--dns-search-add=example.com", "--dns-option-add=timeout:3", name)
+	_, err = d.Cmd("service", "update", "--detach", "--dns-add=1.2.3.4", "--dns-search-add=example.com", "--dns-option-add=timeout:3", name)
 	c.Assert(err, checker.IsNil)
 
 	out, err := d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.DNSConfig }}", name)
@@ -1496,7 +1497,7 @@
 
 	// Create a service
 	name := "top"
-	_, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--host=example.com:1.2.3.4", "busybox", "top")
+	_, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--host=example.com:1.2.3.4", "busybox", "top")
 	c.Assert(err, checker.IsNil)
 
 	// Make sure task has been deployed.
@@ -1535,22 +1536,6 @@
 	c.Assert(out, checker.Contains, expectedOutput)
 }
 
-func (s *DockerSwarmSuite) TestSwarmServiceInspectPretty(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	name := "top"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", name, "--limit-cpu=0.5", "busybox", "top")
-	c.Assert(err, checker.IsNil, check.Commentf(out))
-
-	expectedOutput := `
-Resources:
- Limits:
-  CPU:		0.5`
-	out, err = d.Cmd("service", "inspect", "--pretty", name)
-	c.Assert(err, checker.IsNil, check.Commentf(out))
-	c.Assert(out, checker.Contains, expectedOutput, check.Commentf(out))
-}
-
 func (s *DockerSwarmSuite) TestSwarmNetworkIPAMOptions(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
@@ -1562,7 +1547,7 @@
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	c.Assert(strings.TrimSpace(out), checker.Equals, "map[foo:bar]")
 
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--network=foo", "--name", "top", "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--network=foo", "--name", "top", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// make sure task has been deployed.
@@ -1580,7 +1565,7 @@
 	repoName := s.trustSuite.setupTrustedImage(c, "trusted-pull")
 
 	name := "trusted"
-	cli.Docker(cli.Args("-D", "service", "create", "--no-resolve-image", "--name", name, repoName, "top"), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
+	cli.Docker(cli.Args("-D", "service", "create", "--detach", "--no-resolve-image", "--name", name, repoName, "top"), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
 		Err: "resolved image tag to",
 	})
 
@@ -1597,7 +1582,7 @@
 	cli.DockerCmd(c, "rmi", repoName)
 
 	name = "untrusted"
-	cli.Docker(cli.Args("service", "create", "--no-resolve-image", "--name", name, repoName, "top"), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
+	cli.Docker(cli.Args("service", "create", "--detach", "--no-resolve-image", "--name", name, repoName, "top"), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
 		ExitCode: 1,
 		Err:      "Error: remote trust data does not exist",
 	})
@@ -1615,7 +1600,7 @@
 	name := "myservice"
 
 	// Create a service without content trust
-	cli.Docker(cli.Args("service", "create", "--no-resolve-image", "--name", name, repoName, "top"), cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
+	cli.Docker(cli.Args("service", "create", "--detach", "--no-resolve-image", "--name", name, repoName, "top"), cli.Daemon(d.Daemon)).Assert(c, icmd.Success)
 
 	result := cli.Docker(cli.Args("service", "inspect", "--pretty", name), cli.Daemon(d.Daemon))
 	c.Assert(result.Error, checker.IsNil, check.Commentf(result.Combined()))
@@ -1623,7 +1608,7 @@
 	// DOCKER_SERVICE_PREFER_OFFLINE_IMAGE.
 	c.Assert(result.Combined(), check.Not(checker.Contains), repoName+"@", check.Commentf(result.Combined()))
 
-	cli.Docker(cli.Args("-D", "service", "update", "--no-resolve-image", "--image", repoName, name), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
+	cli.Docker(cli.Args("-D", "service", "update", "--detach", "--no-resolve-image", "--image", repoName, name), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
 		Err: "resolved image tag to",
 	})
 
@@ -1639,7 +1624,7 @@
 	cli.DockerCmd(c, "push", repoName)
 	cli.DockerCmd(c, "rmi", repoName)
 
-	cli.Docker(cli.Args("service", "update", "--no-resolve-image", "--image", repoName, name), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
+	cli.Docker(cli.Args("service", "update", "--detach", "--no-resolve-image", "--image", repoName, name), trustedCmd, cli.Daemon(d.Daemon)).Assert(c, icmd.Expected{
 		ExitCode: 1,
 		Err:      "Error: remote trust data does not exist",
 	})
@@ -1692,76 +1677,6 @@
 	}
 }
 
-func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) {
-	d := s.AddDaemon(c, true, true)
-
-	name1 := "top1"
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name1, "--replicas=3", "busybox", "top")
-	c.Assert(err, checker.IsNil)
-	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
-	id1 := strings.TrimSpace(out)
-
-	name2 := "top2"
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--name", name2, "--replicas=3", "busybox", "top")
-	c.Assert(err, checker.IsNil)
-	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
-	id2 := strings.TrimSpace(out)
-
-	// make sure task has been deployed.
-	waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 6)
-
-	out, err = d.Cmd("service", "ps", name1)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, checker.Contains, name1+".1")
-	c.Assert(out, checker.Contains, name1+".2")
-	c.Assert(out, checker.Contains, name1+".3")
-	c.Assert(out, checker.Not(checker.Contains), name2+".1")
-	c.Assert(out, checker.Not(checker.Contains), name2+".2")
-	c.Assert(out, checker.Not(checker.Contains), name2+".3")
-
-	out, err = d.Cmd("service", "ps", name1, name2)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, checker.Contains, name1+".1")
-	c.Assert(out, checker.Contains, name1+".2")
-	c.Assert(out, checker.Contains, name1+".3")
-	c.Assert(out, checker.Contains, name2+".1")
-	c.Assert(out, checker.Contains, name2+".2")
-	c.Assert(out, checker.Contains, name2+".3")
-
-	// Name Prefix
-	out, err = d.Cmd("service", "ps", "to")
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, checker.Contains, name1+".1")
-	c.Assert(out, checker.Contains, name1+".2")
-	c.Assert(out, checker.Contains, name1+".3")
-	c.Assert(out, checker.Contains, name2+".1")
-	c.Assert(out, checker.Contains, name2+".2")
-	c.Assert(out, checker.Contains, name2+".3")
-
-	// Name Prefix (no hit)
-	out, err = d.Cmd("service", "ps", "noname")
-	c.Assert(err, checker.NotNil)
-	c.Assert(out, checker.Contains, "no such services: noname")
-
-	out, err = d.Cmd("service", "ps", id1)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, checker.Contains, name1+".1")
-	c.Assert(out, checker.Contains, name1+".2")
-	c.Assert(out, checker.Contains, name1+".3")
-	c.Assert(out, checker.Not(checker.Contains), name2+".1")
-	c.Assert(out, checker.Not(checker.Contains), name2+".2")
-	c.Assert(out, checker.Not(checker.Contains), name2+".3")
-
-	out, err = d.Cmd("service", "ps", id1, id2)
-	c.Assert(err, checker.IsNil)
-	c.Assert(out, checker.Contains, name1+".1")
-	c.Assert(out, checker.Contains, name1+".2")
-	c.Assert(out, checker.Contains, name1+".3")
-	c.Assert(out, checker.Contains, name2+".1")
-	c.Assert(out, checker.Contains, name2+".2")
-	c.Assert(out, checker.Contains, name2+".3")
-}
-
 func (s *DockerSwarmSuite) TestSwarmPublishDuplicatePorts(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
@@ -1825,7 +1740,7 @@
 
 	d := s.AddDaemon(c, true, true)
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "top", "--read-only", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top", "--read-only", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// make sure task has been deployed.
@@ -1845,19 +1760,17 @@
 	d := s.AddDaemon(c, true, true)
 
 	name := "foo"
-	networkCreateRequest := types.NetworkCreateRequest{
-		Name: name,
-		NetworkCreate: types.NetworkCreate{
-			CheckDuplicate: false,
-			Driver:         "bridge",
-		},
+	options := types.NetworkCreate{
+		CheckDuplicate: false,
+		Driver:         "bridge",
 	}
 
-	var n1 types.NetworkCreateResponse
-	status, body, err := d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
-	c.Assert(json.Unmarshal(body, &n1), checker.IsNil)
+	cli, err := d.NewClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
+
+	n1, err := cli.NetworkCreate(context.Background(), name, options)
+	c.Assert(err, checker.IsNil)
 
 	// Full ID always works
 	out, err := d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID)
@@ -1869,12 +1782,8 @@
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	c.Assert(strings.TrimSpace(out), checker.Equals, n1.ID)
 
-	var n2 types.NetworkCreateResponse
-	status, body, err = d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
-	c.Assert(json.Unmarshal(body, &n2), checker.IsNil)
-
+	n2, err := cli.NetworkCreate(context.Background(), name, options)
+	c.Assert(err, checker.IsNil)
 	// Full ID always works
 	out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
@@ -1887,18 +1796,16 @@
 	// Name with duplicates
 	out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", name)
 	c.Assert(err, checker.NotNil, check.Commentf(out))
-	c.Assert(out, checker.Contains, "network foo is ambiguous (2 matches found based on name)")
+	c.Assert(out, checker.Contains, "2 matches found based on name")
 
 	out, err = d.Cmd("network", "rm", n2.ID)
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
-	// Duplicates with name but with different driver
-	networkCreateRequest.NetworkCreate.Driver = "overlay"
+	// Dupliates with name but with different driver
+	options.Driver = "overlay"
 
-	status, body, err = d.SockRequest("POST", "/networks/create", networkCreateRequest)
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
-	c.Assert(json.Unmarshal(body, &n2), checker.IsNil)
+	n2, err = cli.NetworkCreate(context.Background(), name, options)
+	c.Assert(err, checker.IsNil)
 
 	// Full ID always works
 	out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID)
@@ -1912,7 +1819,7 @@
 	// Name with duplicates
 	out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", name)
 	c.Assert(err, checker.NotNil, check.Commentf(out))
-	c.Assert(out, checker.Contains, "network foo is ambiguous (2 matches found based on name)")
+	c.Assert(out, checker.Contains, "2 matches found based on name")
 }
 
 func (s *DockerSwarmSuite) TestSwarmStopSignal(c *check.C) {
@@ -1920,7 +1827,7 @@
 
 	d := s.AddDaemon(c, true, true)
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "top", "--stop-signal=SIGHUP", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top", "--stop-signal=SIGHUP", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// make sure task has been deployed.
@@ -1935,7 +1842,7 @@
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	c.Assert(strings.TrimSpace(out), checker.Equals, "SIGHUP")
 
-	out, err = d.Cmd("service", "update", "--stop-signal=SIGUSR1", "top")
+	out, err = d.Cmd("service", "update", "--detach", "--stop-signal=SIGUSR1", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.StopSignal }}", "top")
@@ -1946,11 +1853,11 @@
 func (s *DockerSwarmSuite) TestSwarmServiceLsFilterMode(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "top1", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top1", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
-	out, err = d.Cmd("service", "create", "--no-resolve-image", "--name", "top2", "--mode=global", "busybox", "top")
+	out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top2", "--mode=global", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 	c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "")
 
diff --git a/integration-cli/docker_cli_swarm_unix_test.go b/integration-cli/docker_cli_swarm_unix_test.go
index cffabcc..16b27ef 100644
--- a/integration-cli/docker_cli_swarm_unix_test.go
+++ b/integration-cli/docker_cli_swarm_unix_test.go
@@ -15,7 +15,7 @@
 func (s *DockerSwarmSuite) TestSwarmVolumePlugin(c *check.C) {
 	d := s.AddDaemon(c, true, true)
 
-	out, err := d.Cmd("service", "create", "--no-resolve-image", "--mount", "type=volume,source=my-volume,destination=/foo,volume-driver=customvolumedriver", "--name", "top", "busybox", "top")
+	out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--mount", "type=volume,source=my-volume,destination=/foo,volume-driver=customvolumedriver", "--name", "top", "busybox", "top")
 	c.Assert(err, checker.IsNil, check.Commentf(out))
 
 	// Make sure task stays pending before plugin is available
@@ -74,7 +74,7 @@
 
 	// create a global service to ensure that both nodes will have an instance
 	serviceName := "my-service"
-	_, err = d1.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "--mode=global", "--network", networkName, "busybox", "top")
+	_, err = d1.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--mode=global", "--network", networkName, "busybox", "top")
 	c.Assert(err, checker.IsNil)
 
 	// wait for tasks ready
@@ -94,9 +94,9 @@
 
 	time.Sleep(20 * time.Second)
 
-	image := "busybox"
+	image := "busybox:latest"
 	// create a new global service again.
-	_, err = d1.Cmd("service", "create", "--no-resolve-image", "--name", serviceName, "--mode=global", "--network", networkName, image, "top")
+	_, err = d1.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", serviceName, "--mode=global", "--network", networkName, image, "top")
 	c.Assert(err, checker.IsNil)
 
 	waitAndAssert(c, defaultReconciliationTimeout, d1.CheckRunningTaskImages, checker.DeepEquals,
diff --git a/integration-cli/docker_cli_top_test.go b/integration-cli/docker_cli_top_test.go
index ea32fc6..f52f240 100644
--- a/integration-cli/docker_cli_top_test.go
+++ b/integration-cli/docker_cli_top_test.go
@@ -4,8 +4,8 @@
 	"strings"
 
 	"github.com/docker/docker/integration-cli/checker"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestTopMultipleArgs(c *check.C) {
@@ -20,7 +20,7 @@
 		expected = icmd.Expected{Out: "PID"}
 	}
 	result := dockerCmdWithResult("top", cleanedContainerID, "-o", "pid")
-	c.Assert(result, icmd.Matches, expected)
+	result.Assert(c, expected)
 }
 
 func (s *DockerSuite) TestTopNonPrivileged(c *check.C) {
diff --git a/integration-cli/docker_cli_update_test.go b/integration-cli/docker_cli_update_test.go
index c898690..5b9b730 100644
--- a/integration-cli/docker_cli_update_test.go
+++ b/integration-cli/docker_cli_update_test.go
@@ -6,8 +6,8 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 func (s *DockerSuite) TestUpdateRestartPolicy(c *check.C) {
diff --git a/integration-cli/docker_cli_update_unix_test.go b/integration-cli/docker_cli_update_unix_test.go
index be2274b..c3dfbcc 100644
--- a/integration-cli/docker_cli_update_unix_test.go
+++ b/integration-cli/docker_cli_update_unix_test.go
@@ -3,6 +3,7 @@
 package main
 
 import (
+	"context"
 	"encoding/json"
 	"fmt"
 	"os/exec"
@@ -10,6 +11,7 @@
 	"time"
 
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
 	"github.com/docker/docker/pkg/parsers/kernel"
@@ -137,7 +139,7 @@
 func (s *DockerSuite) TestUpdateKernelMemoryUninitialized(c *check.C) {
 	testRequires(c, DaemonIsLinux, kernelMemorySupport)
 
-	isNewKernel := kernel.CheckKernelVersion(4, 6, 0)
+	isNewKernel := CheckKernelVersion(4, 6, 0)
 	name := "test-update-container"
 	dockerCmd(c, "run", "-d", "--name", name, "busybox", "top")
 	_, _, err := dockerCmdWithError("update", "--kernel-memory", "100M", name)
@@ -169,6 +171,18 @@
 	c.Assert(strings.TrimSpace(out), checker.Equals, "314572800")
 }
 
+// GetKernelVersion gets the current kernel version.
+func GetKernelVersion() *kernel.VersionInfo {
+	v, _ := kernel.ParseRelease(testEnv.DaemonInfo.KernelVersion)
+	return v
+}
+
+// CheckKernelVersion checks if current kernel is newer than (or equal to)
+// the given version.
+func CheckKernelVersion(k, major, minor int) bool {
+	return kernel.CompareKernelVersion(*GetKernelVersion(), kernel.VersionInfo{Kernel: k, Major: major, Minor: minor}) > 0
+}
+
 func (s *DockerSuite) TestUpdateSwapMemoryOnly(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	testRequires(c, memoryLimitSupport)
@@ -295,20 +309,26 @@
 	out, _ = dockerCmd(c, "exec", "top", "sh", "-c", fmt.Sprintf("cat %s && cat %s", file1, file2))
 	c.Assert(strings.TrimSpace(out), checker.Equals, "50000\n100000")
 
-	out = inspectField(c, "top", "HostConfig.NanoCpus")
-	c.Assert(out, checker.Equals, "5e+08", check.Commentf("setting the Nano CPUs failed"))
+	clt, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	inspect, err := clt.ContainerInspect(context.Background(), "top")
+	c.Assert(err, checker.IsNil)
+	c.Assert(inspect.HostConfig.NanoCPUs, checker.Equals, int64(500000000))
+
 	out = inspectField(c, "top", "HostConfig.CpuQuota")
 	c.Assert(out, checker.Equals, "0", check.Commentf("CPU CFS quota should be 0"))
 	out = inspectField(c, "top", "HostConfig.CpuPeriod")
 	c.Assert(out, checker.Equals, "0", check.Commentf("CPU CFS period should be 0"))
 
-	out, _, err := dockerCmdWithError("update", "--cpu-quota", "80000", "top")
+	out, _, err = dockerCmdWithError("update", "--cpu-quota", "80000", "top")
 	c.Assert(err, checker.NotNil)
 	c.Assert(out, checker.Contains, "Conflicting options: CPU Quota cannot be updated as NanoCPUs has already been set")
 
 	out, _ = dockerCmd(c, "update", "--cpus", "0.8", "top")
-	out = inspectField(c, "top", "HostConfig.NanoCpus")
-	c.Assert(out, checker.Equals, "8e+08", check.Commentf("updating the Nano CPUs failed"))
+	inspect, err = clt.ContainerInspect(context.Background(), "top")
+	c.Assert(err, checker.IsNil)
+	c.Assert(inspect.HostConfig.NanoCPUs, checker.Equals, int64(800000000))
+
 	out = inspectField(c, "top", "HostConfig.CpuQuota")
 	c.Assert(out, checker.Equals, "0", check.Commentf("CPU CFS quota should be 0"))
 	out = inspectField(c, "top", "HostConfig.CpuPeriod")
diff --git a/integration-cli/docker_cli_userns_test.go b/integration-cli/docker_cli_userns_test.go
index 8311401..54cfdd1 100644
--- a/integration-cli/docker_cli_userns_test.go
+++ b/integration-cli/docker_cli_userns_test.go
@@ -15,7 +15,6 @@
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/system"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/go-check/check"
 )
 
@@ -62,15 +61,15 @@
 	c.Assert(err, checker.IsNil, check.Commentf("Could not inspect running container: out: %q", pid))
 	// check the uid and gid maps for the PID to ensure root is remapped
 	// (cmd = cat /proc/<pid>/uid_map | grep -E '0\s+9999\s+1')
-	out, rc1, err := testutil.RunCommandPipelineWithOutput(
+	out, err = RunCommandPipelineWithOutput(
 		exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/uid_map"),
 		exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", uid)))
-	c.Assert(rc1, checker.Equals, 0, check.Commentf("Didn't match uid_map: output: %s", out))
+	c.Assert(err, check.IsNil)
 
-	out, rc2, err := testutil.RunCommandPipelineWithOutput(
+	out, err = RunCommandPipelineWithOutput(
 		exec.Command("cat", "/proc/"+strings.TrimSpace(pid)+"/gid_map"),
 		exec.Command("grep", "-E", fmt.Sprintf("0[[:space:]]+%d[[:space:]]+", gid)))
-	c.Assert(rc2, checker.Equals, 0, check.Commentf("Didn't match gid_map: output: %s", out))
+	c.Assert(err, check.IsNil)
 
 	// check that the touched file is owned by remapped uid:gid
 	stat, err := system.Stat(filepath.Join(tmpDir, "testfile"))
diff --git a/integration-cli/docker_cli_version_test.go b/integration-cli/docker_cli_version_test.go
deleted file mode 100644
index 074a7db..0000000
--- a/integration-cli/docker_cli_version_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package main
-
-import (
-	"strings"
-
-	"github.com/docker/docker/integration-cli/checker"
-	"github.com/go-check/check"
-)
-
-// ensure docker version works
-func (s *DockerSuite) TestVersionEnsureSucceeds(c *check.C) {
-	out, _ := dockerCmd(c, "version")
-	stringsToCheck := map[string]int{
-		"Client:":       1,
-		"Server:":       1,
-		" Version:":     2,
-		" API version:": 2,
-		" Go version:":  2,
-		" Git commit:":  2,
-		" OS/Arch:":     2,
-		" Built:":       2,
-	}
-
-	for k, v := range stringsToCheck {
-		c.Assert(strings.Count(out, k), checker.Equals, v, check.Commentf("The count of %v in %s does not match excepted", k, out))
-	}
-}
-
-// ensure the Windows daemon return the correct platform string
-func (s *DockerSuite) TestVersionPlatform_w(c *check.C) {
-	testRequires(c, DaemonIsWindows)
-	testVersionPlatform(c, "windows/amd64")
-}
-
-// ensure the Linux daemon return the correct platform string
-func (s *DockerSuite) TestVersionPlatform_l(c *check.C) {
-	testRequires(c, DaemonIsLinux)
-	testVersionPlatform(c, "linux")
-}
-
-func testVersionPlatform(c *check.C, platform string) {
-	out, _ := dockerCmd(c, "version")
-	expected := "OS/Arch:      " + platform
-
-	split := strings.Split(out, "\n")
-	c.Assert(len(split) >= 14, checker.Equals, true, check.Commentf("got %d lines from version", len(split)))
-
-	// Verify the second 'OS/Arch' matches the platform. Experimental has
-	// more lines of output than 'regular'
-	bFound := false
-	for i := 14; i < len(split); i++ {
-		if strings.Contains(split[i], expected) {
-			bFound = true
-			break
-		}
-	}
-	c.Assert(bFound, checker.Equals, true, check.Commentf("Could not find server '%s' in '%s'", expected, out))
-}
diff --git a/integration-cli/docker_cli_volume_test.go b/integration-cli/docker_cli_volume_test.go
index e0bf7ca..fc930d3 100644
--- a/integration-cli/docker_cli_volume_test.go
+++ b/integration-cli/docker_cli_volume_test.go
@@ -3,17 +3,20 @@
 import (
 	"fmt"
 	"io/ioutil"
-	"net/http"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"strings"
 
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/mount"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli/build"
-	"github.com/docker/docker/integration-cli/request"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	"golang.org/x/net/context"
 )
 
 func (s *DockerSuite) TestVolumeCLICreate(c *check.C) {
@@ -55,15 +58,12 @@
 	dockerCmd(c, "volume", "create", "test3")
 
 	result := dockerCmdWithResult("volume", "inspect", "--format={{ .Name }}", "test1", "test2", "doesnotexist", "test3")
-	c.Assert(result, icmd.Matches, icmd.Expected{
+	result.Assert(c, icmd.Expected{
 		ExitCode: 1,
 		Err:      "No such volume: doesnotexist",
 	})
 
 	out := result.Stdout()
-	outArr := strings.Split(strings.TrimSpace(out), "\n")
-	c.Assert(len(outArr), check.Equals, 3, check.Commentf("\n%s", out))
-
 	c.Assert(out, checker.Contains, "test1")
 	c.Assert(out, checker.Contains, "test2")
 	c.Assert(out, checker.Contains, "test3")
@@ -78,11 +78,8 @@
 	dockerCmd(c, "volume", "create", "soo")
 	dockerCmd(c, "run", "-v", "soo:"+prefix+"/foo", "busybox", "ls", "/")
 
-	out, _ := dockerCmd(c, "volume", "ls")
-	outArr := strings.Split(strings.TrimSpace(out), "\n")
-	c.Assert(len(outArr), check.Equals, 4, check.Commentf("\n%s", out))
-
-	assertVolList(c, out, []string{"aaa", "soo", "test"})
+	out, _ := dockerCmd(c, "volume", "ls", "-q")
+	assertVolumesInList(c, out, []string{"aaa", "soo", "test"})
 }
 
 func (s *DockerSuite) TestVolumeLsFormat(c *check.C) {
@@ -91,12 +88,7 @@
 	dockerCmd(c, "volume", "create", "soo")
 
 	out, _ := dockerCmd(c, "volume", "ls", "--format", "{{.Name}}")
-	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
-
-	expected := []string{"aaa", "soo", "test"}
-	var names []string
-	names = append(names, lines...)
-	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
+	assertVolumesInList(c, out, []string{"aaa", "soo", "test"})
 }
 
 func (s *DockerSuite) TestVolumeLsFormatDefaultFormat(c *check.C) {
@@ -115,12 +107,7 @@
 	c.Assert(err, checker.IsNil)
 
 	out, _ := dockerCmd(c, "--config", d, "volume", "ls")
-	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
-
-	expected := []string{"aaa default", "soo default", "test default"}
-	var names []string
-	names = append(names, lines...)
-	c.Assert(expected, checker.DeepEquals, names, check.Commentf("Expected array with truncated names: %v, got: %v", expected, names))
+	assertVolumesInList(c, out, []string{"aaa default", "soo default", "test default"})
 }
 
 // assertVolList checks volume retrieved with ls command
@@ -139,6 +126,20 @@
 	c.Assert(volList, checker.DeepEquals, expectVols)
 }
 
+func assertVolumesInList(c *check.C, out string, expected []string) {
+	lines := strings.Split(strings.TrimSpace(string(out)), "\n")
+	for _, expect := range expected {
+		found := false
+		for _, v := range lines {
+			found = v == expect
+			if found {
+				break
+			}
+		}
+		c.Assert(found, checker.Equals, true, check.Commentf("Expected volume not found: %v, got: %v", expect, lines))
+	}
+}
+
 func (s *DockerSuite) TestVolumeCLILsFilterDangling(c *check.C) {
 	prefix, _ := getPrefixAndSlashFromDaemonPlatform()
 	dockerCmd(c, "volume", "create", "testnotinuse1")
@@ -210,10 +211,6 @@
 	dockerCmd(c, "volume", "rm", id)
 	dockerCmd(c, "volume", "rm", "test")
 
-	out, _ = dockerCmd(c, "volume", "ls")
-	outArr := strings.Split(strings.TrimSpace(out), "\n")
-	c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
-
 	volumeID := "testing"
 	dockerCmd(c, "run", "-v", volumeID+":"+prefix+"/foo", "--name=test", "busybox", "sh", "-c", "echo hello > /foo/bar")
 
@@ -404,10 +401,6 @@
 
 	dockerCmd(c, "volume", "rm", "-f", id)
 	dockerCmd(c, "volume", "rm", "--force", "nonexist")
-
-	out, _ = dockerCmd(c, "volume", "ls")
-	outArr := strings.Split(strings.TrimSpace(out), "\n")
-	c.Assert(len(outArr), check.Equals, 1, check.Commentf("%s\n", out))
 }
 
 func (s *DockerSuite) TestVolumeCLIRmForce(c *check.C) {
@@ -607,25 +600,28 @@
 	err := os.MkdirAll("/tmp/data", 0755)
 	c.Assert(err, checker.IsNil)
 	// Mounts is available in API
-	status, body, err := request.SockRequest("POST", "/containers/create?name=app", map[string]interface{}{
-		"Image": "busybox",
-		"Cmd":   []string{"top"},
-		"HostConfig": map[string]interface{}{
-			"VolumesFrom": []string{
-				"data1",
-				"data2",
-			},
-			"Mounts": []map[string]interface{}{
-				{
-					"Type":   "bind",
-					"Source": "/tmp/data",
-					"Target": "/tmp/data",
-				},
-			}},
-	}, daemonHost())
+	cli, err := client.NewEnvClient()
+	c.Assert(err, checker.IsNil)
+	defer cli.Close()
 
-	c.Assert(err, checker.IsNil, check.Commentf(string(body)))
-	c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(body)))
+	config := container.Config{
+		Cmd:   []string{"top"},
+		Image: "busybox",
+	}
+
+	hostConfig := container.HostConfig{
+		VolumesFrom: []string{"data1", "data2"},
+		Mounts: []mount.Mount{
+			{
+				Type:   "bind",
+				Source: "/tmp/data",
+				Target: "/tmp/data",
+			},
+		},
+	}
+	_, err = cli.ContainerCreate(context.Background(), &config, &hostConfig, &network.NetworkingConfig{}, "app")
+
+	c.Assert(err, checker.IsNil)
 
 	// No volume will be referenced (mount is /tmp/data), this is backward compatible
 	out, _ = dockerCmd(c, "inspect", "--format", "{{(index .Mounts 0).Name}}", "app")
diff --git a/integration-cli/docker_cli_wait_test.go b/integration-cli/docker_cli_wait_test.go
index 6f45bf0..e804704 100644
--- a/integration-cli/docker_cli_wait_test.go
+++ b/integration-cli/docker_cli_wait_test.go
@@ -7,8 +7,8 @@
 	"time"
 
 	"github.com/docker/docker/integration-cli/checker"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 // non-blocking wait with 0 exit code
diff --git a/integration-cli/docker_deprecated_api_v124_test.go b/integration-cli/docker_deprecated_api_v124_test.go
index a3a8fbd..edf3e57 100644
--- a/integration-cli/docker_deprecated_api_v124_test.go
+++ b/integration-cli/docker_deprecated_api_v124_test.go
@@ -9,7 +9,6 @@
 
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/request"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/go-check/check"
 )
 
@@ -23,10 +22,14 @@
 	config := map[string]interface{}{
 		"Binds": []string{"/aa:/bb"},
 	}
-	status, body, err := request.SockRequest("POST", "/containers/"+name+"/start", config, daemonHost())
+	res, body, err := request.Post("/containers/"+name+"/start", request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusBadRequest)
-	c.Assert(string(body), checker.Contains, "was deprecated since v1.10")
+
+	buf, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
+	c.Assert(string(buf), checker.Contains, "was deprecated since API v1.22")
 }
 
 func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumeBinds(c *check.C) {
@@ -42,17 +45,17 @@
 		"Volumes": map[string]struct{}{path: {}},
 	}
 
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/create?name="+name), config, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
-	bindPath := testutil.RandomTmpDirPath("test", testEnv.DaemonPlatform())
+	bindPath := RandomTmpDirPath("test", testEnv.DaemonPlatform())
 	config = map[string]interface{}{
 		"Binds": []string{bindPath + ":" + path},
 	}
-	status, _, err = request.SockRequest("POST", formatV123StartAPIURL("/containers/"+name+"/start"), config, daemonHost())
+	res, _, err = request.Post(formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent)
 
 	pth, err := inspectMountSourceField(name, path)
 	c.Assert(err, checker.IsNil)
@@ -69,20 +72,24 @@
 		"Volumes": map[string]struct{}{"/tmp": {}},
 	}
 
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/create?name="+name), config, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
-	bindPath1 := testutil.RandomTmpDirPath("test1", testEnv.DaemonPlatform())
-	bindPath2 := testutil.RandomTmpDirPath("test2", testEnv.DaemonPlatform())
+	bindPath1 := RandomTmpDirPath("test1", testEnv.DaemonPlatform())
+	bindPath2 := RandomTmpDirPath("test2", testEnv.DaemonPlatform())
 
 	config = map[string]interface{}{
 		"Binds": []string{bindPath1 + ":/tmp", bindPath2 + ":/tmp"},
 	}
-	status, body, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/"+name+"/start"), config, daemonHost())
+	res, body, err := request.Post(formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusInternalServerError)
-	c.Assert(string(body), checker.Contains, "Duplicate mount point", check.Commentf("Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(body), err))
+
+	buf, err := request.ReadBody(body)
+	c.Assert(err, checker.IsNil)
+
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
+	c.Assert(string(buf), checker.Contains, "Duplicate mount point", check.Commentf("Expected failure due to duplicate bind mounts to same path, instead got: %q with error: %v", string(buf), err))
 }
 
 func (s *DockerSuite) TestDeprecatedContainerAPIStartVolumesFrom(c *check.C) {
@@ -99,16 +106,16 @@
 		"Volumes": map[string]struct{}{volPath: {}},
 	}
 
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/create?name="+name), config, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/create?name="+name), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusCreated)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusCreated)
 
 	config = map[string]interface{}{
 		"VolumesFrom": []string{volName},
 	}
-	status, _, err = request.SockRequest("POST", formatV123StartAPIURL("/containers/"+name+"/start"), config, daemonHost())
+	res, _, err = request.Post(formatV123StartAPIURL("/containers/"+name+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent)
 
 	pth, err := inspectMountSourceField(name, volPath)
 	c.Assert(err, checker.IsNil)
@@ -129,9 +136,9 @@
 	dockerCmd(c, "create", "-v", "/foo", "--name=two", "busybox")
 
 	bindSpec := map[string][]string{"Binds": {fooDir + ":/foo"}}
-	status, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/two/start"), bindSpec, daemonHost())
+	res, _, err := request.Post(formatV123StartAPIURL("/containers/two/start"), request.JSONBody(bindSpec))
 	c.Assert(err, checker.IsNil)
-	c.Assert(status, checker.Equals, http.StatusNoContent)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusNoContent)
 
 	fooDir2, err := inspectMountSourceField("two", "/foo")
 	c.Assert(err, checker.IsNil)
@@ -152,9 +159,9 @@
 
 	res, body, err := request.Post(formatV123StartAPIURL("/containers/"+containerID+"/start"), request.RawString(config), request.JSON)
 	c.Assert(err, checker.IsNil)
-	b, err2 := testutil.ReadBody(body)
+	b, err2 := request.ReadBody(body)
 	c.Assert(err2, checker.IsNil)
-	c.Assert(res.StatusCode, checker.Equals, http.StatusInternalServerError)
+	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
 	c.Assert(string(b), checker.Contains, "Minimum memory limit allowed is 4MB")
 }
 
diff --git a/integration-cli/docker_deprecated_api_v124_unix_test.go b/integration-cli/docker_deprecated_api_v124_unix_test.go
index 5fc6c2d..20a8885 100644
--- a/integration-cli/docker_deprecated_api_v124_unix_test.go
+++ b/integration-cli/docker_deprecated_api_v124_unix_test.go
@@ -22,7 +22,7 @@
 			"NetworkMode": netName,
 		},
 	}
-	_, _, err := request.SockRequest("POST", formatV123StartAPIURL("/containers/"+conName+"/start"), config, daemonHost())
+	_, _, err := request.Post(formatV123StartAPIURL("/containers/"+conName+"/start"), request.JSONBody(config))
 	c.Assert(err, checker.IsNil)
 	c.Assert(waitRun(conName), checker.IsNil)
 	networks := inspectField(c, conName, "NetworkSettings.Networks")
diff --git a/integration-cli/docker_experimental_network_test.go b/integration-cli/docker_experimental_network_test.go
index f352050..888970a 100644
--- a/integration-cli/docker_experimental_network_test.go
+++ b/integration-cli/docker_experimental_network_test.go
@@ -9,8 +9,8 @@
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/pkg/parsers/kernel"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 // ensure Kernel version is >= v3.9 for macvlan support
@@ -382,7 +382,7 @@
 
 	// access outside of the network should fail
 	result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second))
-	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
+	result.Assert(c, icmd.Expected{Timeout: true})
 
 	// intra-network communications should succeed
 	cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first")
@@ -421,7 +421,7 @@
 
 	// access outside of the network should fail
 	result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second))
-	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
+	result.Assert(c, icmd.Expected{Timeout: true})
 	// intra-network communications should succeed
 	cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first")
 }
@@ -461,7 +461,7 @@
 
 	// access outside of the network should fail
 	result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second))
-	c.Assert(result, icmd.Matches, icmd.Expected{Timeout: true})
+	result.Assert(c, icmd.Expected{Timeout: true})
 	// intra-network communications should succeed
 	cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first")
 }
diff --git a/integration-cli/docker_hub_pull_suite_test.go b/integration-cli/docker_hub_pull_suite_test.go
index 2633720..286a391 100644
--- a/integration-cli/docker_hub_pull_suite_test.go
+++ b/integration-cli/docker_hub_pull_suite_test.go
@@ -39,7 +39,7 @@
 
 // SetUpSuite starts the suite daemon.
 func (s *DockerHubPullSuite) SetUpSuite(c *check.C) {
-	testRequires(c, DaemonIsLinux)
+	testRequires(c, DaemonIsLinux, SameHostDaemon)
 	s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
 		Experimental: testEnv.ExperimentalDaemon(),
 	})
diff --git a/integration-cli/docker_utils_test.go b/integration-cli/docker_utils_test.go
index 0c0a164..1bda2c7 100644
--- a/integration-cli/docker_utils_test.go
+++ b/integration-cli/docker_utils_test.go
@@ -6,7 +6,6 @@
 	"fmt"
 	"io"
 	"io/ioutil"
-	"net/http"
 	"os"
 	"path"
 	"path/filepath"
@@ -15,13 +14,15 @@
 	"time"
 
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/daemon"
 	"github.com/docker/docker/integration-cli/registry"
 	"github.com/docker/docker/integration-cli/request"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	"golang.org/x/net/context"
 )
 
 // Deprecated
@@ -232,7 +233,7 @@
 }
 
 func containerStorageFile(containerID, basename string) string {
-	return filepath.Join(testEnv.ContainerStoragePath(), containerID, basename)
+	return filepath.Join(testEnv.PlatformDefaults.ContainerStoragePath, containerID, basename)
 }
 
 // docker commands that use this function must be run with the '-d' switch.
@@ -264,20 +265,15 @@
 
 // daemonTime provides the current time on the daemon host
 func daemonTime(c *check.C) time.Time {
-	if testEnv.LocalDaemon() {
+	if testEnv.IsLocalDaemon() {
 		return time.Now()
 	}
-
-	status, body, err := request.SockRequest("GET", "/info", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
+	defer cli.Close()
 
-	type infoJSON struct {
-		SystemTime string
-	}
-	var info infoJSON
-	err = json.Unmarshal(body, &info)
-	c.Assert(err, check.IsNil, check.Commentf("unable to unmarshal GET /info response"))
+	info, err := cli.Info(context.Background())
+	c.Assert(err, check.IsNil)
 
 	dt, err := time.Parse(time.RFC3339Nano, info.SystemTime)
 	c.Assert(err, check.IsNil, check.Commentf("invalid time format in GET /info response"))
@@ -376,10 +372,11 @@
 }
 
 func getInspectBody(c *check.C, version, id string) []byte {
-	endpoint := fmt.Sprintf("/%s/containers/%s/json", version, id)
-	status, body, err := request.SockRequest("GET", endpoint, nil, daemonHost())
+	cli, err := request.NewEnvClientWithVersion(version)
 	c.Assert(err, check.IsNil)
-	c.Assert(status, check.Equals, http.StatusOK)
+	defer cli.Close()
+	_, body, err := cli.ContainerInspectWithRaw(context.Background(), id, false)
+	c.Assert(err, check.IsNil)
 	return body
 }
 
@@ -406,20 +403,17 @@
 }
 
 func getGoroutineNumber() (int, error) {
-	i := struct {
-		NGoroutines int
-	}{}
-	status, b, err := request.SockRequest("GET", "/info", nil, daemonHost())
+	cli, err := client.NewEnvClient()
 	if err != nil {
 		return 0, err
 	}
-	if status != http.StatusOK {
-		return 0, fmt.Errorf("http status code: %d", status)
-	}
-	if err := json.Unmarshal(b, &i); err != nil {
+	defer cli.Close()
+
+	info, err := cli.Info(context.Background())
+	if err != nil {
 		return 0, err
 	}
-	return i.NGoroutines, nil
+	return info.NGoroutines, nil
 }
 
 func waitForGoroutines(expected int) error {
diff --git a/integration-cli/environment/clean.go b/integration-cli/environment/clean.go
deleted file mode 100644
index 809baa7..0000000
--- a/integration-cli/environment/clean.go
+++ /dev/null
@@ -1,216 +0,0 @@
-package environment
-
-import (
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"regexp"
-	"strings"
-
-	"github.com/docker/docker/api/types"
-	volumetypes "github.com/docker/docker/api/types/volume"
-	"github.com/docker/docker/integration-cli/request"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
-)
-
-type testingT interface {
-	logT
-	Fatalf(string, ...interface{})
-}
-
-type logT interface {
-	Logf(string, ...interface{})
-}
-
-// Clean the environment, preserving protected objects (images, containers, ...)
-// and removing everything else. It's meant to run after any tests so that they don't
-// depend on each others.
-func (e *Execution) Clean(t testingT, dockerBinary string) {
-	if (e.DaemonPlatform() != "windows") || (e.DaemonPlatform() == "windows" && e.Isolation() == "hyperv") {
-		unpauseAllContainers(t, dockerBinary)
-	}
-	deleteAllContainers(t, dockerBinary)
-	deleteAllImages(t, dockerBinary, e.protectedElements.images)
-	deleteAllVolumes(t, dockerBinary)
-	deleteAllNetworks(t, dockerBinary, e.DaemonPlatform())
-	if e.DaemonPlatform() == "linux" {
-		deleteAllPlugins(t, dockerBinary)
-	}
-}
-
-func unpauseAllContainers(t testingT, dockerBinary string) {
-	containers := getPausedContainers(t, dockerBinary)
-	if len(containers) > 0 {
-		icmd.RunCommand(dockerBinary, append([]string{"unpause"}, containers...)...).Assert(t, icmd.Success)
-	}
-}
-
-func getPausedContainers(t testingT, dockerBinary string) []string {
-	result := icmd.RunCommand(dockerBinary, "ps", "-f", "status=paused", "-q", "-a")
-	result.Assert(t, icmd.Success)
-	return strings.Fields(result.Combined())
-}
-
-var alreadyExists = regexp.MustCompile(`Error response from daemon: removal of container (\w+) is already in progress`)
-
-func deleteAllContainers(t testingT, dockerBinary string) {
-	containers := getAllContainers(t, dockerBinary)
-	if len(containers) > 0 {
-		result := icmd.RunCommand(dockerBinary, append([]string{"rm", "-fv"}, containers...)...)
-		if result.Error != nil {
-			// If the error is "No such container: ..." this means the container doesn't exists anymore,
-			// or if it is "... removal of container ... is already in progress" it will be removed eventually.
-			// We can safely ignore those.
-			if strings.Contains(result.Stderr(), "No such container") || alreadyExists.MatchString(result.Stderr()) {
-				return
-			}
-			t.Fatalf("error removing containers %v : %v (%s)", containers, result.Error, result.Combined())
-		}
-	}
-}
-
-func getAllContainers(t testingT, dockerBinary string) []string {
-	result := icmd.RunCommand(dockerBinary, "ps", "-q", "-a")
-	result.Assert(t, icmd.Success)
-	return strings.Fields(result.Combined())
-}
-
-func deleteAllImages(t testingT, dockerBinary string, protectedImages map[string]struct{}) {
-	result := icmd.RunCommand(dockerBinary, "images", "--digests")
-	result.Assert(t, icmd.Success)
-	lines := strings.Split(string(result.Combined()), "\n")[1:]
-	imgMap := map[string]struct{}{}
-	for _, l := range lines {
-		if l == "" {
-			continue
-		}
-		fields := strings.Fields(l)
-		imgTag := fields[0] + ":" + fields[1]
-		if _, ok := protectedImages[imgTag]; !ok {
-			if fields[0] == "<none>" || fields[1] == "<none>" {
-				if fields[2] != "<none>" {
-					imgMap[fields[0]+"@"+fields[2]] = struct{}{}
-				} else {
-					imgMap[fields[3]] = struct{}{}
-				}
-				// continue
-			} else {
-				imgMap[imgTag] = struct{}{}
-			}
-		}
-	}
-	if len(imgMap) != 0 {
-		imgs := make([]string, 0, len(imgMap))
-		for k := range imgMap {
-			imgs = append(imgs, k)
-		}
-		icmd.RunCommand(dockerBinary, append([]string{"rmi", "-f"}, imgs...)...).Assert(t, icmd.Success)
-	}
-}
-
-func deleteAllVolumes(t testingT, dockerBinary string) {
-	volumes, err := getAllVolumes()
-	if err != nil {
-		t.Fatalf("%v", err)
-	}
-	var errs []string
-	for _, v := range volumes {
-		status, b, err := request.SockRequest("DELETE", "/volumes/"+v.Name, nil, request.DaemonHost())
-		if err != nil {
-			errs = append(errs, err.Error())
-			continue
-		}
-		if status != http.StatusNoContent {
-			errs = append(errs, fmt.Sprintf("error deleting volume %s: %s", v.Name, string(b)))
-		}
-	}
-	if len(errs) > 0 {
-		t.Fatalf("%v", strings.Join(errs, "\n"))
-	}
-}
-
-func getAllVolumes() ([]*types.Volume, error) {
-	var volumes volumetypes.VolumesListOKBody
-	_, b, err := request.SockRequest("GET", "/volumes", nil, request.DaemonHost())
-	if err != nil {
-		return nil, err
-	}
-	if err := json.Unmarshal(b, &volumes); err != nil {
-		return nil, err
-	}
-	return volumes.Volumes, nil
-}
-
-func deleteAllNetworks(t testingT, dockerBinary string, daemonPlatform string) {
-	networks, err := getAllNetworks()
-	if err != nil {
-		t.Fatalf("%v", err)
-	}
-	var errs []string
-	for _, n := range networks {
-		if n.Name == "bridge" || n.Name == "none" || n.Name == "host" {
-			continue
-		}
-		if daemonPlatform == "windows" && strings.ToLower(n.Name) == "nat" {
-			// nat is a pre-defined network on Windows and cannot be removed
-			continue
-		}
-		status, b, err := request.SockRequest("DELETE", "/networks/"+n.Name, nil, request.DaemonHost())
-		if err != nil {
-			errs = append(errs, err.Error())
-			continue
-		}
-		if status != http.StatusNoContent {
-			errs = append(errs, fmt.Sprintf("error deleting network %s: %s", n.Name, string(b)))
-		}
-	}
-	if len(errs) > 0 {
-		t.Fatalf("%v", strings.Join(errs, "\n"))
-	}
-}
-
-func getAllNetworks() ([]types.NetworkResource, error) {
-	var networks []types.NetworkResource
-	_, b, err := request.SockRequest("GET", "/networks", nil, request.DaemonHost())
-	if err != nil {
-		return nil, err
-	}
-	if err := json.Unmarshal(b, &networks); err != nil {
-		return nil, err
-	}
-	return networks, nil
-}
-
-func deleteAllPlugins(t testingT, dockerBinary string) {
-	plugins, err := getAllPlugins()
-	if err != nil {
-		t.Fatalf("%v", err)
-	}
-	var errs []string
-	for _, p := range plugins {
-		pluginName := p.Name
-		status, b, err := request.SockRequest("DELETE", "/plugins/"+pluginName+"?force=1", nil, request.DaemonHost())
-		if err != nil {
-			errs = append(errs, err.Error())
-			continue
-		}
-		if status != http.StatusOK {
-			errs = append(errs, fmt.Sprintf("error deleting plugin %s: %s", p.Name, string(b)))
-		}
-	}
-	if len(errs) > 0 {
-		t.Fatalf("%v", strings.Join(errs, "\n"))
-	}
-}
-
-func getAllPlugins() (types.PluginsListResponse, error) {
-	var plugins types.PluginsListResponse
-	_, b, err := request.SockRequest("GET", "/plugins", nil, request.DaemonHost())
-	if err != nil {
-		return nil, err
-	}
-	if err := json.Unmarshal(b, &plugins); err != nil {
-		return nil, err
-	}
-	return plugins, nil
-}
diff --git a/integration-cli/environment/environment.go b/integration-cli/environment/environment.go
index a8a1045..0decc06 100644
--- a/integration-cli/environment/environment.go
+++ b/integration-cli/environment/environment.go
@@ -1,19 +1,11 @@
 package environment
 
 import (
-	"fmt"
-	"io/ioutil"
 	"os"
-	"os/exec"
-	"path/filepath"
-	"strconv"
-	"strings"
 
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/client"
-	"github.com/docker/docker/opts"
-	"golang.org/x/net/context"
+	"os/exec"
+
+	"github.com/docker/docker/internal/test/environment"
 )
 
 var (
@@ -23,89 +15,28 @@
 
 func init() {
 	if DefaultClientBinary == "" {
-		// TODO: to be removed once we no longer depend on the docker cli for integration tests
-		//panic("TEST_CLIENT_BINARY must be set")
 		DefaultClientBinary = "docker"
 	}
 }
 
-// Execution holds informations about the test execution environment.
+// Execution contains information about the current test execution and daemon
+// under test
 type Execution struct {
-	daemonPlatform      string
-	localDaemon         bool
-	experimentalDaemon  bool
-	daemonStorageDriver string
-	isolation           container.Isolation
-	daemonPid           int
-	daemonKernelVersion string
-	// For a local daemon on Linux, these values will be used for testing
-	// user namespace support as the standard graph path(s) will be
-	// appended with the root remapped uid.gid prefix
-	dockerBasePath       string
-	volumesConfigPath    string
-	containerStoragePath string
-	// baseImage is the name of the base image for testing
-	// Environment variable WINDOWS_BASE_IMAGE can override this
-	baseImage    string
+	environment.Execution
 	dockerBinary string
-
-	protectedElements protectedElements
 }
 
-// New creates a new Execution struct
+// DockerBinary returns the docker binary for this testing environment
+func (e *Execution) DockerBinary() string {
+	return e.dockerBinary
+}
+
+// New returns details about the testing environment
 func New() (*Execution, error) {
-	localDaemon := true
-	// Deterministically working out the environment in which CI is running
-	// to evaluate whether the daemon is local or remote is not possible through
-	// a build tag.
-	//
-	// For example Windows to Linux CI under Jenkins tests the 64-bit
-	// Windows binary build with the daemon build tag, but calls a remote
-	// Linux daemon.
-	//
-	// We can't just say if Windows then assume the daemon is local as at
-	// some point, we will be testing the Windows CLI against a Windows daemon.
-	//
-	// Similarly, it will be perfectly valid to also run CLI tests from
-	// a Linux CLI (built with the daemon tag) against a Windows daemon.
-	if len(os.Getenv("DOCKER_REMOTE_DAEMON")) > 0 {
-		localDaemon = false
-	}
-	info, err := getDaemonDockerInfo()
+	env, err := environment.New()
 	if err != nil {
 		return nil, err
 	}
-	daemonPlatform := info.OSType
-	if daemonPlatform != "linux" && daemonPlatform != "windows" {
-		return nil, fmt.Errorf("Cannot run tests against platform: %s", daemonPlatform)
-	}
-	baseImage := "scratch"
-	volumesConfigPath := filepath.Join(info.DockerRootDir, "volumes")
-	containerStoragePath := filepath.Join(info.DockerRootDir, "containers")
-	// Make sure in context of daemon, not the local platform. Note we can't
-	// use filepath.FromSlash or ToSlash here as they are a no-op on Unix.
-	if daemonPlatform == "windows" {
-		volumesConfigPath = strings.Replace(volumesConfigPath, `/`, `\`, -1)
-		containerStoragePath = strings.Replace(containerStoragePath, `/`, `\`, -1)
-
-		baseImage = "microsoft/windowsservercore"
-		if len(os.Getenv("WINDOWS_BASE_IMAGE")) > 0 {
-			baseImage = os.Getenv("WINDOWS_BASE_IMAGE")
-			fmt.Println("INFO: Windows Base image is ", baseImage)
-		}
-	} else {
-		volumesConfigPath = strings.Replace(volumesConfigPath, `\`, `/`, -1)
-		containerStoragePath = strings.Replace(containerStoragePath, `\`, `/`, -1)
-	}
-
-	var daemonPid int
-	dest := os.Getenv("DEST")
-	b, err := ioutil.ReadFile(filepath.Join(dest, "docker.pid"))
-	if err == nil {
-		if p, err := strconv.ParseInt(string(b), 10, 32); err == nil {
-			daemonPid = int(p)
-		}
-	}
 
 	dockerBinary, err := exec.LookPath(DefaultClientBinary)
 	if err != nil {
@@ -113,117 +44,36 @@
 	}
 
 	return &Execution{
-		localDaemon:          localDaemon,
-		daemonPlatform:       daemonPlatform,
-		daemonStorageDriver:  info.Driver,
-		daemonKernelVersion:  info.KernelVersion,
-		dockerBasePath:       info.DockerRootDir,
-		volumesConfigPath:    volumesConfigPath,
-		containerStoragePath: containerStoragePath,
-		isolation:            info.Isolation,
-		daemonPid:            daemonPid,
-		experimentalDaemon:   info.ExperimentalBuild,
-		baseImage:            baseImage,
-		dockerBinary:         dockerBinary,
-		protectedElements: protectedElements{
-			images: map[string]struct{}{},
-		},
+		Execution:    *env,
+		dockerBinary: dockerBinary,
 	}, nil
 }
-func getDaemonDockerInfo() (types.Info, error) {
-	// FIXME(vdemeester) should be safe to use as is
-	client, err := client.NewEnvClient()
-	if err != nil {
-		return types.Info{}, err
-	}
-	return client.Info(context.Background())
+
+// DockerBasePath is the base path of the docker folder (by default it is -/var/run/docker)
+// TODO: remove
+// Deprecated: use Execution.DaemonInfo.DockerRootDir
+func (e *Execution) DockerBasePath() string {
+	return e.DaemonInfo.DockerRootDir
 }
 
-// LocalDaemon is true if the daemon under test is on the same
-// host as the CLI.
-func (e *Execution) LocalDaemon() bool {
-	return e.localDaemon
+// ExperimentalDaemon tell whether the main daemon has
+// experimental features enabled or not
+// Deprecated: use DaemonInfo.ExperimentalBuild
+func (e *Execution) ExperimentalDaemon() bool {
+	return e.DaemonInfo.ExperimentalBuild
 }
 
 // DaemonPlatform is held globally so that tests can make intelligent
 // decisions on how to configure themselves according to the platform
 // of the daemon. This is initialized in docker_utils by sending
 // a version call to the daemon and examining the response header.
+// Deprecated: use Execution.OSType
 func (e *Execution) DaemonPlatform() string {
-	return e.daemonPlatform
-}
-
-// DockerBasePath is the base path of the docker folder (by default it is -/var/run/docker)
-func (e *Execution) DockerBasePath() string {
-	return e.dockerBasePath
-}
-
-// VolumesConfigPath is the path of the volume configuration for the testing daemon
-func (e *Execution) VolumesConfigPath() string {
-	return e.volumesConfigPath
-}
-
-// ContainerStoragePath is the path where the container are stored for the testing daemon
-func (e *Execution) ContainerStoragePath() string {
-	return e.containerStoragePath
-}
-
-// DaemonStorageDriver is held globally so that tests can know the storage
-// driver of the daemon. This is initialized in docker_utils by sending
-// a version call to the daemon and examining the response header.
-func (e *Execution) DaemonStorageDriver() string {
-	return e.daemonStorageDriver
-}
-
-// Isolation is the isolation mode of the daemon under test
-func (e *Execution) Isolation() container.Isolation {
-	return e.isolation
-}
-
-// DaemonPID is the pid of the main test daemon
-func (e *Execution) DaemonPID() int {
-	return e.daemonPid
-}
-
-// ExperimentalDaemon tell whether the main daemon has
-// experimental features enabled or not
-func (e *Execution) ExperimentalDaemon() bool {
-	return e.experimentalDaemon
+	return e.OSType
 }
 
 // MinimalBaseImage is the image used for minimal builds (it depends on the platform)
+// Deprecated: use Execution.PlatformDefaults.BaseImage
 func (e *Execution) MinimalBaseImage() string {
-	return e.baseImage
-}
-
-// DaemonKernelVersion is the kernel version of the daemon as a string, as returned
-// by an INFO call to the daemon.
-func (e *Execution) DaemonKernelVersion() string {
-	return e.daemonKernelVersion
-}
-
-// DaemonKernelVersionNumeric is the kernel version of the daemon as an integer.
-// Mostly useful on Windows where DaemonKernelVersion holds the full string such
-// as `10.0 14393 (14393.447.amd64fre.rs1_release_inmarket.161102-0100)`, but
-// integration tests really only need the `14393` piece to make decisions.
-func (e *Execution) DaemonKernelVersionNumeric() int {
-	if e.daemonPlatform != "windows" {
-		return -1
-	}
-	v, _ := strconv.Atoi(strings.Split(e.daemonKernelVersion, " ")[1])
-	return v
-}
-
-// DockerBinary returns the docker binary for this testing environment
-func (e *Execution) DockerBinary() string {
-	return e.dockerBinary
-}
-
-// DaemonHost return the daemon host string for this test execution
-func DaemonHost() string {
-	daemonURLStr := "unix://" + opts.DefaultUnixSocket
-	if daemonHostVar := os.Getenv("DOCKER_HOST"); daemonHostVar != "" {
-		daemonURLStr = daemonHostVar
-	}
-	return daemonURLStr
+	return e.PlatformDefaults.BaseImage
 }
diff --git a/integration-cli/environment/protect.go b/integration-cli/environment/protect.go
deleted file mode 100644
index 2b0dd6d..0000000
--- a/integration-cli/environment/protect.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package environment
-
-// ProtectImage adds the specified image(s) to be protected in case of clean
-func (e *Execution) ProtectImage(t testingT, images ...string) {
-	for _, image := range images {
-		e.protectedElements.images[image] = struct{}{}
-	}
-}
-
-type protectedElements struct {
-	images map[string]struct{}
-}
diff --git a/integration-cli/events_utils_test.go b/integration-cli/events_utils_test.go
index 9350edc..5801889 100644
--- a/integration-cli/events_utils_test.go
+++ b/integration-cli/events_utils_test.go
@@ -9,10 +9,10 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	eventstestutils "github.com/docker/docker/daemon/events/testutils"
 	"github.com/docker/docker/integration-cli/checker"
 	"github.com/go-check/check"
+	"github.com/sirupsen/logrus"
 )
 
 // eventMatcher is a function that tries to match an event input.
diff --git a/integration-cli/fixtures/load/frozen.go b/integration-cli/fixtures/load/frozen.go
index 13cd393..4bec323 100644
--- a/integration-cli/fixtures/load/frozen.go
+++ b/integration-cli/fixtures/load/frozen.go
@@ -9,21 +9,27 @@
 	"strings"
 	"sync"
 
+	"context"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
+	"github.com/docker/docker/pkg/jsonmessage"
+	"github.com/docker/docker/pkg/term"
 	"github.com/pkg/errors"
 )
 
-var frozenImgDir = "/docker-frozen-images"
+const frozenImgDir = "/docker-frozen-images"
 
 // FrozenImagesLinux loads the frozen image set for the integration suite
 // If the images are not available locally it will download them
 // TODO: This loads whatever is in the frozen image dir, regardless of what
 // images were passed in. If the images need to be downloaded, then it will respect
 // the passed in images
-func FrozenImagesLinux(dockerBinary string, images ...string) error {
+func FrozenImagesLinux(client client.APIClient, images ...string) error {
 	imgNS := os.Getenv("TEST_IMAGE_NAMESPACE")
 	var loadImages []struct{ srcName, destName string }
 	for _, img := range images {
-		if err := exec.Command(dockerBinary, "inspect", "--type=image", img).Run(); err != nil {
+		if !imageExists(client, img) {
 			srcName := img
 			// hello-world:latest gets re-tagged as hello-world:frozen
 			// there are some tests that use hello-world:latest specifically so it pulls
@@ -46,35 +52,41 @@
 		return nil
 	}
 
+	ctx := context.Background()
 	fi, err := os.Stat(frozenImgDir)
 	if err != nil || !fi.IsDir() {
 		srcImages := make([]string, 0, len(loadImages))
 		for _, img := range loadImages {
 			srcImages = append(srcImages, img.srcName)
 		}
-		if err := pullImages(dockerBinary, srcImages); err != nil {
+		if err := pullImages(ctx, client, srcImages); err != nil {
 			return errors.Wrap(err, "error pulling image list")
 		}
 	} else {
-		if err := loadFrozenImages(dockerBinary); err != nil {
+		if err := loadFrozenImages(ctx, client); err != nil {
 			return err
 		}
 	}
 
 	for _, img := range loadImages {
 		if img.srcName != img.destName {
-			if out, err := exec.Command(dockerBinary, "tag", img.srcName, img.destName).CombinedOutput(); err != nil {
-				return errors.Errorf("%v: %s", err, string(out))
+			if err := client.ImageTag(ctx, img.srcName, img.destName); err != nil {
+				return errors.Wrapf(err, "failed to tag %s as %s", img.srcName, img.destName)
 			}
-			if out, err := exec.Command(dockerBinary, "rmi", img.srcName).CombinedOutput(); err != nil {
-				return errors.Errorf("%v: %s", err, string(out))
+			if _, err := client.ImageRemove(ctx, img.srcName, types.ImageRemoveOptions{}); err != nil {
+				return errors.Wrapf(err, "failed to remove %s", img.srcName)
 			}
 		}
 	}
 	return nil
 }
 
-func loadFrozenImages(dockerBinary string) error {
+func imageExists(client client.APIClient, name string) bool {
+	_, _, err := client.ImageInspectWithRaw(context.Background(), name)
+	return err == nil
+}
+
+func loadFrozenImages(ctx context.Context, client client.APIClient) error {
 	tar, err := exec.LookPath("tar")
 	if err != nil {
 		return errors.Wrap(err, "could not find tar binary")
@@ -90,15 +102,16 @@
 	tarCmd.Start()
 	defer tarCmd.Wait()
 
-	cmd := exec.Command(dockerBinary, "load")
-	cmd.Stdin = out
-	if out, err := cmd.CombinedOutput(); err != nil {
-		return errors.Errorf("%v: %s", err, string(out))
+	resp, err := client.ImageLoad(ctx, out, true)
+	if err != nil {
+		return errors.Wrap(err, "failed to load frozen images")
 	}
-	return nil
+	defer resp.Body.Close()
+	fd, isTerminal := term.GetFdInfo(os.Stdout)
+	return jsonmessage.DisplayJSONMessagesStream(resp.Body, os.Stdout, fd, isTerminal, nil)
 }
 
-func pullImages(dockerBinary string, images []string) error {
+func pullImages(ctx context.Context, client client.APIClient, images []string) error {
 	cwd, err := os.Getwd()
 	if err != nil {
 		return errors.Wrap(err, "error getting path to dockerfile")
@@ -119,16 +132,8 @@
 		wg.Add(1)
 		go func(tag, ref string) {
 			defer wg.Done()
-			if out, err := exec.Command(dockerBinary, "pull", ref).CombinedOutput(); err != nil {
-				chErr <- errors.Errorf("%v: %s", string(out), err)
-				return
-			}
-			if out, err := exec.Command(dockerBinary, "tag", ref, tag).CombinedOutput(); err != nil {
-				chErr <- errors.Errorf("%v: %s", string(out), err)
-				return
-			}
-			if out, err := exec.Command(dockerBinary, "rmi", ref).CombinedOutput(); err != nil {
-				chErr <- errors.Errorf("%v: %s", string(out), err)
+			if err := pullTagAndRemove(ctx, client, ref, tag); err != nil {
+				chErr <- err
 				return
 			}
 		}(tag, ref)
@@ -138,6 +143,25 @@
 	return <-chErr
 }
 
+func pullTagAndRemove(ctx context.Context, client client.APIClient, ref string, tag string) error {
+	resp, err := client.ImagePull(ctx, ref, types.ImagePullOptions{})
+	if err != nil {
+		return errors.Wrapf(err, "failed to pull %s", ref)
+	}
+	defer resp.Close()
+	fd, isTerminal := term.GetFdInfo(os.Stdout)
+	if err := jsonmessage.DisplayJSONMessagesStream(resp, os.Stdout, fd, isTerminal, nil); err != nil {
+		return err
+	}
+
+	if err := client.ImageTag(ctx, ref, tag); err != nil {
+		return errors.Wrapf(err, "failed to tag %s as %s", ref, tag)
+	}
+	_, err = client.ImageRemove(ctx, ref, types.ImageRemoveOptions{})
+	return errors.Wrapf(err, "failed to remove %s", ref)
+
+}
+
 func readFrozenImageList(dockerfilePath string, images []string) (map[string]string, error) {
 	f, err := os.Open(dockerfilePath)
 	if err != nil {
@@ -156,11 +180,6 @@
 			continue
 		}
 
-		frozenImgDir = line[2]
-		if line[2] == frozenImgDir {
-			frozenImgDir = filepath.Join(os.Getenv("DEST"), "frozen-images")
-		}
-
 		for scanner.Scan() {
 			img := strings.TrimSpace(scanner.Text())
 			img = strings.TrimSuffix(img, "\\")
diff --git a/integration-cli/fixtures/plugin/plugin.go b/integration-cli/fixtures/plugin/plugin.go
index c8259be..0b13134 100644
--- a/integration-cli/fixtures/plugin/plugin.go
+++ b/integration-cli/fixtures/plugin/plugin.go
@@ -1,13 +1,23 @@
 package plugin
 
 import (
+	"encoding/json"
 	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"time"
 
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/plugin"
+	"github.com/docker/docker/registry"
+	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 )
 
-// CreateOpt is is passed used to change the defualt plugin config before
+// CreateOpt is is passed used to change the default plugin config before
 // creating it
 type CreateOpt func(*Config)
 
@@ -32,3 +42,142 @@
 type CreateClient interface {
 	PluginCreate(context.Context, io.Reader, types.PluginCreateOptions) error
 }
+
+// Create creates a new plugin with the specified name
+func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
+	tmpDir, err := ioutil.TempDir("", "create-test-plugin")
+	if err != nil {
+		return err
+	}
+	defer os.RemoveAll(tmpDir)
+
+	tar, err := makePluginBundle(tmpDir, opts...)
+	if err != nil {
+		return err
+	}
+	defer tar.Close()
+
+	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
+	defer cancel()
+
+	return c.PluginCreate(ctx, tar, types.PluginCreateOptions{RepoName: name})
+}
+
+// CreateInRegistry makes a plugin (locally) and pushes it to a registry.
+// This does not use a dockerd instance to create or push the plugin.
+// If you just want to create a plugin in some daemon, use `Create`.
+//
+// This can be useful when testing plugins on swarm where you don't really want
+// the plugin to exist on any of the daemons (immediately) and there needs to be
+// some way to distribute the plugin.
+func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
+	tmpDir, err := ioutil.TempDir("", "create-test-plugin-local")
+	if err != nil {
+		return err
+	}
+	defer os.RemoveAll(tmpDir)
+
+	inPath := filepath.Join(tmpDir, "plugin")
+	if err := os.MkdirAll(inPath, 0755); err != nil {
+		return errors.Wrap(err, "error creating plugin root")
+	}
+
+	tar, err := makePluginBundle(inPath, opts...)
+	if err != nil {
+		return err
+	}
+	defer tar.Close()
+
+	dummyExec := func(m *plugin.Manager) (plugin.Executor, error) {
+		return nil, nil
+	}
+
+	regService, err := registry.NewService(registry.ServiceOptions{V2Only: true})
+	if err != nil {
+		return err
+	}
+
+	managerConfig := plugin.ManagerConfig{
+		Store:           plugin.NewStore(),
+		RegistryService: regService,
+		Root:            filepath.Join(tmpDir, "root"),
+		ExecRoot:        "/run/docker", // manager init fails if not set
+		CreateExecutor:  dummyExec,
+		LogPluginEvent:  func(id, name, action string) {}, // panics when not set
+	}
+	manager, err := plugin.NewManager(managerConfig)
+	if err != nil {
+		return errors.Wrap(err, "error creating plugin manager")
+	}
+
+	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
+	defer cancel()
+	if err := manager.CreateFromContext(ctx, tar, &types.PluginCreateOptions{RepoName: repo}); err != nil {
+		return err
+	}
+
+	if auth == nil {
+		auth = &types.AuthConfig{}
+	}
+	err = manager.Push(ctx, repo, nil, auth, ioutil.Discard)
+	return errors.Wrap(err, "error pushing plugin")
+}
+
+func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) {
+	p := &types.PluginConfig{
+		Interface: types.PluginConfigInterface{
+			Socket: "basic.sock",
+			Types:  []types.PluginInterfaceType{{Capability: "docker.dummy/1.0"}},
+		},
+		Entrypoint: []string{"/basic"},
+	}
+	cfg := &Config{
+		PluginConfig: p,
+	}
+	for _, o := range opts {
+		o(cfg)
+	}
+	if cfg.binPath == "" {
+		binPath, err := ensureBasicPluginBin()
+		if err != nil {
+			return nil, err
+		}
+		cfg.binPath = binPath
+	}
+
+	configJSON, err := json.Marshal(p)
+	if err != nil {
+		return nil, err
+	}
+	if err := ioutil.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil {
+		return nil, err
+	}
+	if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(p.Entrypoint[0])), 0755); err != nil {
+		return nil, errors.Wrap(err, "error creating plugin rootfs dir")
+	}
+	if err := archive.NewDefaultArchiver().CopyFileWithTar(cfg.binPath, filepath.Join(inPath, "rootfs", p.Entrypoint[0])); err != nil {
+		return nil, errors.Wrap(err, "error copying plugin binary to rootfs path")
+	}
+	tar, err := archive.Tar(inPath, archive.Uncompressed)
+	return tar, errors.Wrap(err, "error making plugin archive")
+}
+
+func ensureBasicPluginBin() (string, error) {
+	name := "docker-basic-plugin"
+	p, err := exec.LookPath(name)
+	if err == nil {
+		return p, nil
+	}
+
+	goBin, err := exec.LookPath("go")
+	if err != nil {
+		return "", err
+	}
+	installPath := filepath.Join(os.Getenv("GOPATH"), "bin", name)
+	cmd := exec.Command(goBin, "build", "-o", installPath, "./"+filepath.Join("fixtures", "plugin", "basic"))
+	cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
+	if out, err := cmd.CombinedOutput(); err != nil {
+		return "", errors.Wrapf(err, "error building basic plugin bin: %s", string(out))
+	}
+	return installPath, nil
+}
diff --git a/integration-cli/fixtures/plugin/plugin_linux.go b/integration-cli/fixtures/plugin/plugin_linux.go
deleted file mode 100644
index 757694c..0000000
--- a/integration-cli/fixtures/plugin/plugin_linux.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package plugin
-
-import (
-	"encoding/json"
-	"io"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"time"
-
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/libcontainerd"
-	"github.com/docker/docker/pkg/archive"
-	"github.com/docker/docker/plugin"
-	"github.com/docker/docker/registry"
-	"github.com/pkg/errors"
-	"golang.org/x/net/context"
-)
-
-// Create creates a new plugin with the specified name
-func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
-	tmpDir, err := ioutil.TempDir("", "create-test-plugin")
-	if err != nil {
-		return err
-	}
-	defer os.RemoveAll(tmpDir)
-
-	tar, err := makePluginBundle(tmpDir, opts...)
-	if err != nil {
-		return err
-	}
-	defer tar.Close()
-
-	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
-	defer cancel()
-
-	return c.PluginCreate(ctx, tar, types.PluginCreateOptions{RepoName: name})
-}
-
-// TODO(@cpuguy83): we really shouldn't have to do this...
-// The manager panics on init when `Executor` is not set.
-type dummyExecutor struct{}
-
-func (dummyExecutor) Client(libcontainerd.Backend) (libcontainerd.Client, error) { return nil, nil }
-func (dummyExecutor) Cleanup()                                                   {}
-func (dummyExecutor) UpdateOptions(...libcontainerd.RemoteOption) error          { return nil }
-
-// CreateInRegistry makes a plugin (locally) and pushes it to a registry.
-// This does not use a dockerd instance to create or push the plugin.
-// If you just want to create a plugin in some daemon, use `Create`.
-//
-// This can be useful when testing plugins on swarm where you don't really want
-// the plugin to exist on any of the daemons (immediately) and there needs to be
-// some way to distribute the plugin.
-func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
-	tmpDir, err := ioutil.TempDir("", "create-test-plugin-local")
-	if err != nil {
-		return err
-	}
-	defer os.RemoveAll(tmpDir)
-
-	inPath := filepath.Join(tmpDir, "plugin")
-	if err := os.MkdirAll(inPath, 0755); err != nil {
-		return errors.Wrap(err, "error creating plugin root")
-	}
-
-	tar, err := makePluginBundle(inPath, opts...)
-	if err != nil {
-		return err
-	}
-	defer tar.Close()
-
-	managerConfig := plugin.ManagerConfig{
-		Store:           plugin.NewStore(),
-		RegistryService: registry.NewService(registry.ServiceOptions{V2Only: true}),
-		Root:            filepath.Join(tmpDir, "root"),
-		ExecRoot:        "/run/docker", // manager init fails if not set
-		Executor:        dummyExecutor{},
-		LogPluginEvent:  func(id, name, action string) {}, // panics when not set
-	}
-	manager, err := plugin.NewManager(managerConfig)
-	if err != nil {
-		return errors.Wrap(err, "error creating plugin manager")
-	}
-
-	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
-	defer cancel()
-	if err := manager.CreateFromContext(ctx, tar, &types.PluginCreateOptions{RepoName: repo}); err != nil {
-		return err
-	}
-
-	if auth == nil {
-		auth = &types.AuthConfig{}
-	}
-	err = manager.Push(ctx, repo, nil, auth, ioutil.Discard)
-	return errors.Wrap(err, "error pushing plugin")
-}
-
-func makePluginBundle(inPath string, opts ...CreateOpt) (io.ReadCloser, error) {
-	p := &types.PluginConfig{
-		Interface: types.PluginConfigInterface{
-			Socket: "basic.sock",
-			Types:  []types.PluginInterfaceType{{Capability: "docker.dummy/1.0"}},
-		},
-		Entrypoint: []string{"/basic"},
-	}
-	cfg := &Config{
-		PluginConfig: p,
-	}
-	for _, o := range opts {
-		o(cfg)
-	}
-	if cfg.binPath == "" {
-		binPath, err := ensureBasicPluginBin()
-		if err != nil {
-			return nil, err
-		}
-		cfg.binPath = binPath
-	}
-
-	configJSON, err := json.Marshal(p)
-	if err != nil {
-		return nil, err
-	}
-	if err := ioutil.WriteFile(filepath.Join(inPath, "config.json"), configJSON, 0644); err != nil {
-		return nil, err
-	}
-	if err := os.MkdirAll(filepath.Join(inPath, "rootfs", filepath.Dir(p.Entrypoint[0])), 0755); err != nil {
-		return nil, errors.Wrap(err, "error creating plugin rootfs dir")
-	}
-	if err := archive.NewDefaultArchiver().CopyFileWithTar(cfg.binPath, filepath.Join(inPath, "rootfs", p.Entrypoint[0])); err != nil {
-		return nil, errors.Wrap(err, "error copying plugin binary to rootfs path")
-	}
-	tar, err := archive.Tar(inPath, archive.Uncompressed)
-	return tar, errors.Wrap(err, "error making plugin archive")
-}
-
-func ensureBasicPluginBin() (string, error) {
-	name := "docker-basic-plugin"
-	p, err := exec.LookPath(name)
-	if err == nil {
-		return p, nil
-	}
-
-	goBin, err := exec.LookPath("go")
-	if err != nil {
-		return "", err
-	}
-	installPath := filepath.Join(os.Getenv("GOPATH"), "bin", name)
-	cmd := exec.Command(goBin, "build", "-o", installPath, "./"+filepath.Join("fixtures", "plugin", "basic"))
-	cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
-	if out, err := cmd.CombinedOutput(); err != nil {
-		return "", errors.Wrapf(err, "error building basic plugin bin: %s", string(out))
-	}
-	return installPath, nil
-}
diff --git a/integration-cli/fixtures/plugin/plugin_unsuported.go b/integration-cli/fixtures/plugin/plugin_unsuported.go
deleted file mode 100644
index 7c272a3..0000000
--- a/integration-cli/fixtures/plugin/plugin_unsuported.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build !linux
-
-package plugin
-
-import (
-	"github.com/docker/docker/api/types"
-	"github.com/pkg/errors"
-	"golang.org/x/net/context"
-)
-
-// Create is not supported on this platform
-func Create(ctx context.Context, c CreateClient, name string, opts ...CreateOpt) error {
-	return errors.New("not supported on this platform")
-}
-
-// CreateInRegistry is not supported on this platform
-func CreateInRegistry(ctx context.Context, repo string, auth *types.AuthConfig, opts ...CreateOpt) error {
-	return errors.New("not supported on this platform")
-}
diff --git a/integration-cli/fixtures_linux_daemon_test.go b/integration-cli/fixtures_linux_daemon_test.go
index 895f976..6ac4511 100644
--- a/integration-cli/fixtures_linux_daemon_test.go
+++ b/integration-cli/fixtures_linux_daemon_test.go
@@ -24,16 +24,6 @@
 	Logf(string, ...interface{})
 }
 
-func ensureFrozenImagesLinux(t testingT) {
-	images := []string{"busybox:latest", "hello-world:frozen", "debian:jessie"}
-	err := load.FrozenImagesLinux(dockerBinary, images...)
-	if err != nil {
-		t.Logf(dockerCmdWithError("images"))
-		t.Fatalf("%+v", err)
-	}
-	defer testEnv.ProtectImage(t, images...)
-}
-
 var ensureSyscallTestOnce sync.Once
 
 func ensureSyscallTest(c *check.C) {
@@ -67,7 +57,7 @@
 	}
 
 	if runtime.GOOS == "linux" && runtime.GOARCH == "amd64" {
-		out, err := exec.Command(gcc, "-s", "-m32", "-nostdlib", "../contrib/syscall-test/exit32.s", "-o", tmp+"/"+"exit32-test").CombinedOutput()
+		out, err := exec.Command(gcc, "-s", "-m32", "-nostdlib", "-static", "../contrib/syscall-test/exit32.s", "-o", tmp+"/"+"exit32-test").CombinedOutput()
 		c.Assert(err, checker.IsNil, check.Commentf(string(out)))
 	}
 
@@ -89,7 +79,7 @@
 }
 
 func ensureSyscallTestBuild(c *check.C) {
-	err := load.FrozenImagesLinux(dockerBinary, "buildpack-deps:jessie")
+	err := load.FrozenImagesLinux(testEnv.APIClient(), "buildpack-deps:jessie")
 	c.Assert(err, checker.IsNil)
 
 	var buildArgs []string
@@ -136,7 +126,7 @@
 }
 
 func ensureNNPTestBuild(c *check.C) {
-	err := load.FrozenImagesLinux(dockerBinary, "buildpack-deps:jessie")
+	err := load.FrozenImagesLinux(testEnv.APIClient(), "buildpack-deps:jessie")
 	c.Assert(err, checker.IsNil)
 
 	var buildArgs []string
diff --git a/integration-cli/request/request.go b/integration-cli/request/request.go
index 6f2bf65..f22b08d 100644
--- a/integration-cli/request/request.go
+++ b/integration-cli/request/request.go
@@ -21,7 +21,6 @@
 	dclient "github.com/docker/docker/client"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/ioutils"
-	"github.com/docker/docker/pkg/testutil"
 	"github.com/docker/go-connections/sockets"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/pkg/errors"
@@ -130,7 +129,11 @@
 		return nil, fmt.Errorf("could not create new request: %v", err)
 	}
 
-	req.URL.Scheme = "http"
+	if os.Getenv("DOCKER_TLS_VERIFY") != "" {
+		req.URL.Scheme = "https"
+	} else {
+		req.URL.Scheme = "http"
+	}
 	req.URL.Host = addr
 
 	for _, config := range modifiers {
@@ -166,7 +169,11 @@
 
 // NewClient returns a new Docker API client
 func NewClient() (dclient.APIClient, error) {
-	host := DaemonHost()
+	return NewClientForHost(DaemonHost())
+}
+
+// NewClientForHost returns a Docker API client for the host
+func NewClientForHost(host string) (dclient.APIClient, error) {
 	httpClient, err := NewHTTPClient(host)
 	if err != nil {
 		return nil, err
@@ -214,10 +221,16 @@
 	if err != nil {
 		return -1, nil, err
 	}
-	b, err := testutil.ReadBody(body)
+	b, err := ReadBody(body)
 	return res.StatusCode, b, err
 }
 
+// ReadBody read the specified ReadCloser content and returns it
+func ReadBody(b io.ReadCloser) ([]byte, error) {
+	defer b.Close()
+	return ioutil.ReadAll(b)
+}
+
 // SockRequestRaw create a request against the specified host (with method, endpoint and other request modifier) and
 // returns the http response, the output as a io.ReadCloser
 // Deprecated: use request.Do (or Get, Delete, Post) instead
@@ -310,3 +323,35 @@
 	}
 	return daemonURLStr
 }
+
+// NewEnvClientWithVersion returns a docker client with a specified version.
+// See: github.com/docker/docker/client `NewEnvClient()`
+func NewEnvClientWithVersion(version string) (*dclient.Client, error) {
+	if version == "" {
+		return nil, errors.New("version not specified")
+	}
+
+	var httpClient *http.Client
+	if os.Getenv("DOCKER_CERT_PATH") != "" {
+		tlsConfig, err := getTLSConfig()
+		if err != nil {
+			return nil, err
+		}
+		httpClient = &http.Client{
+			Transport: &http.Transport{
+				TLSClientConfig: tlsConfig,
+			},
+		}
+	}
+
+	host := os.Getenv("DOCKER_HOST")
+	if host == "" {
+		host = dclient.DefaultDockerHost
+	}
+
+	cli, err := dclient.NewClient(host, version, httpClient, nil)
+	if err != nil {
+		return cli, err
+	}
+	return cli, nil
+}
diff --git a/integration-cli/requirement/requirement.go b/integration-cli/requirement/requirement.go
index f609174..9486c32 100644
--- a/integration-cli/requirement/requirement.go
+++ b/integration-cli/requirement/requirement.go
@@ -8,7 +8,8 @@
 	"strings"
 )
 
-type skipT interface {
+// SkipT is the interface required to skip tests
+type SkipT interface {
 	Skip(reason string)
 }
 
@@ -17,7 +18,7 @@
 
 // Is checks if the environment satisfies the requirements
 // for the test to run or skips the tests.
-func Is(s skipT, requirements ...Test) {
+func Is(s SkipT, requirements ...Test) {
 	for _, r := range requirements {
 		isValid := r()
 		if !isValid {
diff --git a/integration-cli/requirements_test.go b/integration-cli/requirements_test.go
index 15b3df2..838977e 100644
--- a/integration-cli/requirements_test.go
+++ b/integration-cli/requirements_test.go
@@ -1,56 +1,63 @@
 package main
 
 import (
+	"context"
 	"fmt"
 	"io/ioutil"
 	"net/http"
 	"os"
 	"os/exec"
+	"strconv"
 	"strings"
 	"time"
 
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
 	"github.com/docker/docker/integration-cli/requirement"
-	"github.com/go-check/check"
 )
 
-func PlatformIs(platform string) bool {
-	return testEnv.DaemonPlatform() == platform
-}
-
-func ArchitectureIs(arch string) bool {
-	return os.Getenv("DOCKER_ENGINE_GOARCH") == arch
-}
-
 func ArchitectureIsNot(arch string) bool {
 	return os.Getenv("DOCKER_ENGINE_GOARCH") != arch
 }
 
-func StorageDriverIs(storageDriver string) bool {
-	return strings.HasPrefix(testEnv.DaemonStorageDriver(), storageDriver)
-}
-
-func StorageDriverIsNot(storageDriver string) bool {
-	return !strings.HasPrefix(testEnv.DaemonStorageDriver(), storageDriver)
-}
-
 func DaemonIsWindows() bool {
-	return PlatformIs("windows")
+	return testEnv.OSType == "windows"
+}
+
+func DaemonIsWindowsAtLeastBuild(buildNumber int) func() bool {
+	return func() bool {
+		if testEnv.OSType != "windows" {
+			return false
+		}
+		version := testEnv.DaemonInfo.KernelVersion
+		numVersion, _ := strconv.Atoi(strings.Split(version, " ")[1])
+		return numVersion >= buildNumber
+	}
 }
 
 func DaemonIsLinux() bool {
-	return PlatformIs("linux")
+	return testEnv.OSType == "linux"
 }
 
+func OnlyDefaultNetworks() bool {
+	cli, err := client.NewEnvClient()
+	if err != nil {
+		return false
+	}
+	networks, err := cli.NetworkList(context.TODO(), types.NetworkListOptions{})
+	if err != nil || len(networks) > 0 {
+		return false
+	}
+	return true
+}
+
+// Deprecated: use skip.IfCondition(t, !testEnv.DaemonInfo.ExperimentalBuild)
 func ExperimentalDaemon() bool {
-	return testEnv.ExperimentalDaemon()
-}
-
-func NotExperimentalDaemon() bool {
-	return !testEnv.ExperimentalDaemon()
+	return testEnv.DaemonInfo.ExperimentalBuild
 }
 
 func IsAmd64() bool {
-	return ArchitectureIs("amd64")
+	return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64"
 }
 
 func NotArm() bool {
@@ -70,7 +77,7 @@
 }
 
 func SameHostDaemon() bool {
-	return testEnv.LocalDaemon()
+	return testEnv.IsLocalDaemon()
 }
 
 func UnixCli() bool {
@@ -121,12 +128,8 @@
 	return err == nil
 }
 
-func NotOverlay() bool {
-	return StorageDriverIsNot("overlay")
-}
-
 func Devicemapper() bool {
-	return StorageDriverIs("devicemapper")
+	return strings.HasPrefix(testEnv.DaemonInfo.Driver, "devicemapper")
 }
 
 func IPv6() bool {
@@ -171,21 +174,21 @@
 }
 
 func IsPausable() bool {
-	if testEnv.DaemonPlatform() == "windows" {
-		return testEnv.Isolation() == "hyperv"
+	if testEnv.OSType == "windows" {
+		return testEnv.DaemonInfo.Isolation == "hyperv"
 	}
 	return true
 }
 
 func NotPausable() bool {
-	if testEnv.DaemonPlatform() == "windows" {
-		return testEnv.Isolation() == "process"
+	if testEnv.OSType == "windows" {
+		return testEnv.DaemonInfo.Isolation == "process"
 	}
 	return false
 }
 
 func IsolationIs(expectedIsolation string) bool {
-	return testEnv.DaemonPlatform() == "windows" && string(testEnv.Isolation()) == expectedIsolation
+	return testEnv.OSType == "windows" && string(testEnv.DaemonInfo.Isolation) == expectedIsolation
 }
 
 func IsolationIsHyperv() bool {
@@ -198,6 +201,6 @@
 
 // testRequires checks if the environment satisfies the requirements
 // for the test to run or skips the tests.
-func testRequires(c *check.C, requirements ...requirement.Test) {
+func testRequires(c requirement.SkipT, requirements ...requirement.Test) {
 	requirement.Is(c, requirements...)
 }
diff --git a/integration-cli/requirements_unix_test.go b/integration-cli/requirements_unix_test.go
index 2ed04f6..7c594f7 100644
--- a/integration-cli/requirements_unix_test.go
+++ b/integration-cli/requirements_unix_test.go
@@ -18,19 +18,19 @@
 )
 
 func cpuCfsPeriod() bool {
-	return SysInfo.CPUCfsPeriod
+	return testEnv.DaemonInfo.CPUCfsPeriod
 }
 
 func cpuCfsQuota() bool {
-	return SysInfo.CPUCfsQuota
+	return testEnv.DaemonInfo.CPUCfsQuota
 }
 
 func cpuShare() bool {
-	return SysInfo.CPUShares
+	return testEnv.DaemonInfo.CPUShares
 }
 
 func oomControl() bool {
-	return SysInfo.OomKillDisable
+	return testEnv.DaemonInfo.OomKillDisable
 }
 
 func pidsLimit() bool {
@@ -38,11 +38,11 @@
 }
 
 func kernelMemorySupport() bool {
-	return SysInfo.KernelMemory
+	return testEnv.DaemonInfo.KernelMemory
 }
 
 func memoryLimitSupport() bool {
-	return SysInfo.MemoryLimit
+	return testEnv.DaemonInfo.MemoryLimit
 }
 
 func memoryReservationSupport() bool {
@@ -50,19 +50,19 @@
 }
 
 func swapMemorySupport() bool {
-	return SysInfo.SwapLimit
+	return testEnv.DaemonInfo.SwapLimit
 }
 
 func memorySwappinessSupport() bool {
-	return SysInfo.MemorySwappiness
+	return SameHostDaemon() && SysInfo.MemorySwappiness
 }
 
 func blkioWeight() bool {
-	return SysInfo.BlkioWeight
+	return SameHostDaemon() && SysInfo.BlkioWeight
 }
 
 func cgroupCpuset() bool {
-	return SysInfo.Cpuset
+	return testEnv.DaemonInfo.CPUSet
 }
 
 func seccompEnabled() bool {
@@ -101,7 +101,7 @@
 		return false
 	}
 
-	daemonV, err := kernel.ParseRelease(testEnv.DaemonKernelVersion())
+	daemonV, err := kernel.ParseRelease(testEnv.DaemonInfo.KernelVersion)
 	if err != nil {
 		return false
 	}
@@ -111,5 +111,7 @@
 }
 
 func init() {
-	SysInfo = sysinfo.New(true)
+	if SameHostDaemon() {
+		SysInfo = sysinfo.New(true)
+	}
 }
diff --git a/integration-cli/trust_server_test.go b/integration-cli/trust_server_test.go
index 9a99932..19abe87 100644
--- a/integration-cli/trust_server_test.go
+++ b/integration-cli/trust_server_test.go
@@ -18,9 +18,9 @@
 	"github.com/docker/docker/integration-cli/cli"
 	"github.com/docker/docker/integration-cli/fixtures/plugin"
 	"github.com/docker/docker/integration-cli/request"
-	icmd "github.com/docker/docker/pkg/testutil/cmd"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
 )
 
 var notaryBinary = "notary"
diff --git a/integration-cli/utils_test.go b/integration-cli/utils_test.go
index 2725ddf..d176c7f 100644
--- a/integration-cli/utils_test.go
+++ b/integration-cli/utils_test.go
@@ -1,9 +1,16 @@
 package main
 
 import (
+	"fmt"
+	"os"
 	"os/exec"
+	"path/filepath"
+	"strings"
 
-	"github.com/docker/docker/pkg/testutil/cmd"
+	"github.com/docker/docker/pkg/stringutils"
+	"github.com/go-check/check"
+	"github.com/gotestyourself/gotestyourself/icmd"
+	"github.com/pkg/errors"
 )
 
 func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) {
@@ -14,15 +21,15 @@
 }
 
 // TODO: update code to call cmd.RunCmd directly, and remove this function
-// Deprecated: use pkg/testutil/cmd instead
+// Deprecated: use gotestyourself/gotestyourself/icmd
 func runCommandWithOutput(execCmd *exec.Cmd) (string, int, error) {
-	result := cmd.RunCmd(transformCmd(execCmd))
+	result := icmd.RunCmd(transformCmd(execCmd))
 	return result.Combined(), result.ExitCode, result.Error
 }
 
 // Temporary shim for migrating commands to the new function
-func transformCmd(execCmd *exec.Cmd) cmd.Cmd {
-	return cmd.Cmd{
+func transformCmd(execCmd *exec.Cmd) icmd.Cmd {
+	return icmd.Cmd{
 		Command: execCmd.Args,
 		Env:     execCmd.Env,
 		Dir:     execCmd.Dir,
@@ -30,3 +37,147 @@
 		Stdout:  execCmd.Stdout,
 	}
 }
+
+// ParseCgroupPaths parses 'procCgroupData', which is output of '/proc/<pid>/cgroup', and returns
+// a map which cgroup name as key and path as value.
+func ParseCgroupPaths(procCgroupData string) map[string]string {
+	cgroupPaths := map[string]string{}
+	for _, line := range strings.Split(procCgroupData, "\n") {
+		parts := strings.Split(line, ":")
+		if len(parts) != 3 {
+			continue
+		}
+		cgroupPaths[parts[1]] = parts[2]
+	}
+	return cgroupPaths
+}
+
+// RandomTmpDirPath provides a temporary path with rand string appended.
+// does not create or checks if it exists.
+func RandomTmpDirPath(s string, platform string) string {
+	// TODO: why doesn't this use os.TempDir() ?
+	tmp := "/tmp"
+	if platform == "windows" {
+		tmp = os.Getenv("TEMP")
+	}
+	path := filepath.Join(tmp, fmt.Sprintf("%s.%s", s, stringutils.GenerateRandomAlphaOnlyString(10)))
+	if platform == "windows" {
+		return filepath.FromSlash(path) // Using \
+	}
+	return filepath.ToSlash(path) // Using /
+}
+
+// RunCommandPipelineWithOutput runs the array of commands with the output
+// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
+// It returns the final output, the exitCode different from 0 and the error
+// if something bad happened.
+// Deprecated: use icmd instead
+func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, err error) {
+	if len(cmds) < 2 {
+		return "", errors.New("pipeline does not have multiple cmds")
+	}
+
+	// connect stdin of each cmd to stdout pipe of previous cmd
+	for i, cmd := range cmds {
+		if i > 0 {
+			prevCmd := cmds[i-1]
+			cmd.Stdin, err = prevCmd.StdoutPipe()
+
+			if err != nil {
+				return "", fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
+			}
+		}
+	}
+
+	// start all cmds except the last
+	for _, cmd := range cmds[:len(cmds)-1] {
+		if err = cmd.Start(); err != nil {
+			return "", fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
+		}
+	}
+
+	defer func() {
+		var pipeErrMsgs []string
+		// wait all cmds except the last to release their resources
+		for _, cmd := range cmds[:len(cmds)-1] {
+			if pipeErr := cmd.Wait(); pipeErr != nil {
+				pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
+			}
+		}
+		if len(pipeErrMsgs) > 0 && err == nil {
+			err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
+		}
+	}()
+
+	// wait on last cmd
+	out, err := cmds[len(cmds)-1].CombinedOutput()
+	return string(out), err
+}
+
+type elementListOptions struct {
+	element, format string
+}
+
+func existingElements(c *check.C, opts elementListOptions) []string {
+	args := []string{}
+	switch opts.element {
+	case "container":
+		args = append(args, "ps", "-a")
+	case "image":
+		args = append(args, "images", "-a")
+	case "network":
+		args = append(args, "network", "ls")
+	case "plugin":
+		args = append(args, "plugin", "ls")
+	case "volume":
+		args = append(args, "volume", "ls")
+	}
+	if opts.format != "" {
+		args = append(args, "--format", opts.format)
+	}
+	out, _ := dockerCmd(c, args...)
+	lines := []string{}
+	for _, l := range strings.Split(out, "\n") {
+		if l != "" {
+			lines = append(lines, l)
+		}
+	}
+	return lines
+}
+
+// ExistingContainerIDs returns a list of currently existing container IDs.
+func ExistingContainerIDs(c *check.C) []string {
+	return existingElements(c, elementListOptions{element: "container", format: "{{.ID}}"})
+}
+
+// ExistingContainerNames returns a list of existing container names.
+func ExistingContainerNames(c *check.C) []string {
+	return existingElements(c, elementListOptions{element: "container", format: "{{.Names}}"})
+}
+
+// RemoveLinesForExistingElements removes existing elements from the output of a
+// docker command.
+// This function takes an output []string and returns a []string.
+func RemoveLinesForExistingElements(output, existing []string) []string {
+	for _, e := range existing {
+		index := -1
+		for i, line := range output {
+			if strings.Contains(line, e) {
+				index = i
+				break
+			}
+		}
+		if index != -1 {
+			output = append(output[:index], output[index+1:]...)
+		}
+	}
+	return output
+}
+
+// RemoveOutputForExistingElements removes existing elements from the output of
+// a docker command.
+// This function takes an output string and returns a string.
+func RemoveOutputForExistingElements(output string, existing []string) string {
+	res := RemoveLinesForExistingElements(strings.Split(output, "\n"), existing)
+	return strings.Join(res, "\n")
+}
diff --git a/integration/container/create_test.go b/integration/container/create_test.go
new file mode 100644
index 0000000..6c8a084
--- /dev/null
+++ b/integration/container/create_test.go
@@ -0,0 +1,93 @@
+package container
+
+import (
+	"context"
+	"strconv"
+	"testing"
+
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/integration/util/request"
+	"github.com/docker/docker/internal/testutil"
+)
+
+func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
+	defer setupTest(t)()
+	client := request.NewAPIClient(t)
+
+	testCases := []struct {
+		doc           string
+		image         string
+		expectedError string
+	}{
+		{
+			doc:           "image and tag",
+			image:         "test456:v1",
+			expectedError: "No such image: test456:v1",
+		},
+		{
+			doc:           "image no tag",
+			image:         "test456",
+			expectedError: "No such image: test456",
+		},
+		{
+			doc:           "digest",
+			image:         "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
+			expectedError: "No such image: sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efeaaaa",
+		},
+	}
+
+	for _, tc := range testCases {
+		tc := tc
+		t.Run(tc.doc, func(t *testing.T) {
+			t.Parallel()
+			_, err := client.ContainerCreate(context.Background(),
+				&container.Config{Image: tc.image},
+				&container.HostConfig{},
+				&network.NetworkingConfig{},
+				"foo",
+			)
+			testutil.ErrorContains(t, err, tc.expectedError)
+		})
+	}
+}
+
+func TestCreateWithInvalidEnv(t *testing.T) {
+	defer setupTest(t)()
+	client := request.NewAPIClient(t)
+
+	testCases := []struct {
+		env           string
+		expectedError string
+	}{
+		{
+			env:           "",
+			expectedError: "invalid environment variable:",
+		},
+		{
+			env:           "=",
+			expectedError: "invalid environment variable: =",
+		},
+		{
+			env:           "=foo",
+			expectedError: "invalid environment variable: =foo",
+		},
+	}
+
+	for index, tc := range testCases {
+		tc := tc
+		t.Run(strconv.Itoa(index), func(t *testing.T) {
+			t.Parallel()
+			_, err := client.ContainerCreate(context.Background(),
+				&container.Config{
+					Image: "busybox",
+					Env:   []string{tc.env},
+				},
+				&container.HostConfig{},
+				&network.NetworkingConfig{},
+				"foo",
+			)
+			testutil.ErrorContains(t, err, tc.expectedError)
+		})
+	}
+}
diff --git a/integration/container/main_test.go b/integration/container/main_test.go
new file mode 100644
index 0000000..fbfed2a
--- /dev/null
+++ b/integration/container/main_test.go
@@ -0,0 +1,28 @@
+package container
+
+import (
+	"fmt"
+	"os"
+	"testing"
+
+	"github.com/docker/docker/internal/test/environment"
+)
+
+var testEnv *environment.Execution
+
+func TestMain(m *testing.M) {
+	var err error
+	testEnv, err = environment.New()
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	testEnv.Print()
+	os.Exit(m.Run())
+}
+
+func setupTest(t *testing.T) func() {
+	environment.ProtectAll(t, testEnv)
+	return func() { testEnv.Clean(t) }
+}
diff --git a/integration/container/rename_test.go b/integration/container/rename_test.go
new file mode 100644
index 0000000..cf36757
--- /dev/null
+++ b/integration/container/rename_test.go
@@ -0,0 +1,88 @@
+package container
+
+import (
+	"context"
+	"testing"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/container"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/api/types/strslice"
+	"github.com/docker/docker/client"
+	"github.com/docker/docker/integration/util/request"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func runContainer(ctx context.Context, t *testing.T, client client.APIClient, cntCfg *container.Config, hstCfg *container.HostConfig, nwkCfg *network.NetworkingConfig, cntName string) string {
+	cnt, err := client.ContainerCreate(ctx, cntCfg, hstCfg, nwkCfg, cntName)
+	require.NoError(t, err)
+
+	err = client.ContainerStart(ctx, cnt.ID, types.ContainerStartOptions{})
+	require.NoError(t, err)
+	return cnt.ID
+}
+
+// This test simulates the scenario mentioned in #31392:
+// Having two linked container, renaming the target and bringing a replacement
+// and then deleting and recreating the source container linked to the new target.
+// This checks that "rename" updates source container correctly and doesn't set it to null.
+func TestRenameLinkedContainer(t *testing.T) {
+	defer setupTest(t)()
+	ctx := context.Background()
+	client := request.NewAPIClient(t)
+
+	cntConfig := &container.Config{
+		Image: "busybox",
+		Tty:   true,
+		Cmd:   strslice.StrSlice([]string{"top"}),
+	}
+
+	var (
+		aID, bID string
+		cntJSON  types.ContainerJSON
+		err      error
+	)
+
+	aID = runContainer(ctx, t, client,
+		cntConfig,
+		&container.HostConfig{},
+		&network.NetworkingConfig{},
+		"a0",
+	)
+
+	bID = runContainer(ctx, t, client,
+		cntConfig,
+		&container.HostConfig{
+			Links: []string{"a0"},
+		},
+		&network.NetworkingConfig{},
+		"b0",
+	)
+
+	err = client.ContainerRename(ctx, aID, "a1")
+	require.NoError(t, err)
+
+	runContainer(ctx, t, client,
+		cntConfig,
+		&container.HostConfig{},
+		&network.NetworkingConfig{},
+		"a0",
+	)
+
+	err = client.ContainerRemove(ctx, bID, types.ContainerRemoveOptions{Force: true})
+	require.NoError(t, err)
+
+	bID = runContainer(ctx, t, client,
+		cntConfig,
+		&container.HostConfig{
+			Links: []string{"a0"},
+		},
+		&network.NetworkingConfig{},
+		"b0",
+	)
+
+	cntJSON, err = client.ContainerInspect(ctx, bID)
+	require.NoError(t, err)
+	assert.Equal(t, []string{"/a0:/b0/a0"}, cntJSON.HostConfig.Links)
+}
diff --git a/integration/doc.go b/integration/doc.go
new file mode 100644
index 0000000..2fdf62e
--- /dev/null
+++ b/integration/doc.go
@@ -0,0 +1,3 @@
+// Package integration provides integrations tests for Moby (API).
+// These tests require a daemon (dockerd for now) to run.
+package integration
diff --git a/integration/service/create_test.go b/integration/service/create_test.go
new file mode 100644
index 0000000..cb0823d
--- /dev/null
+++ b/integration/service/create_test.go
@@ -0,0 +1,129 @@
+package service
+
+import (
+	"testing"
+	"time"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/api/types/swarm"
+	"github.com/docker/docker/client"
+	"github.com/docker/docker/integration-cli/request"
+	"github.com/gotestyourself/gotestyourself/poll"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/net/context"
+)
+
+func TestCreateWithLBSandbox(t *testing.T) {
+	defer setupTest(t)()
+	d := newSwarm(t)
+	defer d.Stop(t)
+	client, err := request.NewClientForHost(d.Sock())
+	require.NoError(t, err)
+
+	overlayName := "overlay1"
+	networkCreate := types.NetworkCreate{
+		CheckDuplicate: true,
+		Driver:         "overlay",
+	}
+
+	netResp, err := client.NetworkCreate(context.Background(), overlayName, networkCreate)
+	require.NoError(t, err)
+	overlayID := netResp.ID
+
+	var instances uint64 = 1
+	serviceSpec := swarmServiceSpec("TestService", instances)
+
+	serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: overlayName})
+
+	serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{
+		QueryRegistry: false,
+	})
+	require.NoError(t, err)
+
+	serviceID := serviceResp.ID
+	poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances))
+
+	_, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{})
+	require.NoError(t, err)
+
+	network, err := client.NetworkInspect(context.Background(), overlayID, types.NetworkInspectOptions{})
+	require.NoError(t, err)
+	assert.Contains(t, network.Containers, overlayName+"-sbox")
+
+	err = client.ServiceRemove(context.Background(), serviceID)
+	require.NoError(t, err)
+
+	poll.WaitOn(t, serviceIsRemoved(client, serviceID))
+	err = client.NetworkRemove(context.Background(), overlayID)
+	require.NoError(t, err)
+
+	poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second))
+}
+
+func swarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec {
+	return swarm.ServiceSpec{
+		Annotations: swarm.Annotations{
+			Name: name,
+		},
+		TaskTemplate: swarm.TaskSpec{
+			ContainerSpec: &swarm.ContainerSpec{
+				Image:   "busybox:latest",
+				Command: []string{"/bin/top"},
+			},
+		},
+		Mode: swarm.ServiceMode{
+			Replicated: &swarm.ReplicatedService{
+				Replicas: &replicas,
+			},
+		},
+	}
+}
+
+func serviceRunningTasksCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result {
+	return func(log poll.LogT) poll.Result {
+		filter := filters.NewArgs()
+		filter.Add("service", serviceID)
+		tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
+			Filters: filter,
+		})
+		switch {
+		case err != nil:
+			return poll.Error(err)
+		case len(tasks) == int(instances):
+			for _, task := range tasks {
+				if task.Status.State != swarm.TaskStateRunning {
+					return poll.Continue("waiting for tasks to enter run state")
+				}
+			}
+			return poll.Success()
+		default:
+			return poll.Continue("task count at %d waiting for %d", len(tasks), instances)
+		}
+	}
+}
+
+func serviceIsRemoved(client client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result {
+	return func(log poll.LogT) poll.Result {
+		filter := filters.NewArgs()
+		filter.Add("service", serviceID)
+		_, err := client.TaskList(context.Background(), types.TaskListOptions{
+			Filters: filter,
+		})
+		if err == nil {
+			return poll.Continue("waiting for service %s to be deleted", serviceID)
+		}
+		return poll.Success()
+	}
+}
+
+func networkIsRemoved(client client.NetworkAPIClient, networkID string) func(log poll.LogT) poll.Result {
+	return func(log poll.LogT) poll.Result {
+		_, err := client.NetworkInspect(context.Background(), networkID, types.NetworkInspectOptions{})
+		if err == nil {
+			return poll.Continue("waiting for network %s to be removed", networkID)
+		}
+		return poll.Success()
+	}
+}
diff --git a/integration/service/inspect_test.go b/integration/service/inspect_test.go
new file mode 100644
index 0000000..61831b7
--- /dev/null
+++ b/integration/service/inspect_test.go
@@ -0,0 +1,148 @@
+package service
+
+import (
+	"fmt"
+	"testing"
+	"time"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/api/types/swarm"
+	"github.com/docker/docker/client"
+	"github.com/docker/docker/integration-cli/daemon"
+	"github.com/docker/docker/integration-cli/request"
+	"github.com/gotestyourself/gotestyourself/poll"
+	"github.com/gotestyourself/gotestyourself/skip"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/net/context"
+)
+
+func TestInspect(t *testing.T) {
+	skip.IfCondition(t, !testEnv.IsLocalDaemon())
+	defer setupTest(t)()
+	d := newSwarm(t)
+	defer d.Stop(t)
+	client, err := request.NewClientForHost(d.Sock())
+	require.NoError(t, err)
+
+	var before = time.Now()
+	var instances uint64 = 2
+	serviceSpec := fullSwarmServiceSpec("test-service-inspect", instances)
+
+	ctx := context.Background()
+	resp, err := client.ServiceCreate(ctx, serviceSpec, types.ServiceCreateOptions{
+		QueryRegistry: false,
+	})
+	require.NoError(t, err)
+
+	id := resp.ID
+	poll.WaitOn(t, serviceContainerCount(client, id, instances))
+
+	service, _, err := client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{})
+	require.NoError(t, err)
+	assert.Equal(t, serviceSpec, service.Spec)
+	assert.Equal(t, uint64(11), service.Meta.Version.Index)
+	assert.Equal(t, id, service.ID)
+	assert.WithinDuration(t, before, service.CreatedAt, 30*time.Second)
+	assert.WithinDuration(t, before, service.UpdatedAt, 30*time.Second)
+}
+
+func fullSwarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec {
+	restartDelay := 100 * time.Millisecond
+	maxAttempts := uint64(4)
+
+	return swarm.ServiceSpec{
+		Annotations: swarm.Annotations{
+			Name: name,
+			Labels: map[string]string{
+				"service-label": "service-label-value",
+			},
+		},
+		TaskTemplate: swarm.TaskSpec{
+			ContainerSpec: &swarm.ContainerSpec{
+				Image:           "busybox:latest",
+				Labels:          map[string]string{"container-label": "container-value"},
+				Command:         []string{"/bin/top"},
+				Args:            []string{"-u", "root"},
+				Hostname:        "hostname",
+				Env:             []string{"envvar=envvalue"},
+				Dir:             "/work",
+				User:            "root",
+				StopSignal:      "SIGINT",
+				StopGracePeriod: &restartDelay,
+				Hosts:           []string{"8.8.8.8  google"},
+				DNSConfig: &swarm.DNSConfig{
+					Nameservers: []string{"8.8.8.8"},
+					Search:      []string{"somedomain"},
+				},
+			},
+			RestartPolicy: &swarm.RestartPolicy{
+				Delay:       &restartDelay,
+				Condition:   swarm.RestartPolicyConditionOnFailure,
+				MaxAttempts: &maxAttempts,
+			},
+			Runtime: swarm.RuntimeContainer,
+		},
+		Mode: swarm.ServiceMode{
+			Replicated: &swarm.ReplicatedService{
+				Replicas: &replicas,
+			},
+		},
+		UpdateConfig: &swarm.UpdateConfig{
+			Parallelism:     2,
+			Delay:           200 * time.Second,
+			FailureAction:   swarm.UpdateFailureActionContinue,
+			Monitor:         2 * time.Second,
+			MaxFailureRatio: 0.2,
+			Order:           swarm.UpdateOrderStopFirst,
+		},
+		RollbackConfig: &swarm.UpdateConfig{
+			Parallelism:     3,
+			Delay:           300 * time.Second,
+			FailureAction:   swarm.UpdateFailureActionPause,
+			Monitor:         3 * time.Second,
+			MaxFailureRatio: 0.3,
+			Order:           swarm.UpdateOrderStartFirst,
+		},
+	}
+}
+
+const defaultSwarmPort = 2477
+
+func newSwarm(t *testing.T) *daemon.Swarm {
+	d := &daemon.Swarm{
+		Daemon: daemon.New(t, "", dockerdBinary, daemon.Config{
+			Experimental: testEnv.DaemonInfo.ExperimentalBuild,
+		}),
+		// TODO: better method of finding an unused port
+		Port: defaultSwarmPort,
+	}
+	// TODO: move to a NewSwarm constructor
+	d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port)
+
+	// avoid networking conflicts
+	args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"}
+	d.StartWithBusybox(t, args...)
+
+	require.NoError(t, d.Init(swarm.InitRequest{}))
+	return d
+}
+
+func serviceContainerCount(client client.ServiceAPIClient, id string, count uint64) func(log poll.LogT) poll.Result {
+	return func(log poll.LogT) poll.Result {
+		filter := filters.NewArgs()
+		filter.Add("service", id)
+		tasks, err := client.TaskList(context.Background(), types.TaskListOptions{
+			Filters: filter,
+		})
+		switch {
+		case err != nil:
+			return poll.Error(err)
+		case len(tasks) == int(count):
+			return poll.Success()
+		default:
+			return poll.Continue("task count at %d waiting for %d", len(tasks), count)
+		}
+	}
+}
diff --git a/integration/service/main_test.go b/integration/service/main_test.go
new file mode 100644
index 0000000..4cad6ed
--- /dev/null
+++ b/integration/service/main_test.go
@@ -0,0 +1,30 @@
+package service
+
+import (
+	"fmt"
+	"os"
+	"testing"
+
+	"github.com/docker/docker/internal/test/environment"
+)
+
+var testEnv *environment.Execution
+
+const dockerdBinary = "dockerd"
+
+func TestMain(m *testing.M) {
+	var err error
+	testEnv, err = environment.New()
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	testEnv.Print()
+	os.Exit(m.Run())
+}
+
+func setupTest(t *testing.T) func() {
+	environment.ProtectAll(t, testEnv)
+	return func() { testEnv.Clean(t) }
+}
diff --git a/integration/system/main_test.go b/integration/system/main_test.go
new file mode 100644
index 0000000..575bbc1
--- /dev/null
+++ b/integration/system/main_test.go
@@ -0,0 +1,28 @@
+package system
+
+import (
+	"fmt"
+	"os"
+	"testing"
+
+	"github.com/docker/docker/internal/test/environment"
+)
+
+var testEnv *environment.Execution
+
+func TestMain(m *testing.M) {
+	var err error
+	testEnv, err = environment.New()
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	testEnv.Print()
+	os.Exit(m.Run())
+}
+
+func setupTest(t *testing.T) func() {
+	environment.ProtectAll(t, testEnv)
+	return func() { testEnv.Clean(t) }
+}
diff --git a/integration/system/version_test.go b/integration/system/version_test.go
new file mode 100644
index 0000000..c1231fd
--- /dev/null
+++ b/integration/system/version_test.go
@@ -0,0 +1,23 @@
+package system
+
+import (
+	"testing"
+
+	"github.com/docker/docker/integration/util/request"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/net/context"
+)
+
+func TestVersion(t *testing.T) {
+	client := request.NewAPIClient(t)
+
+	version, err := client.ServerVersion(context.Background())
+	require.NoError(t, err)
+
+	assert.NotNil(t, version.APIVersion)
+	assert.NotNil(t, version.Version)
+	assert.NotNil(t, version.MinAPIVersion)
+	assert.Equal(t, testEnv.DaemonInfo.ExperimentalBuild, version.Experimental)
+	assert.Equal(t, testEnv.OSType, version.Os)
+}
diff --git a/integration/util/request/client.go b/integration/util/request/client.go
new file mode 100644
index 0000000..7715636
--- /dev/null
+++ b/integration/util/request/client.go
@@ -0,0 +1,15 @@
+package request
+
+import (
+	"testing"
+
+	"github.com/docker/docker/client"
+	"github.com/stretchr/testify/require"
+)
+
+// NewAPIClient returns a docker API client configured from environment variables
+func NewAPIClient(t *testing.T) client.APIClient {
+	clt, err := client.NewEnvClient()
+	require.NoError(t, err)
+	return clt
+}
diff --git a/internal/test/environment/clean.go b/internal/test/environment/clean.go
new file mode 100644
index 0000000..e9548d1
--- /dev/null
+++ b/internal/test/environment/clean.go
@@ -0,0 +1,190 @@
+package environment
+
+import (
+	"regexp"
+	"strings"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
+	"github.com/docker/docker/client"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/net/context"
+)
+
+type testingT interface {
+	require.TestingT
+	logT
+	Fatalf(string, ...interface{})
+}
+
+type logT interface {
+	Logf(string, ...interface{})
+}
+
+// Clean the environment, preserving protected objects (images, containers, ...)
+// and removing everything else. It's meant to run after any tests so that they don't
+// depend on each others.
+func (e *Execution) Clean(t testingT) {
+	client := e.APIClient()
+
+	platform := e.OSType
+	if (platform != "windows") || (platform == "windows" && e.DaemonInfo.Isolation == "hyperv") {
+		unpauseAllContainers(t, client)
+	}
+	deleteAllContainers(t, client, e.protectedElements.containers)
+	deleteAllImages(t, client, e.protectedElements.images)
+	deleteAllVolumes(t, client, e.protectedElements.volumes)
+	deleteAllNetworks(t, client, platform, e.protectedElements.networks)
+	if platform == "linux" {
+		deleteAllPlugins(t, client, e.protectedElements.plugins)
+	}
+}
+
+func unpauseAllContainers(t assert.TestingT, client client.ContainerAPIClient) {
+	ctx := context.Background()
+	containers := getPausedContainers(ctx, t, client)
+	if len(containers) > 0 {
+		for _, container := range containers {
+			err := client.ContainerUnpause(ctx, container.ID)
+			assert.NoError(t, err, "failed to unpause container %s", container.ID)
+		}
+	}
+}
+
+func getPausedContainers(ctx context.Context, t assert.TestingT, client client.ContainerAPIClient) []types.Container {
+	filter := filters.NewArgs()
+	filter.Add("status", "paused")
+	containers, err := client.ContainerList(ctx, types.ContainerListOptions{
+		Filters: filter,
+		Quiet:   true,
+		All:     true,
+	})
+	assert.NoError(t, err, "failed to list containers")
+	return containers
+}
+
+var alreadyExists = regexp.MustCompile(`Error response from daemon: removal of container (\w+) is already in progress`)
+
+func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient, protectedContainers map[string]struct{}) {
+	ctx := context.Background()
+	containers := getAllContainers(ctx, t, apiclient)
+	if len(containers) == 0 {
+		return
+	}
+
+	for _, container := range containers {
+		if _, ok := protectedContainers[container.ID]; ok {
+			continue
+		}
+		err := apiclient.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{
+			Force:         true,
+			RemoveVolumes: true,
+		})
+		if err == nil || client.IsErrNotFound(err) || alreadyExists.MatchString(err.Error()) || isErrNotFoundSwarmClassic(err) {
+			continue
+		}
+		assert.NoError(t, err, "failed to remove %s", container.ID)
+	}
+}
+
+func getAllContainers(ctx context.Context, t assert.TestingT, client client.ContainerAPIClient) []types.Container {
+	containers, err := client.ContainerList(ctx, types.ContainerListOptions{
+		Quiet: true,
+		All:   true,
+	})
+	assert.NoError(t, err, "failed to list containers")
+	return containers
+}
+
+func deleteAllImages(t testingT, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) {
+	images, err := apiclient.ImageList(context.Background(), types.ImageListOptions{})
+	assert.NoError(t, err, "failed to list images")
+
+	ctx := context.Background()
+	for _, image := range images {
+		tags := tagsFromImageSummary(image)
+		if len(tags) == 0 {
+			t.Logf("Removing image %s", image.ID)
+			removeImage(ctx, t, apiclient, image.ID)
+			continue
+		}
+		for _, tag := range tags {
+			if _, ok := protectedImages[tag]; !ok {
+				t.Logf("Removing image %s", tag)
+				removeImage(ctx, t, apiclient, tag)
+				continue
+			}
+		}
+	}
+}
+
+func removeImage(ctx context.Context, t assert.TestingT, apiclient client.ImageAPIClient, ref string) {
+	_, err := apiclient.ImageRemove(ctx, ref, types.ImageRemoveOptions{
+		Force: true,
+	})
+	if client.IsErrNotFound(err) {
+		return
+	}
+	assert.NoError(t, err, "failed to remove image %s", ref)
+}
+
+func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolumes map[string]struct{}) {
+	volumes, err := c.VolumeList(context.Background(), filters.Args{})
+	assert.NoError(t, err, "failed to list volumes")
+
+	for _, v := range volumes.Volumes {
+		if _, ok := protectedVolumes[v.Name]; ok {
+			continue
+		}
+		err := c.VolumeRemove(context.Background(), v.Name, true)
+		// Docker EE may list volumes that no longer exist.
+		if isErrNotFoundSwarmClassic(err) {
+			continue
+		}
+		assert.NoError(t, err, "failed to remove volume %s", v.Name)
+	}
+}
+
+func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string, protectedNetworks map[string]struct{}) {
+	networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{})
+	assert.NoError(t, err, "failed to list networks")
+
+	for _, n := range networks {
+		if n.Name == "bridge" || n.Name == "none" || n.Name == "host" {
+			continue
+		}
+		if _, ok := protectedNetworks[n.ID]; ok {
+			continue
+		}
+		if daemonPlatform == "windows" && strings.ToLower(n.Name) == "nat" {
+			// nat is a pre-defined network on Windows and cannot be removed
+			continue
+		}
+		err := c.NetworkRemove(context.Background(), n.ID)
+		assert.NoError(t, err, "failed to remove network %s", n.ID)
+	}
+}
+
+func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient, protectedPlugins map[string]struct{}) {
+	plugins, err := c.PluginList(context.Background(), filters.Args{})
+	// Docker EE does not allow cluster-wide plugin management.
+	if client.IsErrNotImplemented(err) {
+		return
+	}
+	assert.NoError(t, err, "failed to list plugins")
+
+	for _, p := range plugins {
+		if _, ok := protectedPlugins[p.Name]; ok {
+			continue
+		}
+		err := c.PluginRemove(context.Background(), p.Name, types.PluginRemoveOptions{Force: true})
+		assert.NoError(t, err, "failed to remove plugin %s", p.ID)
+	}
+}
+
+// Swarm classic aggregates node errors and returns a 500 so we need to check
+// the error string instead of just IsErrNotFound().
+func isErrNotFoundSwarmClassic(err error) bool {
+	return err != nil && strings.Contains(strings.ToLower(err.Error()), "no such")
+}
diff --git a/internal/test/environment/environment.go b/internal/test/environment/environment.go
new file mode 100644
index 0000000..eba92b2
--- /dev/null
+++ b/internal/test/environment/environment.go
@@ -0,0 +1,130 @@
+package environment
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/client"
+	"github.com/pkg/errors"
+	"golang.org/x/net/context"
+)
+
+// Execution contains information about the current test execution and daemon
+// under test
+type Execution struct {
+	client            client.APIClient
+	DaemonInfo        types.Info
+	OSType            string
+	PlatformDefaults  PlatformDefaults
+	protectedElements protectedElements
+}
+
+// PlatformDefaults are defaults values for the platform of the daemon under test
+type PlatformDefaults struct {
+	BaseImage            string
+	VolumesConfigPath    string
+	ContainerStoragePath string
+}
+
+// New creates a new Execution struct
+func New() (*Execution, error) {
+	client, err := client.NewEnvClient()
+	if err != nil {
+		return nil, errors.Wrapf(err, "failed to create client")
+	}
+
+	info, err := client.Info(context.Background())
+	if err != nil {
+		return nil, errors.Wrapf(err, "failed to get info from daemon")
+	}
+
+	osType := getOSType(info)
+
+	return &Execution{
+		client:            client,
+		DaemonInfo:        info,
+		OSType:            osType,
+		PlatformDefaults:  getPlatformDefaults(info, osType),
+		protectedElements: newProtectedElements(),
+	}, nil
+}
+
+func getOSType(info types.Info) string {
+	// Docker EE does not set the OSType so allow the user to override this value.
+	userOsType := os.Getenv("TEST_OSTYPE")
+	if userOsType != "" {
+		return userOsType
+	}
+	return info.OSType
+}
+
+func getPlatformDefaults(info types.Info, osType string) PlatformDefaults {
+	volumesPath := filepath.Join(info.DockerRootDir, "volumes")
+	containersPath := filepath.Join(info.DockerRootDir, "containers")
+
+	switch osType {
+	case "linux":
+		return PlatformDefaults{
+			BaseImage:            "scratch",
+			VolumesConfigPath:    toSlash(volumesPath),
+			ContainerStoragePath: toSlash(containersPath),
+		}
+	case "windows":
+		baseImage := "microsoft/windowsservercore"
+		if override := os.Getenv("WINDOWS_BASE_IMAGE"); override != "" {
+			baseImage = override
+			fmt.Println("INFO: Windows Base image is ", baseImage)
+		}
+		return PlatformDefaults{
+			BaseImage:            baseImage,
+			VolumesConfigPath:    filepath.FromSlash(volumesPath),
+			ContainerStoragePath: filepath.FromSlash(containersPath),
+		}
+	default:
+		panic(fmt.Sprintf("unknown OSType for daemon: %s", osType))
+	}
+}
+
+// Make sure in context of daemon, not the local platform. Note we can't
+// use filepath.FromSlash or ToSlash here as they are a no-op on Unix.
+func toSlash(path string) string {
+	return strings.Replace(path, `\`, `/`, -1)
+}
+
+// IsLocalDaemon is true if the daemon under test is on the same
+// host as the CLI.
+//
+// Deterministically working out the environment in which CI is running
+// to evaluate whether the daemon is local or remote is not possible through
+// a build tag.
+//
+// For example Windows to Linux CI under Jenkins tests the 64-bit
+// Windows binary build with the daemon build tag, but calls a remote
+// Linux daemon.
+//
+// We can't just say if Windows then assume the daemon is local as at
+// some point, we will be testing the Windows CLI against a Windows daemon.
+//
+// Similarly, it will be perfectly valid to also run CLI tests from
+// a Linux CLI (built with the daemon tag) against a Windows daemon.
+func (e *Execution) IsLocalDaemon() bool {
+	return os.Getenv("DOCKER_REMOTE_DAEMON") == ""
+}
+
+// Print the execution details to stdout
+// TODO: print everything
+func (e *Execution) Print() {
+	if e.IsLocalDaemon() {
+		fmt.Println("INFO: Testing against a local daemon")
+	} else {
+		fmt.Println("INFO: Testing against a remote daemon")
+	}
+}
+
+// APIClient returns an APIClient connected to the daemon under test
+func (e *Execution) APIClient() client.APIClient {
+	return e.client
+}
diff --git a/internal/test/environment/protect.go b/internal/test/environment/protect.go
new file mode 100644
index 0000000..296ae73
--- /dev/null
+++ b/internal/test/environment/protect.go
@@ -0,0 +1,213 @@
+package environment
+
+import (
+	"context"
+
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/filters"
+	dclient "github.com/docker/docker/client"
+	"github.com/docker/docker/integration-cli/fixtures/load"
+	"github.com/stretchr/testify/require"
+)
+
+type protectedElements struct {
+	containers map[string]struct{}
+	images     map[string]struct{}
+	networks   map[string]struct{}
+	plugins    map[string]struct{}
+	volumes    map[string]struct{}
+}
+
+func newProtectedElements() protectedElements {
+	return protectedElements{
+		containers: map[string]struct{}{},
+		images:     map[string]struct{}{},
+		networks:   map[string]struct{}{},
+		plugins:    map[string]struct{}{},
+		volumes:    map[string]struct{}{},
+	}
+}
+
+// ProtectAll protects the existing environment (containers, images, networks,
+// volumes, and, on Linux, plugins) from being cleaned up at the end of test
+// runs
+func ProtectAll(t testingT, testEnv *Execution) {
+	ProtectContainers(t, testEnv)
+	ProtectImages(t, testEnv)
+	ProtectNetworks(t, testEnv)
+	ProtectVolumes(t, testEnv)
+	if testEnv.OSType == "linux" {
+		ProtectPlugins(t, testEnv)
+	}
+}
+
+// ProtectContainer adds the specified container(s) to be protected in case of
+// clean
+func (e *Execution) ProtectContainer(t testingT, containers ...string) {
+	for _, container := range containers {
+		e.protectedElements.containers[container] = struct{}{}
+	}
+}
+
+// ProtectContainers protects existing containers from being cleaned up at the
+// end of test runs
+func ProtectContainers(t testingT, testEnv *Execution) {
+	containers := getExistingContainers(t, testEnv)
+	testEnv.ProtectContainer(t, containers...)
+}
+
+func getExistingContainers(t require.TestingT, testEnv *Execution) []string {
+	client := testEnv.APIClient()
+	containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{
+		All: true,
+	})
+	require.NoError(t, err, "failed to list containers")
+
+	containers := []string{}
+	for _, container := range containerList {
+		containers = append(containers, container.ID)
+	}
+	return containers
+}
+
+// ProtectImage adds the specified image(s) to be protected in case of clean
+func (e *Execution) ProtectImage(t testingT, images ...string) {
+	for _, image := range images {
+		e.protectedElements.images[image] = struct{}{}
+	}
+}
+
+// ProtectImages protects existing images and on linux frozen images from being
+// cleaned up at the end of test runs
+func ProtectImages(t testingT, testEnv *Execution) {
+	images := getExistingImages(t, testEnv)
+
+	if testEnv.OSType == "linux" {
+		images = append(images, ensureFrozenImagesLinux(t, testEnv)...)
+	}
+	testEnv.ProtectImage(t, images...)
+}
+
+func getExistingImages(t require.TestingT, testEnv *Execution) []string {
+	client := testEnv.APIClient()
+	filter := filters.NewArgs()
+	filter.Add("dangling", "false")
+	imageList, err := client.ImageList(context.Background(), types.ImageListOptions{
+		All:     true,
+		Filters: filter,
+	})
+	require.NoError(t, err, "failed to list images")
+
+	images := []string{}
+	for _, image := range imageList {
+		images = append(images, tagsFromImageSummary(image)...)
+	}
+	return images
+}
+
+func tagsFromImageSummary(image types.ImageSummary) []string {
+	result := []string{}
+	for _, tag := range image.RepoTags {
+		if tag != "<none>:<none>" {
+			result = append(result, tag)
+		}
+	}
+	for _, digest := range image.RepoDigests {
+		if digest != "<none>@<none>" {
+			result = append(result, digest)
+		}
+	}
+	return result
+}
+
+func ensureFrozenImagesLinux(t testingT, testEnv *Execution) []string {
+	images := []string{"busybox:latest", "hello-world:frozen", "debian:jessie"}
+	err := load.FrozenImagesLinux(testEnv.APIClient(), images...)
+	if err != nil {
+		t.Fatalf("Failed to load frozen images: %s", err)
+	}
+	return images
+}
+
+// ProtectNetwork adds the specified network(s) to be protected in case of
+// clean
+func (e *Execution) ProtectNetwork(t testingT, networks ...string) {
+	for _, network := range networks {
+		e.protectedElements.networks[network] = struct{}{}
+	}
+}
+
+// ProtectNetworks protects existing networks from being cleaned up at the end
+// of test runs
+func ProtectNetworks(t testingT, testEnv *Execution) {
+	networks := getExistingNetworks(t, testEnv)
+	testEnv.ProtectNetwork(t, networks...)
+}
+
+func getExistingNetworks(t require.TestingT, testEnv *Execution) []string {
+	client := testEnv.APIClient()
+	networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{})
+	require.NoError(t, err, "failed to list networks")
+
+	networks := []string{}
+	for _, network := range networkList {
+		networks = append(networks, network.ID)
+	}
+	return networks
+}
+
+// ProtectPlugin adds the specified plugin(s) to be protected in case of clean
+func (e *Execution) ProtectPlugin(t testingT, plugins ...string) {
+	for _, plugin := range plugins {
+		e.protectedElements.plugins[plugin] = struct{}{}
+	}
+}
+
+// ProtectPlugins protects existing plugins from being cleaned up at the end of
+// test runs
+func ProtectPlugins(t testingT, testEnv *Execution) {
+	plugins := getExistingPlugins(t, testEnv)
+	testEnv.ProtectPlugin(t, plugins...)
+}
+
+func getExistingPlugins(t require.TestingT, testEnv *Execution) []string {
+	client := testEnv.APIClient()
+	pluginList, err := client.PluginList(context.Background(), filters.Args{})
+	// Docker EE does not allow cluster-wide plugin management.
+	if dclient.IsErrNotImplemented(err) {
+		return []string{}
+	}
+	require.NoError(t, err, "failed to list plugins")
+
+	plugins := []string{}
+	for _, plugin := range pluginList {
+		plugins = append(plugins, plugin.Name)
+	}
+	return plugins
+}
+
+// ProtectVolume adds the specified volume(s) to be protected in case of clean
+func (e *Execution) ProtectVolume(t testingT, volumes ...string) {
+	for _, volume := range volumes {
+		e.protectedElements.volumes[volume] = struct{}{}
+	}
+}
+
+// ProtectVolumes protects existing volumes from being cleaned up at the end of
+// test runs
+func ProtectVolumes(t testingT, testEnv *Execution) {
+	volumes := getExistingVolumes(t, testEnv)
+	testEnv.ProtectVolume(t, volumes...)
+}
+
+func getExistingVolumes(t require.TestingT, testEnv *Execution) []string {
+	client := testEnv.APIClient()
+	volumeList, err := client.VolumeList(context.Background(), filters.Args{})
+	require.NoError(t, err, "failed to list volumes")
+
+	volumes := []string{}
+	for _, volume := range volumeList.Volumes {
+		volumes = append(volumes, volume.Name)
+	}
+	return volumes
+}
diff --git a/internal/testutil/helpers.go b/internal/testutil/helpers.go
new file mode 100644
index 0000000..a760569
--- /dev/null
+++ b/internal/testutil/helpers.go
@@ -0,0 +1,13 @@
+package testutil
+
+import (
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+// ErrorContains checks that the error is not nil, and contains the expected
+// substring.
+func ErrorContains(t require.TestingT, err error, expectedError string, msgAndArgs ...interface{}) {
+	require.Error(t, err, msgAndArgs...)
+	assert.Contains(t, err.Error(), expectedError, msgAndArgs...)
+}
diff --git a/layer/empty_test.go b/layer/empty_test.go
index 5555dbd..abafc23 100644
--- a/layer/empty_test.go
+++ b/layer/empty_test.go
@@ -28,6 +28,12 @@
 		t.Fatal("expected zero diffsize for empty layer")
 	}
 
+	meta, err := EmptyLayer.Metadata()
+
+	if len(meta) != 0 || err != nil {
+		t.Fatal("expected zero length metadata for empty layer")
+	}
+
 	tarStream, err := EmptyLayer.TarStream()
 	if err != nil {
 		t.Fatalf("error streaming tar for empty layer: %v", err)
diff --git a/layer/filestore.go b/layer/filestore.go
index 533f454..d813555 100644
--- a/layer/filestore.go
+++ b/layer/filestore.go
@@ -13,10 +13,10 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/layer/layer.go b/layer/layer.go
index b3480a0..4ff159e 100644
--- a/layer/layer.go
+++ b/layer/layer.go
@@ -13,10 +13,11 @@
 	"errors"
 	"io"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -137,7 +138,7 @@
 
 	// Mount mounts the RWLayer and returns the filesystem path
 	// the to the writable layer.
-	Mount(mountLabel string) (string, error)
+	Mount(mountLabel string) (containerfs.ContainerFS, error)
 
 	// Unmount unmounts the RWLayer. This should be called
 	// for every mount. If there are multiple mount calls
@@ -178,7 +179,7 @@
 // writable mount. Changes made here will
 // not be included in the Tar stream of the
 // RWLayer.
-type MountInit func(root string) error
+type MountInit func(root containerfs.ContainerFS) error
 
 // CreateRWLayerOpts contains optional arguments to be passed to CreateRWLayer
 type CreateRWLayerOpts struct {
diff --git a/layer/layer_store.go b/layer/layer_store.go
index 75ac1e4..c3973ce 100644
--- a/layer/layer_store.go
+++ b/layer/layer_store.go
@@ -8,7 +8,6 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/pkg/idtools"
@@ -16,6 +15,7 @@
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/system"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 	"github.com/vbatts/tar-split/tar/asm"
 	"github.com/vbatts/tar-split/tar/storage"
 )
@@ -749,5 +749,5 @@
 	if err != nil {
 		return nil, err
 	}
-	return &fileGetPutter{storage.NewPathFileGetter(p), n.Driver, id}, nil
+	return &fileGetPutter{storage.NewPathFileGetter(p.Path()), n.Driver, id}, nil
 }
diff --git a/layer/layer_test.go b/layer/layer_test.go
index 8ec5b4d..5839ac3 100644
--- a/layer/layer_test.go
+++ b/layer/layer_test.go
@@ -10,9 +10,11 @@
 	"strings"
 	"testing"
 
+	"github.com/containerd/continuity/driver"
 	"github.com/docker/docker/daemon/graphdriver"
 	"github.com/docker/docker/daemon/graphdriver/vfs"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/opencontainers/go-digest"
@@ -82,7 +84,7 @@
 	}
 }
 
-type layerInit func(root string) error
+type layerInit func(root containerfs.ContainerFS) error
 
 func createLayer(ls Store, parent ChainID, layerFunc layerInit) (Layer, error) {
 	containerID := stringid.GenerateRandomID()
@@ -91,12 +93,12 @@
 		return nil, err
 	}
 
-	path, err := mount.Mount("")
+	pathFS, err := mount.Mount("")
 	if err != nil {
 		return nil, err
 	}
 
-	if err := layerFunc(path); err != nil {
+	if err := layerFunc(pathFS); err != nil {
 		return nil, err
 	}
 
@@ -123,7 +125,7 @@
 }
 
 type FileApplier interface {
-	ApplyFile(root string) error
+	ApplyFile(root containerfs.ContainerFS) error
 }
 
 type testFile struct {
@@ -140,25 +142,25 @@
 	}
 }
 
-func (tf *testFile) ApplyFile(root string) error {
-	fullPath := filepath.Join(root, tf.name)
-	if err := os.MkdirAll(filepath.Dir(fullPath), 0755); err != nil {
+func (tf *testFile) ApplyFile(root containerfs.ContainerFS) error {
+	fullPath := root.Join(root.Path(), tf.name)
+	if err := root.MkdirAll(root.Dir(fullPath), 0755); err != nil {
 		return err
 	}
 	// Check if already exists
-	if stat, err := os.Stat(fullPath); err == nil && stat.Mode().Perm() != tf.permission {
-		if err := os.Chmod(fullPath, tf.permission); err != nil {
+	if stat, err := root.Stat(fullPath); err == nil && stat.Mode().Perm() != tf.permission {
+		if err := root.Lchmod(fullPath, tf.permission); err != nil {
 			return err
 		}
 	}
-	if err := ioutil.WriteFile(fullPath, tf.content, tf.permission); err != nil {
+	if err := driver.WriteFile(root, fullPath, tf.content, tf.permission); err != nil {
 		return err
 	}
 	return nil
 }
 
 func initWithFiles(files ...FileApplier) layerInit {
-	return func(root string) error {
+	return func(root containerfs.ContainerFS) error {
 		for _, f := range files {
 			if err := f.ApplyFile(root); err != nil {
 				return err
@@ -288,7 +290,7 @@
 		t.Fatal(err)
 	}
 
-	b, err := ioutil.ReadFile(filepath.Join(path2, "testfile.txt"))
+	b, err := driver.ReadFile(path2, path2.Join(path2.Path(), "testfile.txt"))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -391,12 +393,12 @@
 		t.Fatal(err)
 	}
 
-	path, err := m.Mount("")
+	pathFS, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(path, "testfile.txt"), []byte("nothing here"), 0644); err != nil {
+	if err := driver.WriteFile(pathFS, pathFS.Join(pathFS.Path(), "testfile.txt"), []byte("nothing here"), 0644); err != nil {
 		t.Fatal(err)
 	}
 
@@ -430,20 +432,20 @@
 
 	if mountPath, err := m2.Mount(""); err != nil {
 		t.Fatal(err)
-	} else if path != mountPath {
-		t.Fatalf("Unexpected path %s, expected %s", mountPath, path)
+	} else if pathFS.Path() != mountPath.Path() {
+		t.Fatalf("Unexpected path %s, expected %s", mountPath.Path(), pathFS.Path())
 	}
 
 	if mountPath, err := m2.Mount(""); err != nil {
 		t.Fatal(err)
-	} else if path != mountPath {
-		t.Fatalf("Unexpected path %s, expected %s", mountPath, path)
+	} else if pathFS.Path() != mountPath.Path() {
+		t.Fatalf("Unexpected path %s, expected %s", mountPath.Path(), pathFS.Path())
 	}
 	if err := m2.Unmount(); err != nil {
 		t.Fatal(err)
 	}
 
-	b, err := ioutil.ReadFile(filepath.Join(path, "testfile.txt"))
+	b, err := driver.ReadFile(pathFS, pathFS.Join(pathFS.Path(), "testfile.txt"))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -618,7 +620,7 @@
 	defer os.RemoveAll(td)
 
 	for _, f := range files {
-		if err := f.ApplyFile(td); err != nil {
+		if err := f.ApplyFile(containerfs.NewLocalContainerFS(td)); err != nil {
 			return nil, err
 		}
 	}
diff --git a/layer/layer_windows.go b/layer/layer_windows.go
index a1c1953..d02d4d0 100644
--- a/layer/layer_windows.go
+++ b/layer/layer_windows.go
@@ -1,6 +1,15 @@
 package layer
 
-import "errors"
+import (
+	"errors"
+)
+
+// Getter is an interface to get the path to a layer on the host.
+type Getter interface {
+	// GetLayerPath gets the path for the layer. This is different from Get()
+	// since that returns an interface to account for umountable layers.
+	GetLayerPath(id string) (string, error)
+}
 
 // GetLayerPath returns the path to a layer
 func GetLayerPath(s Store, layer ChainID) (string, error) {
@@ -16,6 +25,10 @@
 		return "", ErrLayerDoesNotExist
 	}
 
+	if layerGetter, ok := ls.driver.(Getter); ok {
+		return layerGetter.GetLayerPath(rl.cacheID)
+	}
+
 	path, err := ls.driver.Get(rl.cacheID, "")
 	if err != nil {
 		return "", err
@@ -25,7 +38,7 @@
 		return "", err
 	}
 
-	return path, nil
+	return path.Path(), nil
 }
 
 func (ls *layerStore) mountID(name string) string {
diff --git a/layer/migration.go b/layer/migration.go
index 4803a1a..f4c4ade 100644
--- a/layer/migration.go
+++ b/layer/migration.go
@@ -7,8 +7,8 @@
 	"io"
 	"os"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 	"github.com/vbatts/tar-split/tar/asm"
 	"github.com/vbatts/tar-split/tar/storage"
 )
diff --git a/layer/mount_test.go b/layer/mount_test.go
index f5799e7..44d461f 100644
--- a/layer/mount_test.go
+++ b/layer/mount_test.go
@@ -2,13 +2,13 @@
 
 import (
 	"io/ioutil"
-	"os"
-	"path/filepath"
 	"runtime"
 	"sort"
 	"testing"
 
+	"github.com/containerd/continuity/driver"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 )
 
 func TestMountInit(t *testing.T) {
@@ -28,7 +28,7 @@
 		t.Fatal(err)
 	}
 
-	mountInit := func(root string) error {
+	mountInit := func(root containerfs.ContainerFS) error {
 		return initfile.ApplyFile(root)
 	}
 
@@ -40,22 +40,22 @@
 		t.Fatal(err)
 	}
 
-	path, err := m.Mount("")
+	pathFS, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	f, err := os.Open(filepath.Join(path, "testfile.txt"))
+	fi, err := pathFS.Stat(pathFS.Join(pathFS.Path(), "testfile.txt"))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	f, err := pathFS.Open(pathFS.Join(pathFS.Path(), "testfile.txt"))
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer f.Close()
 
-	fi, err := f.Stat()
-	if err != nil {
-		t.Fatal(err)
-	}
-
 	b, err := ioutil.ReadAll(f)
 	if err != nil {
 		t.Fatal(err)
@@ -88,7 +88,7 @@
 		t.Fatal(err)
 	}
 
-	mountInit := func(root string) error {
+	mountInit := func(root containerfs.ContainerFS) error {
 		return newTestFile("file-init", contentInit, 0777).ApplyFile(root)
 	}
 	rwLayerOpts := &CreateRWLayerOpts{
@@ -100,12 +100,12 @@
 		t.Fatal(err)
 	}
 
-	path, err := m.Mount("")
+	pathFS, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(path, "file2"), content2, 0755); err != nil {
+	if err := driver.WriteFile(pathFS, pathFS.Join(pathFS.Path(), "file2"), content2, 0755); err != nil {
 		t.Fatal(err)
 	}
 
@@ -140,7 +140,7 @@
 		t.Fatal(err)
 	}
 
-	mountInit := func(root string) error {
+	mountInit := func(root containerfs.ContainerFS) error {
 		return initfile.ApplyFile(root)
 	}
 	rwLayerOpts := &CreateRWLayerOpts{
@@ -152,28 +152,28 @@
 		t.Fatal(err)
 	}
 
-	path, err := m.Mount("")
+	pathFS, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if err := os.Chmod(filepath.Join(path, "testfile1.txt"), 0755); err != nil {
+	if err := pathFS.Lchmod(pathFS.Join(pathFS.Path(), "testfile1.txt"), 0755); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(path, "testfile1.txt"), []byte("mount data!"), 0755); err != nil {
+	if err := driver.WriteFile(pathFS, pathFS.Join(pathFS.Path(), "testfile1.txt"), []byte("mount data!"), 0755); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := os.Remove(filepath.Join(path, "testfile2.txt")); err != nil {
+	if err := pathFS.Remove(pathFS.Join(pathFS.Path(), "testfile2.txt")); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := os.Chmod(filepath.Join(path, "testfile3.txt"), 0755); err != nil {
+	if err := pathFS.Lchmod(pathFS.Join(pathFS.Path(), "testfile3.txt"), 0755); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ioutil.WriteFile(filepath.Join(path, "testfile4.txt"), []byte("mount data!"), 0644); err != nil {
+	if err := driver.WriteFile(pathFS, pathFS.Join(pathFS.Path(), "testfile4.txt"), []byte("mount data!"), 0644); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/layer/mounted_layer.go b/layer/mounted_layer.go
index a5cfcfa..47ef966 100644
--- a/layer/mounted_layer.go
+++ b/layer/mounted_layer.go
@@ -4,6 +4,7 @@
 	"io"
 
 	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/containerfs"
 )
 
 type mountedLayer struct {
@@ -88,7 +89,7 @@
 	*mountedLayer
 }
 
-func (rl *referencedRWLayer) Mount(mountLabel string) (string, error) {
+func (rl *referencedRWLayer) Mount(mountLabel string) (containerfs.ContainerFS, error) {
 	return rl.layerStore.driver.Get(rl.mountedLayer.mountID, mountLabel)
 }
 
diff --git a/libcontainerd/client_linux.go b/libcontainerd/client_linux.go
index 54eaf35..12808fd 100644
--- a/libcontainerd/client_linux.go
+++ b/libcontainerd/client_linux.go
@@ -7,7 +7,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	containerd "github.com/containerd/containerd/api/grpc/types"
 	containerd_runtime_types "github.com/containerd/containerd/runtime"
 	"github.com/docker/docker/pkg/ioutils"
@@ -15,6 +14,7 @@
 	"github.com/golang/protobuf/ptypes"
 	"github.com/golang/protobuf/ptypes/timestamp"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/sys/unix"
 )
@@ -296,10 +296,7 @@
 		Pid:       InitFriendlyName,
 		Resources: (*containerd.UpdateResource)(&resources),
 	})
-	if err != nil {
-		return err
-	}
-	return nil
+	return err
 }
 
 func (clnt *client) getExitNotifier(containerID string) *exitNotifier {
diff --git a/libcontainerd/client_solaris.go b/libcontainerd/client_solaris.go
index cb93997..c54cea3 100644
--- a/libcontainerd/client_solaris.go
+++ b/libcontainerd/client_solaris.go
@@ -1,6 +1,9 @@
 package libcontainerd
 
-import "golang.org/x/net/context"
+import (
+	containerd "github.com/containerd/containerd/api/grpc/types"
+	"golang.org/x/net/context"
+)
 
 type client struct {
 	clientCommon
diff --git a/libcontainerd/client_unix.go b/libcontainerd/client_unix.go
index 6dbf3af..202a5b0 100644
--- a/libcontainerd/client_unix.go
+++ b/libcontainerd/client_unix.go
@@ -10,10 +10,10 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	containerd "github.com/containerd/containerd/api/grpc/types"
 	"github.com/docker/docker/pkg/idtools"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -50,7 +50,7 @@
 		return fmt.Errorf("Container %s is already active", containerID)
 	}
 
-	uid, gid, err := getRootIDs(specs.Spec(spec))
+	uid, gid, err := getRootIDs(spec)
 	if err != nil {
 		return err
 	}
diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go
index 455e8e5..df9e40e 100644
--- a/libcontainerd/client_windows.go
+++ b/libcontainerd/client_windows.go
@@ -7,7 +7,9 @@
 	"io"
 	"io/ioutil"
 	"os"
+	"path"
 	"path/filepath"
+	"regexp"
 	"strings"
 	"syscall"
 	"time"
@@ -15,9 +17,11 @@
 	"golang.org/x/net/context"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
+	opengcs "github.com/Microsoft/opengcs/client"
 	"github.com/docker/docker/pkg/sysinfo"
+	"github.com/docker/docker/pkg/system"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 )
 
 type client struct {
@@ -100,8 +104,11 @@
 	if b, err := json.Marshal(spec); err == nil {
 		logrus.Debugln("libcontainerd: client.Create() with spec", string(b))
 	}
-	osName := spec.Platform.OS
-	if osName == "windows" {
+
+	// spec.Linux must be nil for Windows containers, but spec.Windows will be filled in regardless of container platform.
+	// This is a temporary workaround due to LCOW requiring layer folder paths, which are stored under spec.Windows.
+	// TODO: @darrenstahlmsft fix this once the OCI spec is updated to support layer folder paths for LCOW
+	if spec.Linux == nil {
 		return clnt.createWindows(containerID, checkpoint, checkpointDir, spec, attachStdio, options...)
 	}
 	return clnt.createLinux(containerID, checkpoint, checkpointDir, spec, attachStdio, options...)
@@ -112,9 +119,10 @@
 		SystemType: "Container",
 		Name:       containerID,
 		Owner:      defaultOwner,
-		IgnoreFlushesDuringBoot: false,
+		IgnoreFlushesDuringBoot: spec.Windows.IgnoreFlushesDuringBoot,
 		HostName:                spec.Hostname,
 		HvPartition:             false,
+		Servicing:               spec.Windows.Servicing,
 	}
 
 	if spec.Windows.Resources != nil {
@@ -153,49 +161,43 @@
 		}
 	}
 
-	var layerOpt *LayerOption
-	for _, option := range options {
-		if s, ok := option.(*ServicingOption); ok {
-			configuration.Servicing = s.IsServicing
-			continue
-		}
-		if f, ok := option.(*FlushOption); ok {
-			configuration.IgnoreFlushesDuringBoot = f.IgnoreFlushesDuringBoot
-			continue
-		}
-		if h, ok := option.(*HyperVIsolationOption); ok {
-			configuration.HvPartition = h.IsHyperV
-			continue
-		}
-		if l, ok := option.(*LayerOption); ok {
-			layerOpt = l
-		}
-		if n, ok := option.(*NetworkEndpointsOption); ok {
-			configuration.EndpointList = n.Endpoints
-			configuration.AllowUnqualifiedDNSQuery = n.AllowUnqualifiedDNSQuery
-			if n.DNSSearchList != nil {
-				configuration.DNSSearchList = strings.Join(n.DNSSearchList, ",")
-			}
-			configuration.NetworkSharedContainerName = n.NetworkSharedContainerID
-			continue
-		}
-		if c, ok := option.(*CredentialsOption); ok {
-			configuration.Credentials = c.Credentials
-			continue
-		}
+	if spec.Windows.HyperV != nil {
+		configuration.HvPartition = true
 	}
 
-	// We must have a layer option with at least one path
-	if layerOpt == nil || layerOpt.LayerPaths == nil {
-		return fmt.Errorf("no layer option or paths were supplied to the runtime")
+	if spec.Windows.Network != nil {
+		configuration.EndpointList = spec.Windows.Network.EndpointList
+		configuration.AllowUnqualifiedDNSQuery = spec.Windows.Network.AllowUnqualifiedDNSQuery
+		if spec.Windows.Network.DNSSearchList != nil {
+			configuration.DNSSearchList = strings.Join(spec.Windows.Network.DNSSearchList, ",")
+		}
+		configuration.NetworkSharedContainerName = spec.Windows.Network.NetworkSharedContainerName
 	}
 
+	if cs, ok := spec.Windows.CredentialSpec.(string); ok {
+		configuration.Credentials = cs
+	}
+
+	// We must have least two layers in the spec, the bottom one being a base image,
+	// the top one being the RW layer.
+	if spec.Windows.LayerFolders == nil || len(spec.Windows.LayerFolders) < 2 {
+		return fmt.Errorf("OCI spec is invalid - at least two LayerFolders must be supplied to the runtime")
+	}
+
+	// Strip off the top-most layer as that's passed in separately to HCS
+	configuration.LayerFolderPath = spec.Windows.LayerFolders[len(spec.Windows.LayerFolders)-1]
+	layerFolders := spec.Windows.LayerFolders[:len(spec.Windows.LayerFolders)-1]
+
 	if configuration.HvPartition {
-		// Find the upper-most utility VM image, since the utility VM does not
-		// use layering in RS1.
-		// TODO @swernli/jhowardmsft at some point post RS1 this may be re-locatable.
+		// We don't currently support setting the utility VM image explicitly.
+		// TODO @swernli/jhowardmsft circa RS3/4, this may be re-locatable.
+		if spec.Windows.HyperV.UtilityVMPath != "" {
+			return errors.New("runtime does not support an explicit utility VM path for Hyper-V containers")
+		}
+
+		// Find the upper-most utility VM image.
 		var uvmImagePath string
-		for _, path := range layerOpt.LayerPaths {
+		for _, path := range layerFolders {
 			fullPath := filepath.Join(path, "UtilityVM")
 			_, err := os.Stat(fullPath)
 			if err == nil {
@@ -210,13 +212,24 @@
 			return errors.New("utility VM image could not be found")
 		}
 		configuration.HvRuntime = &hcsshim.HvRuntime{ImagePath: uvmImagePath}
+
+		if spec.Root.Path != "" {
+			return errors.New("OCI spec is invalid - Root.Path must be omitted for a Hyper-V container")
+		}
 	} else {
-		configuration.VolumePath = spec.Root.Path
+		const volumeGUIDRegex = `^\\\\\?\\(Volume)\{{0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}\}\\$`
+		if _, err := regexp.MatchString(volumeGUIDRegex, spec.Root.Path); err != nil {
+			return fmt.Errorf(`OCI spec is invalid - Root.Path '%s' must be a volume GUID path in the format '\\?\Volume{GUID}\'`, spec.Root.Path)
+		}
+		// HCS API requires the trailing backslash to be removed
+		configuration.VolumePath = spec.Root.Path[:len(spec.Root.Path)-1]
 	}
 
-	configuration.LayerFolderPath = layerOpt.LayerFolderPath
+	if spec.Root.Readonly {
+		return errors.New(`OCI spec is invalid - Root.Readonly must not be set on Windows`)
+	}
 
-	for _, layerPath := range layerOpt.LayerPaths {
+	for _, layerPath := range layerFolders {
 		_, filename := filepath.Split(layerPath)
 		g, err := hcsshim.NameToGuid(filename)
 		if err != nil {
@@ -229,20 +242,38 @@
 	}
 
 	// Add the mounts (volumes, bind mounts etc) to the structure
-	mds := make([]hcsshim.MappedDir, len(spec.Mounts))
-	for i, mount := range spec.Mounts {
-		mds[i] = hcsshim.MappedDir{
-			HostPath:      mount.Source,
-			ContainerPath: mount.Destination,
-			ReadOnly:      false,
+	var mds []hcsshim.MappedDir
+	var mps []hcsshim.MappedPipe
+	for _, mount := range spec.Mounts {
+		const pipePrefix = `\\.\pipe\`
+		if mount.Type != "" {
+			return fmt.Errorf("OCI spec is invalid - Mount.Type '%s' must not be set", mount.Type)
 		}
-		for _, o := range mount.Options {
-			if strings.ToLower(o) == "ro" {
-				mds[i].ReadOnly = true
+		if strings.HasPrefix(mount.Destination, pipePrefix) {
+			mp := hcsshim.MappedPipe{
+				HostPath:          mount.Source,
+				ContainerPipeName: mount.Destination[len(pipePrefix):],
 			}
+			mps = append(mps, mp)
+		} else {
+			md := hcsshim.MappedDir{
+				HostPath:      mount.Source,
+				ContainerPath: mount.Destination,
+				ReadOnly:      false,
+			}
+			for _, o := range mount.Options {
+				if strings.ToLower(o) == "ro" {
+					md.ReadOnly = true
+				}
+			}
+			mds = append(mds, md)
 		}
 	}
 	configuration.MappedDirectories = mds
+	if len(mps) > 0 && system.GetOSVersion().Build < 16210 { // replace with Win10 RS3 build number at RTM
+		return errors.New("named pipe mounts are not supported on this version of Windows")
+	}
+	configuration.MappedPipes = mps
 
 	hcsContainer, err := hcsshim.CreateContainer(containerID, configuration)
 	if err != nil {
@@ -261,6 +292,7 @@
 			},
 			processes: make(map[string]*process),
 		},
+		isWindows:    true,
 		ociSpec:      spec,
 		hcsContainer: hcsContainer,
 	}
@@ -289,8 +321,16 @@
 func (clnt *client) createLinux(containerID string, checkpoint string, checkpointDir string, spec specs.Spec, attachStdio StdioCallback, options ...CreateOption) error {
 	logrus.Debugf("libcontainerd: createLinux(): containerId %s ", containerID)
 
-	// TODO @jhowardmsft LCOW Support: This needs to be configurable, not hard-coded.
-	// However, good-enough for the LCOW bring-up.
+	var lcowOpt *LCOWOption
+	for _, option := range options {
+		if lcow, ok := option.(*LCOWOption); ok {
+			lcowOpt = lcow
+		}
+	}
+	if lcowOpt == nil || lcowOpt.Config == nil {
+		return fmt.Errorf("lcow option must be supplied to the runtime")
+	}
+
 	configuration := &hcsshim.ContainerConfig{
 		HvPartition:   true,
 		Name:          containerID,
@@ -298,28 +338,37 @@
 		ContainerType: "linux",
 		Owner:         defaultOwner,
 		TerminateOnLastHandleClosed: true,
-		HvRuntime: &hcsshim.HvRuntime{
-			ImagePath:       `c:\Program Files\Linux Containers`,
-			LinuxKernelFile: `bootx64.efi`,
-			LinuxInitrdFile: `initrd.img`,
-		},
 	}
 
-	var layerOpt *LayerOption
-	for _, option := range options {
-		if l, ok := option.(*LayerOption); ok {
-			layerOpt = l
+	if lcowOpt.Config.ActualMode == opengcs.ModeActualVhdx {
+		configuration.HvRuntime = &hcsshim.HvRuntime{
+			ImagePath:          lcowOpt.Config.Vhdx,
+			BootSource:         "Vhd",
+			WritableBootSource: false,
+		}
+	} else {
+		configuration.HvRuntime = &hcsshim.HvRuntime{
+			ImagePath:           lcowOpt.Config.KirdPath,
+			LinuxKernelFile:     lcowOpt.Config.KernelFile,
+			LinuxInitrdFile:     lcowOpt.Config.InitrdFile,
+			LinuxBootParameters: lcowOpt.Config.BootParameters,
 		}
 	}
 
-	// We must have a layer option with at least one path
-	if layerOpt == nil || layerOpt.LayerPaths == nil {
-		return fmt.Errorf("no layer option or paths were supplied to the runtime")
+	if spec.Windows == nil {
+		return fmt.Errorf("spec.Windows must not be nil for LCOW containers")
 	}
 
-	// LayerFolderPath (writeable layer) + Layers (Guid + path)
-	configuration.LayerFolderPath = layerOpt.LayerFolderPath
-	for _, layerPath := range layerOpt.LayerPaths {
+	// We must have least one layer in the spec
+	if spec.Windows.LayerFolders == nil || len(spec.Windows.LayerFolders) == 0 {
+		return fmt.Errorf("OCI spec is invalid - at least one LayerFolders must be supplied to the runtime")
+	}
+
+	// Strip off the top-most layer as that's passed in separately to HCS
+	configuration.LayerFolderPath = spec.Windows.LayerFolders[len(spec.Windows.LayerFolders)-1]
+	layerFolders := spec.Windows.LayerFolders[:len(spec.Windows.LayerFolders)-1]
+
+	for _, layerPath := range layerFolders {
 		_, filename := filepath.Split(layerPath)
 		g, err := hcsshim.NameToGuid(filename)
 		if err != nil {
@@ -331,23 +380,110 @@
 		})
 	}
 
-	for _, option := range options {
-		if n, ok := option.(*NetworkEndpointsOption); ok {
-			configuration.EndpointList = n.Endpoints
-			configuration.AllowUnqualifiedDNSQuery = n.AllowUnqualifiedDNSQuery
-			if n.DNSSearchList != nil {
-				configuration.DNSSearchList = strings.Join(n.DNSSearchList, ",")
-			}
-			configuration.NetworkSharedContainerName = n.NetworkSharedContainerID
-			break
+	if spec.Windows.Network != nil {
+		configuration.EndpointList = spec.Windows.Network.EndpointList
+		configuration.AllowUnqualifiedDNSQuery = spec.Windows.Network.AllowUnqualifiedDNSQuery
+		if spec.Windows.Network.DNSSearchList != nil {
+			configuration.DNSSearchList = strings.Join(spec.Windows.Network.DNSSearchList, ",")
 		}
+		configuration.NetworkSharedContainerName = spec.Windows.Network.NetworkSharedContainerName
 	}
 
+	// Add the mounts (volumes, bind mounts etc) to the structure. We have to do
+	// some translation for both the mapped directories passed into HCS and in
+	// the spec.
+	//
+	// For HCS, we only pass in the mounts from the spec which are type "bind".
+	// Further, the "ContainerPath" field (which is a little mis-leadingly
+	// named when it applies to the utility VM rather than the container in the
+	// utility VM) is moved to under /tmp/gcs/<ID>/binds, where this is passed
+	// by the caller through a 'uvmpath' option.
+	//
+	// We do similar translation for the mounts in the spec by stripping out
+	// the uvmpath option, and translating the Source path to the location in the
+	// utility VM calculated above.
+	//
+	// From inside the utility VM, you would see a 9p mount such as in the following
+	// where a host folder has been mapped to /target. The line with /tmp/gcs/<ID>/binds
+	// specifically:
+	//
+	//	/ # mount
+	//	rootfs on / type rootfs (rw,size=463736k,nr_inodes=115934)
+	//	proc on /proc type proc (rw,relatime)
+	//	sysfs on /sys type sysfs (rw,relatime)
+	//	udev on /dev type devtmpfs (rw,relatime,size=498100k,nr_inodes=124525,mode=755)
+	//	tmpfs on /run type tmpfs (rw,relatime)
+	//	cgroup on /sys/fs/cgroup type cgroup (rw,relatime,cpuset,cpu,cpuacct,blkio,memory,devices,freezer,net_cls,perf_event,net_prio,hugetlb,pids,rdma)
+	//	mqueue on /dev/mqueue type mqueue (rw,relatime)
+	//	devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)
+	//	/binds/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/target on /binds/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/target type 9p (rw,sync,dirsync,relatime,trans=fd,rfdno=6,wfdno=6)
+	//	/dev/pmem0 on /tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/layer0 type ext4 (ro,relatime,block_validity,delalloc,norecovery,barrier,dax,user_xattr,acl)
+	//	/dev/sda on /tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/scratch type ext4 (rw,relatime,block_validity,delalloc,barrier,user_xattr,acl)
+	//	overlay on /tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/rootfs type overlay (rw,relatime,lowerdir=/tmp/base/:/tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/layer0,upperdir=/tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/scratch/upper,workdir=/tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc/scratch/work)
+	//
+	//  /tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc # ls -l
+	//	total 16
+	//	drwx------    3 0        0               60 Sep  7 18:54 binds
+	//	-rw-r--r--    1 0        0             3345 Sep  7 18:54 config.json
+	//	drwxr-xr-x   10 0        0             4096 Sep  6 17:26 layer0
+	//	drwxr-xr-x    1 0        0             4096 Sep  7 18:54 rootfs
+	//	drwxr-xr-x    5 0        0             4096 Sep  7 18:54 scratch
+	//
+	//	/tmp/gcs/b3ea9126d67702173647ece2744f7c11181c0150e9890fc9a431849838033edc # ls -l binds
+	//	total 0
+	//	drwxrwxrwt    2 0        0             4096 Sep  7 16:51 target
+
+	mds := []hcsshim.MappedDir{}
+	specMounts := []specs.Mount{}
+	for _, mount := range spec.Mounts {
+		specMount := mount
+		if mount.Type == "bind" {
+			// Strip out the uvmpath from the options
+			updatedOptions := []string{}
+			uvmPath := ""
+			readonly := false
+			for _, opt := range mount.Options {
+				dropOption := false
+				elements := strings.SplitN(opt, "=", 2)
+				switch elements[0] {
+				case "uvmpath":
+					uvmPath = elements[1]
+					dropOption = true
+				case "rw":
+				case "ro":
+					readonly = true
+				case "rbind":
+				default:
+					return fmt.Errorf("unsupported option %q", opt)
+				}
+				if !dropOption {
+					updatedOptions = append(updatedOptions, opt)
+				}
+			}
+			mount.Options = updatedOptions
+			if uvmPath == "" {
+				return fmt.Errorf("no uvmpath for bind mount %+v", mount)
+			}
+			md := hcsshim.MappedDir{
+				HostPath:          mount.Source,
+				ContainerPath:     path.Join(uvmPath, mount.Destination),
+				CreateInUtilityVM: true,
+				ReadOnly:          readonly,
+			}
+			mds = append(mds, md)
+			specMount.Source = path.Join(uvmPath, mount.Destination)
+		}
+		specMounts = append(specMounts, specMount)
+	}
+	configuration.MappedDirectories = mds
+
 	hcsContainer, err := hcsshim.CreateContainer(containerID, configuration)
 	if err != nil {
 		return err
 	}
 
+	spec.Mounts = specMounts
+
 	// Construct a container object for calling start on it.
 	container := &container{
 		containerCommon: containerCommon{
@@ -394,6 +530,9 @@
 	if err != nil {
 		return -1, err
 	}
+
+	defer container.debugGCS()
+
 	// Note we always tell HCS to
 	// create stdout as it's required regardless of '-i' or '-t' options, so that
 	// docker can always grab the output through logs. We also tell HCS to always
@@ -406,8 +545,10 @@
 	}
 	if procToAdd.Terminal {
 		createProcessParms.EmulateConsole = true
-		createProcessParms.ConsoleSize[0] = uint(procToAdd.ConsoleSize.Height)
-		createProcessParms.ConsoleSize[1] = uint(procToAdd.ConsoleSize.Width)
+		if procToAdd.ConsoleSize != nil {
+			createProcessParms.ConsoleSize[0] = uint(procToAdd.ConsoleSize.Height)
+			createProcessParms.ConsoleSize[1] = uint(procToAdd.ConsoleSize.Width)
+		}
 	}
 
 	// Take working directory from the process to add if it is defined,
@@ -420,7 +561,7 @@
 
 	// Configure the environment for the process
 	createProcessParms.Environment = setupEnvironmentVariables(procToAdd.Env)
-	if container.ociSpec.Platform.OS == "windows" {
+	if container.isWindows {
 		createProcessParms.CommandLine = strings.Join(procToAdd.Args, " ")
 	} else {
 		createProcessParms.CommandArgs = procToAdd.Args
@@ -584,13 +725,8 @@
 		return err
 	}
 
-	for _, option := range container.options {
-		if h, ok := option.(*HyperVIsolationOption); ok {
-			if !h.IsHyperV {
-				return errors.New("cannot pause Windows Server Containers")
-			}
-			break
-		}
+	if container.ociSpec.Windows.HyperV == nil {
+		return errors.New("cannot pause Windows Server Containers")
 	}
 
 	err = container.hcsContainer.Pause()
@@ -624,13 +760,9 @@
 	}
 
 	// This should never happen, since Windows Server Containers cannot be paused
-	for _, option := range container.options {
-		if h, ok := option.(*HyperVIsolationOption); ok {
-			if !h.IsHyperV {
-				return errors.New("cannot resume Windows Server Containers")
-			}
-			break
-		}
+
+	if container.ociSpec.Windows.HyperV == nil {
+		return errors.New("cannot resume Windows Server Containers")
 	}
 
 	err = container.hcsContainer.Resume()
diff --git a/libcontainerd/container_unix.go b/libcontainerd/container_unix.go
index 869f885..9a7dbf0 100644
--- a/libcontainerd/container_unix.go
+++ b/libcontainerd/container_unix.go
@@ -11,10 +11,10 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	containerd "github.com/containerd/containerd/api/grpc/types"
 	"github.com/docker/docker/pkg/ioutils"
 	specs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 	"github.com/tonistiigi/fifo"
 	"golang.org/x/net/context"
 	"golang.org/x/sys/unix"
diff --git a/libcontainerd/container_windows.go b/libcontainerd/container_windows.go
index e895fa0..73fc6bd 100644
--- a/libcontainerd/container_windows.go
+++ b/libcontainerd/container_windows.go
@@ -9,9 +9,8 @@
 	"time"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/pkg/system"
 	"github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/windows"
 )
 
@@ -26,6 +25,7 @@
 	// otherwise have access to the Spec
 	ociSpec specs.Spec
 
+	isWindows           bool
 	manualStopRequested bool
 	hcsContainer        hcsshim.Container
 }
@@ -44,19 +44,13 @@
 // Caller needs to lock container ID before calling this method.
 func (ctr *container) start(attachStdio StdioCallback) error {
 	var err error
-	isServicing := false
-
-	for _, option := range ctr.options {
-		if s, ok := option.(*ServicingOption); ok && s.IsServicing {
-			isServicing = true
-		}
-	}
 
 	// Start the container.  If this is a servicing container, this call will block
 	// until the container is done with the servicing execution.
 	logrus.Debugln("libcontainerd: starting container ", ctr.containerID)
 	if err = ctr.hcsContainer.Start(); err != nil {
 		logrus.Errorf("libcontainerd: failed to start container: %s", err)
+		ctr.debugGCS() // Before terminating!
 		if err := ctr.terminate(); err != nil {
 			logrus.Errorf("libcontainerd: failed to cleanup after a failed Start. %s", err)
 		} else {
@@ -65,24 +59,38 @@
 		return err
 	}
 
+	defer ctr.debugGCS()
+
 	// Note we always tell HCS to
 	// create stdout as it's required regardless of '-i' or '-t' options, so that
 	// docker can always grab the output through logs. We also tell HCS to always
 	// create stdin, even if it's not used - it will be closed shortly. Stderr
 	// is only created if it we're not -t.
-	createProcessParms := &hcsshim.ProcessConfig{
-		EmulateConsole:   ctr.ociSpec.Process.Terminal,
-		WorkingDirectory: ctr.ociSpec.Process.Cwd,
-		CreateStdInPipe:  !isServicing,
-		CreateStdOutPipe: !isServicing,
-		CreateStdErrPipe: !ctr.ociSpec.Process.Terminal && !isServicing,
+	var (
+		emulateConsole   bool
+		createStdErrPipe bool
+	)
+	if ctr.ociSpec.Process != nil {
+		emulateConsole = ctr.ociSpec.Process.Terminal
+		createStdErrPipe = !ctr.ociSpec.Process.Terminal && !ctr.ociSpec.Windows.Servicing
 	}
-	createProcessParms.ConsoleSize[0] = uint(ctr.ociSpec.Process.ConsoleSize.Height)
-	createProcessParms.ConsoleSize[1] = uint(ctr.ociSpec.Process.ConsoleSize.Width)
+
+	createProcessParms := &hcsshim.ProcessConfig{
+		EmulateConsole:   emulateConsole,
+		WorkingDirectory: ctr.ociSpec.Process.Cwd,
+		CreateStdInPipe:  !ctr.ociSpec.Windows.Servicing,
+		CreateStdOutPipe: !ctr.ociSpec.Windows.Servicing,
+		CreateStdErrPipe: createStdErrPipe,
+	}
+
+	if ctr.ociSpec.Process != nil && ctr.ociSpec.Process.ConsoleSize != nil {
+		createProcessParms.ConsoleSize[0] = uint(ctr.ociSpec.Process.ConsoleSize.Height)
+		createProcessParms.ConsoleSize[1] = uint(ctr.ociSpec.Process.ConsoleSize.Width)
+	}
 
 	// Configure the environment for the process
 	createProcessParms.Environment = setupEnvironmentVariables(ctr.ociSpec.Process.Env)
-	if ctr.ociSpec.Platform.OS == "windows" {
+	if ctr.isWindows {
 		createProcessParms.CommandLine = strings.Join(ctr.ociSpec.Process.Args, " ")
 	} else {
 		createProcessParms.CommandArgs = ctr.ociSpec.Process.Args
@@ -90,7 +98,7 @@
 	createProcessParms.User = ctr.ociSpec.Process.User.Username
 
 	// LCOW requires the raw OCI spec passed through HCS and onwards to GCS for the utility VM.
-	if system.LCOWSupported() && ctr.ociSpec.Platform.OS == "linux" {
+	if !ctr.isWindows {
 		ociBuf, err := json.Marshal(ctr.ociSpec)
 		if err != nil {
 			return err
@@ -119,7 +127,7 @@
 
 	// If this is a servicing container, wait on the process synchronously here and
 	// if it succeeds, wait for it cleanly shutdown and merge into the parent container.
-	if isServicing {
+	if ctr.ociSpec.Windows.Servicing {
 		exitCode := ctr.waitProcessExitCode(&ctr.process)
 
 		if exitCode != 0 {
@@ -245,7 +253,7 @@
 		si.State = StateExitProcess
 	} else {
 		// Pending updates is only applicable for WCOW
-		if ctr.ociSpec.Platform.OS == "windows" {
+		if ctr.isWindows {
 			updatePending, err := ctr.hcsContainer.HasPendingUpdates()
 			if err != nil {
 				logrus.Warnf("libcontainerd: HasPendingUpdates() failed (container may have been killed): %s", err)
diff --git a/libcontainerd/oom_linux.go b/libcontainerd/oom_linux.go
index e126b7a..70f0dac 100644
--- a/libcontainerd/oom_linux.go
+++ b/libcontainerd/oom_linux.go
@@ -5,8 +5,8 @@
 	"os"
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/opencontainers/runc/libcontainer/system"
+	"github.com/sirupsen/logrus"
 )
 
 func setOOMScore(pid, score int) error {
diff --git a/libcontainerd/remote_unix.go b/libcontainerd/remote_unix.go
index 24fbc5a..7bab53e 100644
--- a/libcontainerd/remote_unix.go
+++ b/libcontainerd/remote_unix.go
@@ -17,12 +17,12 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	containerd "github.com/containerd/containerd/api/grpc/types"
 	"github.com/docker/docker/pkg/locker"
 	"github.com/docker/docker/pkg/system"
 	"github.com/golang/protobuf/ptypes"
 	"github.com/golang/protobuf/ptypes/timestamp"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/sys/unix"
 	"google.golang.org/grpc"
diff --git a/libcontainerd/types_linux.go b/libcontainerd/types_linux.go
index 4f06358..f21a85e 100644
--- a/libcontainerd/types_linux.go
+++ b/libcontainerd/types_linux.go
@@ -21,7 +21,7 @@
 	// Capabilities are linux capabilities that are kept for the container.
 	Capabilities []string `json:"capabilities,omitempty"`
 	// Rlimits specifies rlimit options to apply to the process.
-	Rlimits []specs.LinuxRlimit `json:"rlimits,omitempty"`
+	Rlimits []specs.POSIXRlimit `json:"rlimits,omitempty"`
 	// ApparmorProfile specifies the apparmor profile for the container.
 	ApparmorProfile *string `json:"apparmorProfile,omitempty"`
 	// SelinuxLabel specifies the selinux context that the container process is run as.
diff --git a/libcontainerd/types_windows.go b/libcontainerd/types_windows.go
index 317bfb0..f271ecd 100644
--- a/libcontainerd/types_windows.go
+++ b/libcontainerd/types_windows.go
@@ -2,6 +2,7 @@
 
 import (
 	"github.com/Microsoft/hcsshim"
+	opengcs "github.com/Microsoft/opengcs/client"
 	"github.com/opencontainers/runtime-spec/specs-go"
 )
 
@@ -25,47 +26,9 @@
 // Resources defines updatable container resource values.
 type Resources struct{}
 
-// ServicingOption is a CreateOption with a no-op application that signifies
-// the container needs to be used for a Windows servicing operation.
-type ServicingOption struct {
-	IsServicing bool
-}
-
-// FlushOption is a CreateOption that signifies if the container should be
-// started with flushes ignored until boot has completed. This is an optimisation
-// for first boot of a container.
-type FlushOption struct {
-	IgnoreFlushesDuringBoot bool
-}
-
-// HyperVIsolationOption is a CreateOption that indicates whether the runtime
-// should start the container as a Hyper-V container.
-type HyperVIsolationOption struct {
-	IsHyperV bool
-}
-
-// LayerOption is a CreateOption that indicates to the runtime the layer folder
-// and layer paths for a container.
-type LayerOption struct {
-	// LayerFolderPath is the path to the current layer folder. Empty for Hyper-V containers.
-	LayerFolderPath string `json:",omitempty"`
-	// Layer paths of the parent layers
-	LayerPaths []string
-}
-
-// NetworkEndpointsOption is a CreateOption that provides the runtime list
-// of network endpoints to which a container should be attached during its creation.
-type NetworkEndpointsOption struct {
-	Endpoints                []string
-	AllowUnqualifiedDNSQuery bool
-	DNSSearchList            []string
-	NetworkSharedContainerID string
-}
-
-// CredentialsOption is a CreateOption that indicates the credentials from
-// a credential spec to be used to the runtime
-type CredentialsOption struct {
-	Credentials string
+// LCOWOption is a CreateOption required for LCOW configuration
+type LCOWOption struct {
+	Config *opengcs.Config
 }
 
 // Checkpoint holds the details of a checkpoint (not supported in windows)
diff --git a/libcontainerd/utils_linux.go b/libcontainerd/utils_linux.go
index 170f90b..5372b88 100644
--- a/libcontainerd/utils_linux.go
+++ b/libcontainerd/utils_linux.go
@@ -43,7 +43,7 @@
 	return pid
 }
 
-func convertRlimits(sr []specs.LinuxRlimit) (cr []*containerd.Rlimit) {
+func convertRlimits(sr []specs.POSIXRlimit) (cr []*containerd.Rlimit) {
 	for _, r := range sr {
 		cr = append(cr, &containerd.Rlimit{
 			Type: r.Type,
diff --git a/libcontainerd/utils_windows.go b/libcontainerd/utils_windows.go
index 41ac40d..bca9fa2 100644
--- a/libcontainerd/utils_windows.go
+++ b/libcontainerd/utils_windows.go
@@ -1,6 +1,10 @@
 package libcontainerd
 
-import "strings"
+import (
+	"strings"
+
+	opengcs "github.com/Microsoft/opengcs/client"
+)
 
 // setupEnvironmentVariables converts a string array of environment variables
 // into a map as required by the HCS. Source array is in format [v1=k1] [v2=k2] etc.
@@ -15,32 +19,20 @@
 	return r
 }
 
-// Apply for a servicing option is a no-op.
-func (s *ServicingOption) Apply(interface{}) error {
+// Apply for the LCOW option is a no-op.
+func (s *LCOWOption) Apply(interface{}) error {
 	return nil
 }
 
-// Apply for the flush option is a no-op.
-func (f *FlushOption) Apply(interface{}) error {
-	return nil
-}
-
-// Apply for the hypervisolation option is a no-op.
-func (h *HyperVIsolationOption) Apply(interface{}) error {
-	return nil
-}
-
-// Apply for the layer option is a no-op.
-func (h *LayerOption) Apply(interface{}) error {
-	return nil
-}
-
-// Apply for the network endpoints option is a no-op.
-func (s *NetworkEndpointsOption) Apply(interface{}) error {
-	return nil
-}
-
-// Apply for the credentials option is a no-op.
-func (s *CredentialsOption) Apply(interface{}) error {
-	return nil
+// debugGCS is a dirty hack for debugging for Linux Utility VMs. It simply
+// runs a bunch of commands inside the UVM, but seriously aides in advanced debugging.
+func (c *container) debugGCS() {
+	if c == nil || c.isWindows || c.hcsContainer == nil {
+		return
+	}
+	cfg := opengcs.Config{
+		Uvm:               c.hcsContainer,
+		UvmTimeoutSeconds: 600,
+	}
+	cfg.DebugGCS()
 }
diff --git a/migrate/v1/migratev1.go b/migrate/v1/migratev1.go
index 3cb8828..60dbfe0 100644
--- a/migrate/v1/migratev1.go
+++ b/migrate/v1/migratev1.go
@@ -13,7 +13,6 @@
 
 	"encoding/json"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/distribution/metadata"
 	"github.com/docker/docker/image"
@@ -22,6 +21,7 @@
 	"github.com/docker/docker/pkg/ioutils"
 	refstore "github.com/docker/docker/reference"
 	"github.com/opencontainers/go-digest"
+	"github.com/sirupsen/logrus"
 )
 
 type graphIDRegistrar interface {
diff --git a/oci/defaults.go b/oci/defaults.go
index 083726e..d706faf 100644
--- a/oci/defaults.go
+++ b/oci/defaults.go
@@ -50,11 +50,9 @@
 func DefaultWindowsSpec() specs.Spec {
 	return specs.Spec{
 		Version: specs.Version,
-		Platform: specs.Platform{
-			OS:   runtime.GOOS,
-			Arch: runtime.GOARCH,
-		},
 		Windows: &specs.Windows{},
+		Process: &specs.Process{},
+		Root:    &specs.Root{},
 	}
 }
 
@@ -62,10 +60,6 @@
 func DefaultSolarisSpec() specs.Spec {
 	s := specs.Spec{
 		Version: "0.6.0",
-		Platform: specs.Platform{
-			OS:   "SunOS",
-			Arch: runtime.GOARCH,
-		},
 	}
 	s.Solaris = &specs.Solaris{}
 	return s
@@ -75,10 +69,8 @@
 func DefaultLinuxSpec() specs.Spec {
 	s := specs.Spec{
 		Version: specs.Version,
-		Platform: specs.Platform{
-			OS:   "linux",
-			Arch: runtime.GOARCH,
-		},
+		Process: &specs.Process{},
+		Root:    &specs.Root{},
 	}
 	s.Mounts = []specs.Mount{
 		{
@@ -117,12 +109,20 @@
 			Source:      "mqueue",
 			Options:     []string{"nosuid", "noexec", "nodev"},
 		},
+		{
+			Destination: "/dev/shm",
+			Type:        "tmpfs",
+			Source:      "shm",
+			Options:     []string{"nosuid", "noexec", "nodev", "mode=1777"},
+		},
 	}
-	s.Process.Capabilities = &specs.LinuxCapabilities{
-		Bounding:    defaultCapabilities(),
-		Permitted:   defaultCapabilities(),
-		Inheritable: defaultCapabilities(),
-		Effective:   defaultCapabilities(),
+	s.Process = &specs.Process{
+		Capabilities: &specs.LinuxCapabilities{
+			Bounding:    defaultCapabilities(),
+			Permitted:   defaultCapabilities(),
+			Inheritable: defaultCapabilities(),
+			Effective:   defaultCapabilities(),
+		},
 	}
 
 	s.Linux = &specs.Linux{
@@ -150,7 +150,7 @@
 		},
 		// Devices implicitly contains the following devices:
 		// null, zero, full, random, urandom, tty, console, and ptmx.
-		// ptmx is a bind-mount or symlink of the container's ptmx.
+		// ptmx is a bind mount or symlink of the container's ptmx.
 		// See also: https://github.com/opencontainers/runtime-spec/blob/master/config-linux.md#default-devices
 		Devices: []specs.LinuxDevice{},
 		Resources: &specs.LinuxResources{
@@ -212,6 +212,11 @@
 		},
 	}
 
+	// For LCOW support, populate a blank Windows spec
+	if runtime.GOOS == "windows" {
+		s.Windows = &specs.Windows{}
+	}
+
 	// For LCOW support, don't mask /sys/firmware
 	if runtime.GOOS != "windows" {
 		s.Linux.MaskedPaths = append(s.Linux.MaskedPaths, "/sys/firmware")
diff --git a/opts/env.go b/opts/env.go
index e6ddd73..4fbd470 100644
--- a/opts/env.go
+++ b/opts/env.go
@@ -5,6 +5,8 @@
 	"os"
 	"runtime"
 	"strings"
+
+	"github.com/pkg/errors"
 )
 
 // ValidateEnv validates an environment variable and returns it.
@@ -18,7 +20,7 @@
 func ValidateEnv(val string) (string, error) {
 	arr := strings.Split(val, "=")
 	if arr[0] == "" {
-		return "", fmt.Errorf("invalid environment variable: %s", val)
+		return "", errors.Errorf("invalid environment variable: %s", val)
 	}
 	if len(arr) > 1 {
 		return val, nil
diff --git a/opts/env_test.go b/opts/env_test.go
index 6f6c7a7..454e989 100644
--- a/opts/env_test.go
+++ b/opts/env_test.go
@@ -8,35 +8,117 @@
 )
 
 func TestValidateEnv(t *testing.T) {
-	valids := map[string]string{
-		"a":                   "a",
-		"something":           "something",
-		"_=a":                 "_=a",
-		"env1=value1":         "env1=value1",
-		"_env1=value1":        "_env1=value1",
-		"env2=value2=value3":  "env2=value2=value3",
-		"env3=abc!qwe":        "env3=abc!qwe",
-		"env_4=value 4":       "env_4=value 4",
-		"PATH":                fmt.Sprintf("PATH=%v", os.Getenv("PATH")),
-		"PATH=something":      "PATH=something",
-		"asd!qwe":             "asd!qwe",
-		"1asd":                "1asd",
-		"123":                 "123",
-		"some space":          "some space",
-		"  some space before": "  some space before",
-		"some space after  ":  "some space after  ",
+	testcase := []struct {
+		value    string
+		expected string
+		err      error
+	}{
+		{
+			value:    "a",
+			expected: "a",
+		},
+		{
+			value:    "something",
+			expected: "something",
+		},
+		{
+			value:    "_=a",
+			expected: "_=a",
+		},
+		{
+			value:    "env1=value1",
+			expected: "env1=value1",
+		},
+		{
+			value:    "_env1=value1",
+			expected: "_env1=value1",
+		},
+		{
+			value:    "env2=value2=value3",
+			expected: "env2=value2=value3",
+		},
+		{
+			value:    "env3=abc!qwe",
+			expected: "env3=abc!qwe",
+		},
+		{
+			value:    "env_4=value 4",
+			expected: "env_4=value 4",
+		},
+		{
+			value:    "PATH",
+			expected: fmt.Sprintf("PATH=%v", os.Getenv("PATH")),
+		},
+		{
+			value: "=a",
+			err:   fmt.Errorf(fmt.Sprintf("invalid environment variable: %s", "=a")),
+		},
+		{
+			value:    "PATH=something",
+			expected: "PATH=something",
+		},
+		{
+			value:    "asd!qwe",
+			expected: "asd!qwe",
+		},
+		{
+			value:    "1asd",
+			expected: "1asd",
+		},
+		{
+			value:    "123",
+			expected: "123",
+		},
+		{
+			value:    "some space",
+			expected: "some space",
+		},
+		{
+			value:    "  some space before",
+			expected: "  some space before",
+		},
+		{
+			value:    "some space after  ",
+			expected: "some space after  ",
+		},
+		{
+			value: "=",
+			err:   fmt.Errorf(fmt.Sprintf("invalid environment variable: %s", "=")),
+		},
 	}
+
 	// Environment variables are case in-sensitive on Windows
 	if runtime.GOOS == "windows" {
-		valids["PaTh"] = fmt.Sprintf("PaTh=%v", os.Getenv("PATH"))
-	}
-	for value, expected := range valids {
-		actual, err := ValidateEnv(value)
-		if err != nil {
-			t.Fatal(err)
+		tmp := struct {
+			value    string
+			expected string
+			err      error
+		}{
+			value:    "PaTh",
+			expected: fmt.Sprintf("PaTh=%v", os.Getenv("PATH")),
 		}
-		if actual != expected {
-			t.Fatalf("Expected [%v], got [%v]", expected, actual)
+		testcase = append(testcase, tmp)
+
+	}
+
+	for _, r := range testcase {
+		actual, err := ValidateEnv(r.value)
+
+		if err != nil {
+			if r.err == nil {
+				t.Fatalf("Expected err is nil, got err[%v]", err)
+			}
+			if err.Error() != r.err.Error() {
+				t.Fatalf("Expected err[%v], got err[%v]", r.err, err)
+			}
+		}
+
+		if err == nil && r.err != nil {
+			t.Fatalf("Expected err[%v], but err is nil", r.err)
+		}
+
+		if actual != r.expected {
+			t.Fatalf("Expected [%v], got [%v]", r.expected, actual)
 		}
 	}
 }
diff --git a/opts/opts.go b/opts/opts.go
index 300fb42..a86d74d 100644
--- a/opts/opts.go
+++ b/opts/opts.go
@@ -7,10 +7,7 @@
 	"regexp"
 	"strings"
 
-	"github.com/docker/docker/api/types/swarm"
-	"github.com/docker/docker/daemon/cluster/convert"
 	units "github.com/docker/go-units"
-	"github.com/docker/swarmkit/api/genericresource"
 )
 
 var (
@@ -180,7 +177,7 @@
 }
 
 func (opts *MapOpts) String() string {
-	return fmt.Sprintf("%v", map[string]string((opts.values)))
+	return fmt.Sprintf("%v", opts.values)
 }
 
 // Type returns a string name for this Option type
@@ -328,19 +325,3 @@
 	*m = MemBytes(val)
 	return err
 }
-
-// ParseGenericResources parses and validates the specified string as a list of GenericResource
-func ParseGenericResources(value string) ([]swarm.GenericResource, error) {
-	if value == "" {
-		return nil, nil
-	}
-
-	resources, err := genericresource.Parse(value)
-	if err != nil {
-		return nil, err
-	}
-
-	obj := convert.GenericResourcesFromGRPC(resources)
-
-	return obj, nil
-}
diff --git a/opts/quotedstring.go b/opts/quotedstring.go
index fb1e537..09c68a5 100644
--- a/opts/quotedstring.go
+++ b/opts/quotedstring.go
@@ -18,7 +18,7 @@
 }
 
 func (s *QuotedString) String() string {
-	return string(*s.value)
+	return *s.value
 }
 
 func trimQuotes(value string) string {
diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go
index 6cbc2e2..aa55637 100644
--- a/pkg/archive/archive.go
+++ b/pkg/archive/archive.go
@@ -16,13 +16,12 @@
 	"strings"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/fileutils"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/pools"
-	"github.com/docker/docker/pkg/promise"
 	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
 )
 
 type (
@@ -55,18 +54,17 @@
 	}
 )
 
-// Archiver allows the reuse of most utility functions of this package
-// with a pluggable Untar function. Also, to facilitate the passing of
-// specific id mappings for untar, an archiver can be created with maps
-// which will then be passed to Untar operations
+// Archiver implements the Archiver interface and allows the reuse of most utility functions of
+// this package with a pluggable Untar function. Also, to facilitate the passing of specific id
+// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations.
 type Archiver struct {
-	Untar      func(io.Reader, string, *TarOptions) error
-	IDMappings *idtools.IDMappings
+	Untar         func(io.Reader, string, *TarOptions) error
+	IDMappingsVar *idtools.IDMappings
 }
 
 // NewDefaultArchiver returns a new Archiver without any IDMappings
 func NewDefaultArchiver() *Archiver {
-	return &Archiver{Untar: Untar, IDMappings: &idtools.IDMappings{}}
+	return &Archiver{Untar: Untar, IDMappingsVar: &idtools.IDMappings{}}
 }
 
 // breakoutError is used to differentiate errors related to breaking out
@@ -382,6 +380,7 @@
 	// for hardlink mapping
 	SeenFiles  map[uint64]string
 	IDMappings *idtools.IDMappings
+	ChownOpts  *idtools.IDPair
 
 	// For packing and unpacking whiteout files in the
 	// non standard format. The whiteout files defined
@@ -390,12 +389,13 @@
 	WhiteoutConverter tarWhiteoutConverter
 }
 
-func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer) *tarAppender {
+func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer, chownOpts *idtools.IDPair) *tarAppender {
 	return &tarAppender{
 		SeenFiles:  make(map[uint64]string),
 		TarWriter:  tar.NewWriter(writer),
 		Buffer:     pools.BufioWriter32KPool.Get(nil),
 		IDMappings: idMapping,
+		ChownOpts:  chownOpts,
 	}
 }
 
@@ -470,6 +470,12 @@
 		}
 	}
 
+	// explicitly override with ChownOpts
+	if ta.ChownOpts != nil {
+		hdr.Uid = ta.ChownOpts.UID
+		hdr.Gid = ta.ChownOpts.GID
+	}
+
 	if ta.WhiteoutConverter != nil {
 		wo, err := ta.WhiteoutConverter.ConvertWrite(hdr, path, fi)
 		if err != nil {
@@ -595,7 +601,7 @@
 		return nil
 
 	default:
-		return fmt.Errorf("Unhandled tar header type %d\n", hdr.Typeflag)
+		return fmt.Errorf("unhandled tar header type %d", hdr.Typeflag)
 	}
 
 	// Lchown is not supported on Windows.
@@ -692,6 +698,7 @@
 		ta := newTarAppender(
 			idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps),
 			compressWriter,
+			options.ChownOpts,
 		)
 		ta.WhiteoutConverter = getWhiteoutConverter(options.WhiteoutFormat)
 
@@ -1016,8 +1023,8 @@
 	}
 	defer archive.Close()
 	options := &TarOptions{
-		UIDMaps: archiver.IDMappings.UIDs(),
-		GIDMaps: archiver.IDMappings.GIDs(),
+		UIDMaps: archiver.IDMappingsVar.UIDs(),
+		GIDMaps: archiver.IDMappingsVar.GIDs(),
 	}
 	return archiver.Untar(archive, dst, options)
 }
@@ -1030,8 +1037,8 @@
 	}
 	defer archive.Close()
 	options := &TarOptions{
-		UIDMaps: archiver.IDMappings.UIDs(),
-		GIDMaps: archiver.IDMappings.GIDs(),
+		UIDMaps: archiver.IDMappingsVar.UIDs(),
+		GIDMaps: archiver.IDMappingsVar.GIDs(),
 	}
 	return archiver.Untar(archive, dst, options)
 }
@@ -1049,10 +1056,10 @@
 		return archiver.CopyFileWithTar(src, dst)
 	}
 
-	// if this archiver is set up with ID mapping we need to create
+	// if this Archiver is set up with ID mapping we need to create
 	// the new destination directory with the remapped root UID/GID pair
 	// as owner
-	rootIDs := archiver.IDMappings.RootPair()
+	rootIDs := archiver.IDMappingsVar.RootPair()
 	// Create dst, copy src's content into it
 	logrus.Debugf("Creating dest directory: %s", dst)
 	if err := idtools.MkdirAllAndChownNew(dst, 0755, rootIDs); err != nil {
@@ -1087,36 +1094,42 @@
 	}
 
 	r, w := io.Pipe()
-	errC := promise.Go(func() error {
-		defer w.Close()
+	errC := make(chan error, 1)
 
-		srcF, err := os.Open(src)
-		if err != nil {
-			return err
-		}
-		defer srcF.Close()
+	go func() {
+		defer close(errC)
 
-		hdr, err := tar.FileInfoHeader(srcSt, "")
-		if err != nil {
-			return err
-		}
-		hdr.Name = filepath.Base(dst)
-		hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
+		errC <- func() error {
+			defer w.Close()
 
-		if err := remapIDs(archiver.IDMappings, hdr); err != nil {
-			return err
-		}
+			srcF, err := os.Open(src)
+			if err != nil {
+				return err
+			}
+			defer srcF.Close()
 
-		tw := tar.NewWriter(w)
-		defer tw.Close()
-		if err := tw.WriteHeader(hdr); err != nil {
-			return err
-		}
-		if _, err := io.Copy(tw, srcF); err != nil {
-			return err
-		}
-		return nil
-	})
+			hdr, err := tar.FileInfoHeader(srcSt, "")
+			if err != nil {
+				return err
+			}
+			hdr.Name = filepath.Base(dst)
+			hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
+
+			if err := remapIDs(archiver.IDMappingsVar, hdr); err != nil {
+				return err
+			}
+
+			tw := tar.NewWriter(w)
+			defer tw.Close()
+			if err := tw.WriteHeader(hdr); err != nil {
+				return err
+			}
+			if _, err := io.Copy(tw, srcF); err != nil {
+				return err
+			}
+			return nil
+		}()
+	}()
 	defer func() {
 		if er := <-errC; err == nil && er != nil {
 			err = er
@@ -1130,6 +1143,11 @@
 	return err
 }
 
+// IDMappings returns the IDMappings of the archiver.
+func (archiver *Archiver) IDMappings() *idtools.IDMappings {
+	return archiver.IDMappingsVar
+}
+
 func remapIDs(idMappings *idtools.IDMappings, hdr *tar.Header) error {
 	ids, err := idMappings.ToHost(idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid})
 	hdr.Uid, hdr.Gid = ids.UID, ids.GID
diff --git a/pkg/archive/archive_linux_test.go b/pkg/archive/archive_linux_test.go
index f219b3e..da683c8 100644
--- a/pkg/archive/archive_linux_test.go
+++ b/pkg/archive/archive_linux_test.go
@@ -8,6 +8,7 @@
 	"testing"
 
 	"github.com/docker/docker/pkg/system"
+	"github.com/stretchr/testify/require"
 	"golang.org/x/sys/unix"
 )
 
@@ -22,46 +23,37 @@
 //     └── f1 # whiteout, 0644
 func setupOverlayTestDir(t *testing.T, src string) {
 	// Create opaque directory containing single file and permission 0700
-	if err := os.Mkdir(filepath.Join(src, "d1"), 0700); err != nil {
-		t.Fatal(err)
-	}
+	err := os.Mkdir(filepath.Join(src, "d1"), 0700)
+	require.NoError(t, err)
 
-	if err := system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0); err != nil {
-		t.Fatal(err)
-	}
+	err = system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0)
+	require.NoError(t, err)
 
-	if err := ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600)
+	require.NoError(t, err)
 
 	// Create another opaque directory containing single file but with permission 0750
-	if err := os.Mkdir(filepath.Join(src, "d2"), 0750); err != nil {
-		t.Fatal(err)
-	}
+	err = os.Mkdir(filepath.Join(src, "d2"), 0750)
+	require.NoError(t, err)
 
-	if err := system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0); err != nil {
-		t.Fatal(err)
-	}
+	err = system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0)
+	require.NoError(t, err)
 
-	if err := ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660)
+	require.NoError(t, err)
 
 	// Create regular directory with deleted file
-	if err := os.Mkdir(filepath.Join(src, "d3"), 0700); err != nil {
-		t.Fatal(err)
-	}
+	err = os.Mkdir(filepath.Join(src, "d3"), 0700)
+	require.NoError(t, err)
 
-	if err := system.Mknod(filepath.Join(src, "d3", "f1"), unix.S_IFCHR, 0); err != nil {
-		t.Fatal(err)
-	}
+	err = system.Mknod(filepath.Join(src, "d3", "f1"), unix.S_IFCHR, 0)
+	require.NoError(t, err)
 }
 
 func checkOpaqueness(t *testing.T, path string, opaque string) {
 	xattrOpaque, err := system.Lgetxattr(path, "trusted.overlay.opaque")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	if string(xattrOpaque) != opaque {
 		t.Fatalf("Unexpected opaque value: %q, expected %q", string(xattrOpaque), opaque)
 	}
@@ -70,9 +62,8 @@
 
 func checkOverlayWhiteout(t *testing.T, path string) {
 	stat, err := os.Stat(path)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	statT, ok := stat.Sys().(*syscall.Stat_t)
 	if !ok {
 		t.Fatalf("Unexpected type: %t, expected *syscall.Stat_t", stat.Sys())
@@ -84,9 +75,8 @@
 
 func checkFileMode(t *testing.T, path string, perm os.FileMode) {
 	stat, err := os.Stat(path)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	if stat.Mode() != perm {
 		t.Fatalf("Unexpected file mode for %s: %o, expected %o", path, stat.Mode(), perm)
 	}
@@ -94,23 +84,17 @@
 
 func TestOverlayTarUntar(t *testing.T) {
 	oldmask, err := system.Umask(0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer system.Umask(oldmask)
 
 	src, err := ioutil.TempDir("", "docker-test-overlay-tar-src")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(src)
 
 	setupOverlayTestDir(t, src)
 
 	dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(dst)
 
 	options := &TarOptions{
@@ -118,14 +102,11 @@
 		WhiteoutFormat: OverlayWhiteoutFormat,
 	}
 	archive, err := TarWithOptions(src, options)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer archive.Close()
 
-	if err := Untar(archive, dst, options); err != nil {
-		t.Fatal(err)
-	}
+	err = Untar(archive, dst, options)
+	require.NoError(t, err)
 
 	checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir)
 	checkFileMode(t, filepath.Join(dst, "d2"), 0750|os.ModeDir)
@@ -142,40 +123,31 @@
 
 func TestOverlayTarAUFSUntar(t *testing.T) {
 	oldmask, err := system.Umask(0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer system.Umask(oldmask)
 
 	src, err := ioutil.TempDir("", "docker-test-overlay-tar-src")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(src)
 
 	setupOverlayTestDir(t, src)
 
 	dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(dst)
 
 	archive, err := TarWithOptions(src, &TarOptions{
 		Compression:    Uncompressed,
 		WhiteoutFormat: OverlayWhiteoutFormat,
 	})
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer archive.Close()
 
-	if err := Untar(archive, dst, &TarOptions{
+	err = Untar(archive, dst, &TarOptions{
 		Compression:    Uncompressed,
 		WhiteoutFormat: AUFSWhiteoutFormat,
-	}); err != nil {
-		t.Fatal(err)
-	}
+	})
+	require.NoError(t, err)
 
 	checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir)
 	checkFileMode(t, filepath.Join(dst, "d1", WhiteoutOpaqueDir), 0700)
diff --git a/pkg/archive/archive_test.go b/pkg/archive/archive_test.go
index 1371b8a..20a07fb 100644
--- a/pkg/archive/archive_test.go
+++ b/pkg/archive/archive_test.go
@@ -14,6 +14,7 @@
 	"testing"
 	"time"
 
+	"github.com/docker/docker/pkg/idtools"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -263,9 +264,7 @@
 
 func TestUntarPathWithInvalidDest(t *testing.T) {
 	tempFolder, err := ioutil.TempDir("", "docker-archive-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(tempFolder)
 	invalidDestFolder := filepath.Join(tempFolder, "invalidDest")
 	// Create a src file
@@ -284,9 +283,7 @@
 
 	cmd := exec.Command("sh", "-c", "tar cf "+tarFileU+" "+srcFileU)
 	_, err = cmd.CombinedOutput()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	err = defaultUntarPath(tarFile, invalidDestFolder)
 	if err == nil {
@@ -308,9 +305,7 @@
 
 func TestUntarPath(t *testing.T) {
 	tmpFolder, err := ioutil.TempDir("", "docker-archive-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(tmpFolder)
 	srcFile := filepath.Join(tmpFolder, "src")
 	tarFile := filepath.Join(tmpFolder, "src.tar")
@@ -331,9 +326,7 @@
 	}
 	cmd := exec.Command("sh", "-c", "tar cf "+tarFileU+" "+srcFileU)
 	_, err = cmd.CombinedOutput()
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	err = defaultUntarPath(tarFile, destFolder)
 	if err != nil {
@@ -732,6 +725,57 @@
 	}
 }
 
+func TestTarWithOptionsChownOptsAlwaysOverridesIdPair(t *testing.T) {
+	origin, err := ioutil.TempDir("", "docker-test-tar-chown-opt")
+	require.NoError(t, err)
+
+	defer os.RemoveAll(origin)
+	filePath := filepath.Join(origin, "1")
+	err = ioutil.WriteFile(filePath, []byte("hello world"), 0700)
+	require.NoError(t, err)
+
+	idMaps := []idtools.IDMap{
+		0: {
+			ContainerID: 0,
+			HostID:      0,
+			Size:        65536,
+		},
+		1: {
+			ContainerID: 0,
+			HostID:      100000,
+			Size:        65536,
+		},
+	}
+
+	cases := []struct {
+		opts        *TarOptions
+		expectedUID int
+		expectedGID int
+	}{
+		{&TarOptions{ChownOpts: &idtools.IDPair{UID: 1337, GID: 42}}, 1337, 42},
+		{&TarOptions{ChownOpts: &idtools.IDPair{UID: 100001, GID: 100001}, UIDMaps: idMaps, GIDMaps: idMaps}, 100001, 100001},
+		{&TarOptions{ChownOpts: &idtools.IDPair{UID: 0, GID: 0}, NoLchown: false}, 0, 0},
+		{&TarOptions{ChownOpts: &idtools.IDPair{UID: 1, GID: 1}, NoLchown: true}, 1, 1},
+		{&TarOptions{ChownOpts: &idtools.IDPair{UID: 1000, GID: 1000}, NoLchown: true}, 1000, 1000},
+	}
+	for _, testCase := range cases {
+		reader, err := TarWithOptions(filePath, testCase.opts)
+		require.NoError(t, err)
+		tr := tar.NewReader(reader)
+		defer reader.Close()
+		for {
+			hdr, err := tr.Next()
+			if err == io.EOF {
+				// end of tar archive
+				break
+			}
+			require.NoError(t, err)
+			assert.Equal(t, hdr.Uid, testCase.expectedUID, "Uid equals expected value")
+			assert.Equal(t, hdr.Gid, testCase.expectedGID, "Gid equals expected value")
+		}
+	}
+}
+
 func TestTarWithOptions(t *testing.T) {
 	// TODO Windows: Figure out how to fix this test.
 	if runtime.GOOS == "windows" {
@@ -1139,8 +1183,10 @@
 func TestTempArchiveCloseMultipleTimes(t *testing.T) {
 	reader := ioutil.NopCloser(strings.NewReader("hello"))
 	tempArchive, err := NewTempArchive(reader, "")
+	require.NoError(t, err)
 	buf := make([]byte, 10)
 	n, err := tempArchive.Read(buf)
+	require.NoError(t, err)
 	if n != 5 {
 		t.Fatalf("Expected to read 5 bytes. Read %d instead", n)
 	}
diff --git a/pkg/archive/archive_unix.go b/pkg/archive/archive_unix.go
index 1213174..ac4a348 100644
--- a/pkg/archive/archive_unix.go
+++ b/pkg/archive/archive_unix.go
@@ -50,8 +50,8 @@
 		// Currently go does not fill in the major/minors
 		if s.Mode&unix.S_IFBLK != 0 ||
 			s.Mode&unix.S_IFCHR != 0 {
-			hdr.Devmajor = int64(major(uint64(s.Rdev)))
-			hdr.Devminor = int64(minor(uint64(s.Rdev)))
+			hdr.Devmajor = int64(major(uint64(s.Rdev))) // nolint: unconvert
+			hdr.Devminor = int64(minor(uint64(s.Rdev))) // nolint: unconvert
 		}
 	}
 
@@ -62,7 +62,7 @@
 	s, ok := stat.(*syscall.Stat_t)
 
 	if ok {
-		inode = uint64(s.Ino)
+		inode = s.Ino
 	}
 
 	return
diff --git a/pkg/archive/archive_unix_test.go b/pkg/archive/archive_unix_test.go
index 90f8ada..a6d957b 100644
--- a/pkg/archive/archive_unix_test.go
+++ b/pkg/archive/archive_unix_test.go
@@ -9,10 +9,13 @@
 	"os"
 	"path/filepath"
 	"runtime"
+	"strings"
 	"syscall"
 	"testing"
 
 	"github.com/docker/docker/pkg/system"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	"golang.org/x/sys/unix"
 )
 
@@ -70,60 +73,89 @@
 
 func TestTarWithHardLink(t *testing.T) {
 	origin, err := ioutil.TempDir("", "docker-test-tar-hardlink")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(origin)
-	if err := ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
-		t.Fatal(err)
-	}
-	if err := os.Link(filepath.Join(origin, "1"), filepath.Join(origin, "2")); err != nil {
-		t.Fatal(err)
-	}
+
+	err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700)
+	require.NoError(t, err)
+
+	err = os.Link(filepath.Join(origin, "1"), filepath.Join(origin, "2"))
+	require.NoError(t, err)
 
 	var i1, i2 uint64
-	if i1, err = getNlink(filepath.Join(origin, "1")); err != nil {
-		t.Fatal(err)
-	}
+	i1, err = getNlink(filepath.Join(origin, "1"))
+	require.NoError(t, err)
+
 	// sanity check that we can hardlink
 	if i1 != 2 {
 		t.Skipf("skipping since hardlinks don't work here; expected 2 links, got %d", i1)
 	}
 
 	dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(dest)
 
 	// we'll do this in two steps to separate failure
 	fh, err := Tar(origin, Uncompressed)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	// ensure we can read the whole thing with no error, before writing back out
 	buf, err := ioutil.ReadAll(fh)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	bRdr := bytes.NewReader(buf)
 	err = Untar(bRdr, dest, &TarOptions{Compression: Uncompressed})
-	if err != nil {
-		t.Fatal(err)
+	require.NoError(t, err)
+
+	i1, err = getInode(filepath.Join(dest, "1"))
+	require.NoError(t, err)
+
+	i2, err = getInode(filepath.Join(dest, "2"))
+	require.NoError(t, err)
+
+	assert.Equal(t, i1, i2)
+}
+
+func TestTarWithHardLinkAndRebase(t *testing.T) {
+	tmpDir, err := ioutil.TempDir("", "docker-test-tar-hardlink-rebase")
+	require.NoError(t, err)
+	defer os.RemoveAll(tmpDir)
+
+	origin := filepath.Join(tmpDir, "origin")
+	err = os.Mkdir(origin, 0700)
+	require.NoError(t, err)
+
+	err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700)
+	require.NoError(t, err)
+
+	err = os.Link(filepath.Join(origin, "1"), filepath.Join(origin, "2"))
+	require.NoError(t, err)
+
+	var i1, i2 uint64
+	i1, err = getNlink(filepath.Join(origin, "1"))
+	require.NoError(t, err)
+
+	// sanity check that we can hardlink
+	if i1 != 2 {
+		t.Skipf("skipping since hardlinks don't work here; expected 2 links, got %d", i1)
 	}
 
-	if i1, err = getInode(filepath.Join(dest, "1")); err != nil {
-		t.Fatal(err)
-	}
-	if i2, err = getInode(filepath.Join(dest, "2")); err != nil {
-		t.Fatal(err)
-	}
+	dest := filepath.Join(tmpDir, "dest")
+	bRdr, err := TarResourceRebase(origin, "origin")
+	require.NoError(t, err)
 
-	if i1 != i2 {
-		t.Errorf("expected matching inodes, but got %d and %d", i1, i2)
-	}
+	dstDir, srcBase := SplitPathDirEntry(origin)
+	_, dstBase := SplitPathDirEntry(dest)
+	content := RebaseArchiveEntries(bRdr, srcBase, dstBase)
+	err = Untar(content, dstDir, &TarOptions{Compression: Uncompressed, NoLchown: true, NoOverwriteDirNonDir: true})
+	require.NoError(t, err)
+
+	i1, err = getInode(filepath.Join(dest, "1"))
+	require.NoError(t, err)
+	i2, err = getInode(filepath.Join(dest, "2"))
+	require.NoError(t, err)
+
+	assert.Equal(t, i1, i2)
 }
 
 func getNlink(path string) (uint64, error) {
@@ -153,51 +185,38 @@
 
 func TestTarWithBlockCharFifo(t *testing.T) {
 	origin, err := ioutil.TempDir("", "docker-test-tar-hardlink")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	defer os.RemoveAll(origin)
-	if err := ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
-		t.Fatal(err)
-	}
-	if err := system.Mknod(filepath.Join(origin, "2"), unix.S_IFBLK, int(system.Mkdev(int64(12), int64(5)))); err != nil {
-		t.Fatal(err)
-	}
-	if err := system.Mknod(filepath.Join(origin, "3"), unix.S_IFCHR, int(system.Mkdev(int64(12), int64(5)))); err != nil {
-		t.Fatal(err)
-	}
-	if err := system.Mknod(filepath.Join(origin, "4"), unix.S_IFIFO, int(system.Mkdev(int64(12), int64(5)))); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700)
+	require.NoError(t, err)
+
+	err = system.Mknod(filepath.Join(origin, "2"), unix.S_IFBLK, int(system.Mkdev(int64(12), int64(5))))
+	require.NoError(t, err)
+	err = system.Mknod(filepath.Join(origin, "3"), unix.S_IFCHR, int(system.Mkdev(int64(12), int64(5))))
+	require.NoError(t, err)
+	err = system.Mknod(filepath.Join(origin, "4"), unix.S_IFIFO, int(system.Mkdev(int64(12), int64(5))))
+	require.NoError(t, err)
 
 	dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(dest)
 
 	// we'll do this in two steps to separate failure
 	fh, err := Tar(origin, Uncompressed)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	// ensure we can read the whole thing with no error, before writing back out
 	buf, err := ioutil.ReadAll(fh)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	bRdr := bytes.NewReader(buf)
 	err = Untar(bRdr, dest, &TarOptions{Compression: Uncompressed})
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	changes, err := ChangesDirs(origin, dest)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	if len(changes) > 0 {
 		t.Fatalf("Tar with special device (block, char, fifo) should keep them (recreate them when untar) : %v", changes)
 	}
@@ -209,22 +228,17 @@
 		t.Skip()
 	}
 	origin, err := ioutil.TempDir("", "docker-test-untar-origin")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(origin)
-	if err := ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
-		t.Fatal(err)
-	}
-	if err := ioutil.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700); err != nil {
-		t.Fatal(err)
-	}
-	if err := ioutil.WriteFile(filepath.Join(origin, "3"), []byte("will be ignored"), 0700); err != nil {
-		t.Fatal(err)
-	}
-	if err := system.Lsetxattr(filepath.Join(origin, "2"), "security.capability", []byte{0x00}, 0); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700)
+	require.NoError(t, err)
+
+	err = ioutil.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700)
+	require.NoError(t, err)
+	err = ioutil.WriteFile(filepath.Join(origin, "3"), []byte("will be ignored"), 0700)
+	require.NoError(t, err)
+	err = system.Lsetxattr(filepath.Join(origin, "2"), "security.capability", []byte{0x00}, 0)
+	require.NoError(t, err)
 
 	for _, c := range []Compression{
 		Uncompressed,
@@ -248,3 +262,58 @@
 		}
 	}
 }
+
+func TestCopyInfoDestinationPathSymlink(t *testing.T) {
+	tmpDir, _ := getTestTempDirs(t)
+	defer removeAllPaths(tmpDir)
+
+	root := strings.TrimRight(tmpDir, "/") + "/"
+
+	type FileTestData struct {
+		resource FileData
+		file     string
+		expected CopyInfo
+	}
+
+	testData := []FileTestData{
+		//Create a directory: /tmp/archive-copy-test*/dir1
+		//Test will "copy" file1 to dir1
+		{resource: FileData{filetype: Dir, path: "dir1", permissions: 0740}, file: "file1", expected: CopyInfo{Path: root + "dir1/file1", Exists: false, IsDir: false}},
+
+		//Create a symlink directory to dir1: /tmp/archive-copy-test*/dirSymlink -> dir1
+		//Test will "copy" file2 to dirSymlink
+		{resource: FileData{filetype: Symlink, path: "dirSymlink", contents: root + "dir1", permissions: 0600}, file: "file2", expected: CopyInfo{Path: root + "dirSymlink/file2", Exists: false, IsDir: false}},
+
+		//Create a file in tmp directory: /tmp/archive-copy-test*/file1
+		//Test to cover when the full file path already exists.
+		{resource: FileData{filetype: Regular, path: "file1", permissions: 0600}, file: "", expected: CopyInfo{Path: root + "file1", Exists: true}},
+
+		//Create a directory: /tmp/archive-copy*/dir2
+		//Test to cover when the full directory path already exists
+		{resource: FileData{filetype: Dir, path: "dir2", permissions: 0740}, file: "", expected: CopyInfo{Path: root + "dir2", Exists: true, IsDir: true}},
+
+		//Create a symlink to a non-existent target: /tmp/archive-copy*/symlink1 -> noSuchTarget
+		//Negative test to cover symlinking to a target that does not exit
+		{resource: FileData{filetype: Symlink, path: "symlink1", contents: "noSuchTarget", permissions: 0600}, file: "", expected: CopyInfo{Path: root + "noSuchTarget", Exists: false}},
+
+		//Create a file in tmp directory for next test: /tmp/existingfile
+		{resource: FileData{filetype: Regular, path: "existingfile", permissions: 0600}, file: "", expected: CopyInfo{Path: root + "existingfile", Exists: true}},
+
+		//Create a symlink to an existing file: /tmp/archive-copy*/symlink2 -> /tmp/existingfile
+		//Test to cover when the parent directory of a new file is a symlink
+		{resource: FileData{filetype: Symlink, path: "symlink2", contents: "existingfile", permissions: 0600}, file: "", expected: CopyInfo{Path: root + "existingfile", Exists: true}},
+	}
+
+	var dirs []FileData
+	for _, data := range testData {
+		dirs = append(dirs, data.resource)
+	}
+	provisionSampleDir(t, tmpDir, dirs)
+
+	for _, info := range testData {
+		p := filepath.Join(tmpDir, info.resource.path, info.file)
+		ci, err := CopyInfoDestinationPath(p)
+		assert.NoError(t, err)
+		assert.Equal(t, info.expected, ci)
+	}
+}
diff --git a/pkg/archive/changes.go b/pkg/archive/changes.go
index 5ca39b7..d78fe6a 100644
--- a/pkg/archive/changes.go
+++ b/pkg/archive/changes.go
@@ -13,10 +13,10 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
 )
 
 // ChangeType represents the change type.
@@ -394,7 +394,7 @@
 func ExportChanges(dir string, changes []Change, uidMaps, gidMaps []idtools.IDMap) (io.ReadCloser, error) {
 	reader, writer := io.Pipe()
 	go func() {
-		ta := newTarAppender(idtools.NewIDMappingsFromMaps(uidMaps, gidMaps), writer)
+		ta := newTarAppender(idtools.NewIDMappingsFromMaps(uidMaps, gidMaps), writer, nil)
 
 		// this buffer is needed for the duration of this piped stream
 		defer pools.BufioWriter32KPool.Put(ta.Buffer)
diff --git a/pkg/archive/changes_linux.go b/pkg/archive/changes_linux.go
index b987e52..8e96d96 100644
--- a/pkg/archive/changes_linux.go
+++ b/pkg/archive/changes_linux.go
@@ -294,7 +294,7 @@
 func overlayDeletedFile(root, path string, fi os.FileInfo) (string, error) {
 	if fi.Mode()&os.ModeCharDevice != 0 {
 		s := fi.Sys().(*syscall.Stat_t)
-		if major(uint64(s.Rdev)) == 0 && minor(uint64(s.Rdev)) == 0 {
+		if major(s.Rdev) == 0 && minor(s.Rdev) == 0 {
 			return path, nil
 		}
 	}
diff --git a/pkg/archive/changes_test.go b/pkg/archive/changes_test.go
index c5d1629..53490aa 100644
--- a/pkg/archive/changes_test.go
+++ b/pkg/archive/changes_test.go
@@ -11,6 +11,7 @@
 	"time"
 
 	"github.com/docker/docker/pkg/system"
+	"github.com/stretchr/testify/require"
 )
 
 func max(x, y int) int {
@@ -49,54 +50,53 @@
 
 func createSampleDir(t *testing.T, root string) {
 	files := []FileData{
-		{Regular, "file1", "file1\n", 0600},
-		{Regular, "file2", "file2\n", 0666},
-		{Regular, "file3", "file3\n", 0404},
-		{Regular, "file4", "file4\n", 0600},
-		{Regular, "file5", "file5\n", 0600},
-		{Regular, "file6", "file6\n", 0600},
-		{Regular, "file7", "file7\n", 0600},
-		{Dir, "dir1", "", 0740},
-		{Regular, "dir1/file1-1", "file1-1\n", 01444},
-		{Regular, "dir1/file1-2", "file1-2\n", 0666},
-		{Dir, "dir2", "", 0700},
-		{Regular, "dir2/file2-1", "file2-1\n", 0666},
-		{Regular, "dir2/file2-2", "file2-2\n", 0666},
-		{Dir, "dir3", "", 0700},
-		{Regular, "dir3/file3-1", "file3-1\n", 0666},
-		{Regular, "dir3/file3-2", "file3-2\n", 0666},
-		{Dir, "dir4", "", 0700},
-		{Regular, "dir4/file3-1", "file4-1\n", 0666},
-		{Regular, "dir4/file3-2", "file4-2\n", 0666},
-		{Symlink, "symlink1", "target1", 0666},
-		{Symlink, "symlink2", "target2", 0666},
-		{Symlink, "symlink3", root + "/file1", 0666},
-		{Symlink, "symlink4", root + "/symlink3", 0666},
-		{Symlink, "dirSymlink", root + "/dir1", 0740},
+		{filetype: Regular, path: "file1", contents: "file1\n", permissions: 0600},
+		{filetype: Regular, path: "file2", contents: "file2\n", permissions: 0666},
+		{filetype: Regular, path: "file3", contents: "file3\n", permissions: 0404},
+		{filetype: Regular, path: "file4", contents: "file4\n", permissions: 0600},
+		{filetype: Regular, path: "file5", contents: "file5\n", permissions: 0600},
+		{filetype: Regular, path: "file6", contents: "file6\n", permissions: 0600},
+		{filetype: Regular, path: "file7", contents: "file7\n", permissions: 0600},
+		{filetype: Dir, path: "dir1", contents: "", permissions: 0740},
+		{filetype: Regular, path: "dir1/file1-1", contents: "file1-1\n", permissions: 01444},
+		{filetype: Regular, path: "dir1/file1-2", contents: "file1-2\n", permissions: 0666},
+		{filetype: Dir, path: "dir2", contents: "", permissions: 0700},
+		{filetype: Regular, path: "dir2/file2-1", contents: "file2-1\n", permissions: 0666},
+		{filetype: Regular, path: "dir2/file2-2", contents: "file2-2\n", permissions: 0666},
+		{filetype: Dir, path: "dir3", contents: "", permissions: 0700},
+		{filetype: Regular, path: "dir3/file3-1", contents: "file3-1\n", permissions: 0666},
+		{filetype: Regular, path: "dir3/file3-2", contents: "file3-2\n", permissions: 0666},
+		{filetype: Dir, path: "dir4", contents: "", permissions: 0700},
+		{filetype: Regular, path: "dir4/file3-1", contents: "file4-1\n", permissions: 0666},
+		{filetype: Regular, path: "dir4/file3-2", contents: "file4-2\n", permissions: 0666},
+		{filetype: Symlink, path: "symlink1", contents: "target1", permissions: 0666},
+		{filetype: Symlink, path: "symlink2", contents: "target2", permissions: 0666},
+		{filetype: Symlink, path: "symlink3", contents: root + "/file1", permissions: 0666},
+		{filetype: Symlink, path: "symlink4", contents: root + "/symlink3", permissions: 0666},
+		{filetype: Symlink, path: "dirSymlink", contents: root + "/dir1", permissions: 0740},
 	}
+	provisionSampleDir(t, root, files)
+}
 
+func provisionSampleDir(t *testing.T, root string, files []FileData) {
 	now := time.Now()
 	for _, info := range files {
 		p := path.Join(root, info.path)
 		if info.filetype == Dir {
-			if err := os.MkdirAll(p, info.permissions); err != nil {
-				t.Fatal(err)
-			}
+			err := os.MkdirAll(p, info.permissions)
+			require.NoError(t, err)
 		} else if info.filetype == Regular {
-			if err := ioutil.WriteFile(p, []byte(info.contents), info.permissions); err != nil {
-				t.Fatal(err)
-			}
+			err := ioutil.WriteFile(p, []byte(info.contents), info.permissions)
+			require.NoError(t, err)
 		} else if info.filetype == Symlink {
-			if err := os.Symlink(info.contents, p); err != nil {
-				t.Fatal(err)
-			}
+			err := os.Symlink(info.contents, p)
+			require.NoError(t, err)
 		}
 
 		if info.filetype != Symlink {
 			// Set a consistent ctime, atime for all files and dirs
-			if err := system.Chtimes(p, now, now); err != nil {
-				t.Fatal(err)
-			}
+			err := system.Chtimes(p, now, now)
+			require.NoError(t, err)
 		}
 	}
 }
@@ -126,20 +126,14 @@
 		t.Skip("symlinks on Windows")
 	}
 	rwLayer, err := ioutil.TempDir("", "docker-changes-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(rwLayer)
 	layer, err := ioutil.TempDir("", "docker-changes-test-layer")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(layer)
 	createSampleDir(t, layer)
 	changes, err := Changes([]string{layer}, rwLayer)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	if len(changes) != 0 {
 		t.Fatalf("Changes with no difference should have detect no changes, but detected %d", len(changes))
 	}
@@ -153,18 +147,14 @@
 	}
 	// Mock the readonly layer
 	layer, err := ioutil.TempDir("", "docker-changes-test-layer")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(layer)
 	createSampleDir(t, layer)
 	os.MkdirAll(path.Join(layer, "dir1/subfolder"), 0740)
 
 	// Mock the RW layer
 	rwLayer, err := ioutil.TempDir("", "docker-changes-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(rwLayer)
 
 	// Create a folder in RW layer
@@ -181,9 +171,7 @@
 	ioutil.WriteFile(newFile, []byte{}, 0740)
 
 	changes, err := Changes([]string{layer}, rwLayer)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	expectedChanges := []Change{
 		{"/dir1", ChangeModify},
@@ -203,6 +191,7 @@
 		t.Skip("symlinks on Windows")
 	}
 	baseLayer, err := ioutil.TempDir("", "docker-changes-test.")
+	require.NoError(t, err)
 	defer os.RemoveAll(baseLayer)
 
 	dir3 := path.Join(baseLayer, "dir1/dir2/dir3")
@@ -212,6 +201,7 @@
 	ioutil.WriteFile(file, []byte("hello"), 0666)
 
 	layer, err := ioutil.TempDir("", "docker-changes-test2.")
+	require.NoError(t, err)
 	defer os.RemoveAll(layer)
 
 	// Test creating a new file
@@ -224,9 +214,7 @@
 	ioutil.WriteFile(file, []byte("bye"), 0666)
 
 	changes, err := Changes([]string{baseLayer}, layer)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	expectedChanges := []Change{
 		{"/dir1/dir2/dir3", ChangeModify},
@@ -236,6 +224,7 @@
 
 	// Now test changing a file
 	layer, err = ioutil.TempDir("", "docker-changes-test3.")
+	require.NoError(t, err)
 	defer os.RemoveAll(layer)
 
 	if err := copyDir(baseLayer+"/dir1", layer+"/"); err != nil {
@@ -246,9 +235,7 @@
 	ioutil.WriteFile(file, []byte("bye"), 0666)
 
 	changes, err = Changes([]string{baseLayer}, layer)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	expectedChanges = []Change{
 		{"/dir1/dir2/dir3/file.txt", ChangeModify},
@@ -265,20 +252,15 @@
 		t.Skip("symlinks on Windows; gcp failure on Solaris")
 	}
 	src, err := ioutil.TempDir("", "docker-changes-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(src)
 	createSampleDir(t, src)
 	dst := src + "-copy"
-	if err := copyDir(src, dst); err != nil {
-		t.Fatal(err)
-	}
+	err = copyDir(src, dst)
+	require.NoError(t, err)
 	defer os.RemoveAll(dst)
 	changes, err := ChangesDirs(dst, src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	if len(changes) != 0 {
 		t.Fatalf("Reported changes for identical dirs: %v", changes)
@@ -289,81 +271,65 @@
 
 func mutateSampleDir(t *testing.T, root string) {
 	// Remove a regular file
-	if err := os.RemoveAll(path.Join(root, "file1")); err != nil {
-		t.Fatal(err)
-	}
+	err := os.RemoveAll(path.Join(root, "file1"))
+	require.NoError(t, err)
 
 	// Remove a directory
-	if err := os.RemoveAll(path.Join(root, "dir1")); err != nil {
-		t.Fatal(err)
-	}
+	err = os.RemoveAll(path.Join(root, "dir1"))
+	require.NoError(t, err)
 
 	// Remove a symlink
-	if err := os.RemoveAll(path.Join(root, "symlink1")); err != nil {
-		t.Fatal(err)
-	}
+	err = os.RemoveAll(path.Join(root, "symlink1"))
+	require.NoError(t, err)
 
 	// Rewrite a file
-	if err := ioutil.WriteFile(path.Join(root, "file2"), []byte("fileNN\n"), 0777); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(path.Join(root, "file2"), []byte("fileNN\n"), 0777)
+	require.NoError(t, err)
 
 	// Replace a file
-	if err := os.RemoveAll(path.Join(root, "file3")); err != nil {
-		t.Fatal(err)
-	}
-	if err := ioutil.WriteFile(path.Join(root, "file3"), []byte("fileMM\n"), 0404); err != nil {
-		t.Fatal(err)
-	}
+	err = os.RemoveAll(path.Join(root, "file3"))
+	require.NoError(t, err)
+	err = ioutil.WriteFile(path.Join(root, "file3"), []byte("fileMM\n"), 0404)
+	require.NoError(t, err)
 
 	// Touch file
-	if err := system.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil {
-		t.Fatal(err)
-	}
+	err = system.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second))
+	require.NoError(t, err)
 
 	// Replace file with dir
-	if err := os.RemoveAll(path.Join(root, "file5")); err != nil {
-		t.Fatal(err)
-	}
-	if err := os.MkdirAll(path.Join(root, "file5"), 0666); err != nil {
-		t.Fatal(err)
-	}
+	err = os.RemoveAll(path.Join(root, "file5"))
+	require.NoError(t, err)
+	err = os.MkdirAll(path.Join(root, "file5"), 0666)
+	require.NoError(t, err)
 
 	// Create new file
-	if err := ioutil.WriteFile(path.Join(root, "filenew"), []byte("filenew\n"), 0777); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(path.Join(root, "filenew"), []byte("filenew\n"), 0777)
+	require.NoError(t, err)
 
 	// Create new dir
-	if err := os.MkdirAll(path.Join(root, "dirnew"), 0766); err != nil {
-		t.Fatal(err)
-	}
+	err = os.MkdirAll(path.Join(root, "dirnew"), 0766)
+	require.NoError(t, err)
 
 	// Create a new symlink
-	if err := os.Symlink("targetnew", path.Join(root, "symlinknew")); err != nil {
-		t.Fatal(err)
-	}
+	err = os.Symlink("targetnew", path.Join(root, "symlinknew"))
+	require.NoError(t, err)
 
 	// Change a symlink
-	if err := os.RemoveAll(path.Join(root, "symlink2")); err != nil {
-		t.Fatal(err)
-	}
-	if err := os.Symlink("target2change", path.Join(root, "symlink2")); err != nil {
-		t.Fatal(err)
-	}
+	err = os.RemoveAll(path.Join(root, "symlink2"))
+	require.NoError(t, err)
+
+	err = os.Symlink("target2change", path.Join(root, "symlink2"))
+	require.NoError(t, err)
 
 	// Replace dir with file
-	if err := os.RemoveAll(path.Join(root, "dir2")); err != nil {
-		t.Fatal(err)
-	}
-	if err := ioutil.WriteFile(path.Join(root, "dir2"), []byte("dir2\n"), 0777); err != nil {
-		t.Fatal(err)
-	}
+	err = os.RemoveAll(path.Join(root, "dir2"))
+	require.NoError(t, err)
+	err = ioutil.WriteFile(path.Join(root, "dir2"), []byte("dir2\n"), 0777)
+	require.NoError(t, err)
 
 	// Touch dir
-	if err := system.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil {
-		t.Fatal(err)
-	}
+	err = system.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second))
+	require.NoError(t, err)
 }
 
 func TestChangesDirsMutated(t *testing.T) {
@@ -374,23 +340,18 @@
 		t.Skip("symlinks on Windows; gcp failures on Solaris")
 	}
 	src, err := ioutil.TempDir("", "docker-changes-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	createSampleDir(t, src)
 	dst := src + "-copy"
-	if err := copyDir(src, dst); err != nil {
-		t.Fatal(err)
-	}
+	err = copyDir(src, dst)
+	require.NoError(t, err)
 	defer os.RemoveAll(src)
 	defer os.RemoveAll(dst)
 
 	mutateSampleDir(t, dst)
 
 	changes, err := ChangesDirs(dst, src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	sort.Sort(changesByPath(changes))
 
@@ -436,41 +397,29 @@
 		t.Skip("symlinks on Windows; gcp failures on Solaris")
 	}
 	src, err := ioutil.TempDir("", "docker-changes-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	createSampleDir(t, src)
 	defer os.RemoveAll(src)
 	dst := src + "-copy"
-	if err := copyDir(src, dst); err != nil {
-		t.Fatal(err)
-	}
+	err = copyDir(src, dst)
+	require.NoError(t, err)
 	mutateSampleDir(t, dst)
 	defer os.RemoveAll(dst)
 
 	changes, err := ChangesDirs(dst, src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	layer, err := ExportChanges(dst, changes, nil, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	layerCopy, err := NewTempArchive(layer, "")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
-	if _, err := ApplyLayer(src, layerCopy); err != nil {
-		t.Fatal(err)
-	}
+	_, err = ApplyLayer(src, layerCopy)
+	require.NoError(t, err)
 
 	changes2, err := ChangesDirs(src, dst)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	if len(changes2) != 0 {
 		t.Fatalf("Unexpected differences after reapplying mutation: %v", changes2)
@@ -484,26 +433,18 @@
 		t.Skip("hardlinks on Windows")
 	}
 	srcDir, err := ioutil.TempDir("", "docker-test-srcDir")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(srcDir)
 
 	destDir, err := ioutil.TempDir("", "docker-test-destDir")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	defer os.RemoveAll(destDir)
 
 	creationSize, err := prepareUntarSourceDirectory(100, destDir, true)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	changes, err := ChangesDirs(destDir, srcDir)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	got := ChangesSize(destDir, changes)
 	if got != int64(creationSize) {
@@ -530,15 +471,15 @@
 
 func TestChangesSize(t *testing.T) {
 	parentPath, err := ioutil.TempDir("", "docker-changes-test")
+	require.NoError(t, err)
 	defer os.RemoveAll(parentPath)
 	addition := path.Join(parentPath, "addition")
-	if err := ioutil.WriteFile(addition, []byte{0x01, 0x01, 0x01}, 0744); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(addition, []byte{0x01, 0x01, 0x01}, 0744)
+	require.NoError(t, err)
 	modification := path.Join(parentPath, "modification")
-	if err = ioutil.WriteFile(modification, []byte{0x01, 0x01, 0x01}, 0744); err != nil {
-		t.Fatal(err)
-	}
+	err = ioutil.WriteFile(modification, []byte{0x01, 0x01, 0x01}, 0744)
+	require.NoError(t, err)
+
 	changes := []Change{
 		{Path: "addition", Kind: ChangeAdd},
 		{Path: "modification", Kind: ChangeModify},
diff --git a/pkg/archive/changes_unix.go b/pkg/archive/changes_unix.go
index 98e2b39..7aa1226 100644
--- a/pkg/archive/changes_unix.go
+++ b/pkg/archive/changes_unix.go
@@ -29,7 +29,7 @@
 }
 
 func getIno(fi os.FileInfo) uint64 {
-	return uint64(fi.Sys().(*syscall.Stat_t).Ino)
+	return fi.Sys().(*syscall.Stat_t).Ino
 }
 
 func hasHardlinks(fi os.FileInfo) bool {
diff --git a/pkg/archive/copy.go b/pkg/archive/copy.go
index 5281e29..d1e036d 100644
--- a/pkg/archive/copy.go
+++ b/pkg/archive/copy.go
@@ -9,8 +9,8 @@
 	"path/filepath"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
 )
 
 // Errors used or returned by this file.
@@ -27,23 +27,23 @@
 // path (from before being processed by utility functions from the path or
 // filepath stdlib packages) ends with a trailing `/.` or `/`. If the cleaned
 // path already ends in a `.` path segment, then another is not added. If the
-// clean path already ends in a path separator, then another is not added.
-func PreserveTrailingDotOrSeparator(cleanedPath, originalPath string) string {
+// clean path already ends in the separator, then another is not added.
+func PreserveTrailingDotOrSeparator(cleanedPath string, originalPath string, sep byte) string {
 	// Ensure paths are in platform semantics
-	cleanedPath = normalizePath(cleanedPath)
-	originalPath = normalizePath(originalPath)
+	cleanedPath = strings.Replace(cleanedPath, "/", string(sep), -1)
+	originalPath = strings.Replace(originalPath, "/", string(sep), -1)
 
 	if !specifiesCurrentDir(cleanedPath) && specifiesCurrentDir(originalPath) {
-		if !hasTrailingPathSeparator(cleanedPath) {
+		if !hasTrailingPathSeparator(cleanedPath, sep) {
 			// Add a separator if it doesn't already end with one (a cleaned
 			// path would only end in a separator if it is the root).
-			cleanedPath += string(filepath.Separator)
+			cleanedPath += string(sep)
 		}
 		cleanedPath += "."
 	}
 
-	if !hasTrailingPathSeparator(cleanedPath) && hasTrailingPathSeparator(originalPath) {
-		cleanedPath += string(filepath.Separator)
+	if !hasTrailingPathSeparator(cleanedPath, sep) && hasTrailingPathSeparator(originalPath, sep) {
+		cleanedPath += string(sep)
 	}
 
 	return cleanedPath
@@ -52,14 +52,14 @@
 // assertsDirectory returns whether the given path is
 // asserted to be a directory, i.e., the path ends with
 // a trailing '/' or `/.`, assuming a path separator of `/`.
-func assertsDirectory(path string) bool {
-	return hasTrailingPathSeparator(path) || specifiesCurrentDir(path)
+func assertsDirectory(path string, sep byte) bool {
+	return hasTrailingPathSeparator(path, sep) || specifiesCurrentDir(path)
 }
 
 // hasTrailingPathSeparator returns whether the given
 // path ends with the system's path separator character.
-func hasTrailingPathSeparator(path string) bool {
-	return len(path) > 0 && os.IsPathSeparator(path[len(path)-1])
+func hasTrailingPathSeparator(path string, sep byte) bool {
+	return len(path) > 0 && path[len(path)-1] == sep
 }
 
 // specifiesCurrentDir returns whether the given path specifies
@@ -72,10 +72,10 @@
 // basename by first cleaning the path but preserves a trailing "." if the
 // original path specified the current directory.
 func SplitPathDirEntry(path string) (dir, base string) {
-	cleanedPath := filepath.Clean(normalizePath(path))
+	cleanedPath := filepath.Clean(filepath.FromSlash(path))
 
 	if specifiesCurrentDir(path) {
-		cleanedPath += string(filepath.Separator) + "."
+		cleanedPath += string(os.PathSeparator) + "."
 	}
 
 	return filepath.Dir(cleanedPath), filepath.Base(cleanedPath)
@@ -106,19 +106,24 @@
 	// Separate the source path between its directory and
 	// the entry in that directory which we are archiving.
 	sourceDir, sourceBase := SplitPathDirEntry(sourcePath)
-
-	filter := []string{sourceBase}
+	opts := TarResourceRebaseOpts(sourceBase, rebaseName)
 
 	logrus.Debugf("copying %q from %q", sourceBase, sourceDir)
+	return TarWithOptions(sourceDir, opts)
+}
 
-	return TarWithOptions(sourceDir, &TarOptions{
+// TarResourceRebaseOpts does not preform the Tar, but instead just creates the rebase
+// parameters to be sent to TarWithOptions (the TarOptions struct)
+func TarResourceRebaseOpts(sourceBase string, rebaseName string) *TarOptions {
+	filter := []string{sourceBase}
+	return &TarOptions{
 		Compression:      Uncompressed,
 		IncludeFiles:     filter,
 		IncludeSourceDir: true,
 		RebaseNames: map[string]string{
 			sourceBase: rebaseName,
 		},
-	})
+	}
 }
 
 // CopyInfo holds basic info about the source
@@ -218,7 +223,7 @@
 		// Ensure destination parent dir exists.
 		dstParent, _ := SplitPathDirEntry(path)
 
-		parentDirStat, err := os.Lstat(dstParent)
+		parentDirStat, err := os.Stat(dstParent)
 		if err != nil {
 			return CopyInfo{}, err
 		}
@@ -281,7 +286,7 @@
 			srcBase = srcInfo.RebaseName
 		}
 		return dstDir, RebaseArchiveEntries(srcContent, srcBase, dstBase), nil
-	case assertsDirectory(dstInfo.Path):
+	case assertsDirectory(dstInfo.Path, os.PathSeparator):
 		// The destination does not exist and is asserted to be created as a
 		// directory, but the source content is not a directory. This is an
 		// error condition since you cannot create a directory from a file
@@ -351,6 +356,9 @@
 	return rebased
 }
 
+// TODO @gupta-ak. These might have to be changed in the future to be
+// continuity driver aware as well to support LCOW.
+
 // CopyResource performs an archive copy from the given source path to the
 // given destination path. The source path MUST exist and the destination
 // path's parent directory must exist.
@@ -365,8 +373,8 @@
 	dstPath = normalizePath(dstPath)
 
 	// Clean the source and destination paths.
-	srcPath = PreserveTrailingDotOrSeparator(filepath.Clean(srcPath), srcPath)
-	dstPath = PreserveTrailingDotOrSeparator(filepath.Clean(dstPath), dstPath)
+	srcPath = PreserveTrailingDotOrSeparator(filepath.Clean(srcPath), srcPath, os.PathSeparator)
+	dstPath = PreserveTrailingDotOrSeparator(filepath.Clean(dstPath), dstPath, os.PathSeparator)
 
 	if srcInfo, err = CopyInfoSourcePath(srcPath, followLink); err != nil {
 		return err
@@ -429,7 +437,8 @@
 		// resolvedDirPath will have been cleaned (no trailing path separators) so
 		// we can manually join it with the base path element.
 		resolvedPath = resolvedDirPath + string(filepath.Separator) + basePath
-		if hasTrailingPathSeparator(path) && filepath.Base(path) != filepath.Base(resolvedPath) {
+		if hasTrailingPathSeparator(path, os.PathSeparator) &&
+			filepath.Base(path) != filepath.Base(resolvedPath) {
 			rebaseName = filepath.Base(path)
 		}
 	}
@@ -442,11 +451,13 @@
 	// linkTarget will have been cleaned (no trailing path separators and dot) so
 	// we can manually join it with them
 	var rebaseName string
-	if specifiesCurrentDir(path) && !specifiesCurrentDir(resolvedPath) {
+	if specifiesCurrentDir(path) &&
+		!specifiesCurrentDir(resolvedPath) {
 		resolvedPath += string(filepath.Separator) + "."
 	}
 
-	if hasTrailingPathSeparator(path) && !hasTrailingPathSeparator(resolvedPath) {
+	if hasTrailingPathSeparator(path, os.PathSeparator) &&
+		!hasTrailingPathSeparator(resolvedPath, os.PathSeparator) {
 		resolvedPath += string(filepath.Separator)
 	}
 
diff --git a/pkg/archive/copy_unix_test.go b/pkg/archive/copy_unix_test.go
index 4d5ae79..e08bcb4 100644
--- a/pkg/archive/copy_unix_test.go
+++ b/pkg/archive/copy_unix_test.go
@@ -15,6 +15,8 @@
 	"path/filepath"
 	"strings"
 	"testing"
+
+	"github.com/stretchr/testify/require"
 )
 
 func removeAllPaths(paths ...string) {
@@ -26,13 +28,11 @@
 func getTestTempDirs(t *testing.T) (tmpDirA, tmpDirB string) {
 	var err error
 
-	if tmpDirA, err = ioutil.TempDir("", "archive-copy-test"); err != nil {
-		t.Fatal(err)
-	}
+	tmpDirA, err = ioutil.TempDir("", "archive-copy-test")
+	require.NoError(t, err)
 
-	if tmpDirB, err = ioutil.TempDir("", "archive-copy-test"); err != nil {
-		t.Fatal(err)
-	}
+	tmpDirB, err = ioutil.TempDir("", "archive-copy-test")
+	require.NoError(t, err)
 
 	return
 }
@@ -118,9 +118,8 @@
 
 	t.Logf("logging directory contents: %q", dirPath)
 
-	if err := filepath.Walk(dirPath, logWalkedPaths); err != nil {
-		t.Fatal(err)
-	}
+	err := filepath.Walk(dirPath, logWalkedPaths)
+	require.NoError(t, err)
 }
 
 func testCopyHelper(t *testing.T, srcPath, dstPath string) (err error) {
@@ -293,9 +292,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, srcPath, dstPath)
+	require.NoError(t, err)
 	os.Remove(dstPath)
 
 	symlinkPath := filepath.Join(tmpDirA, "symlink3")
@@ -306,17 +304,15 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, linkTarget, dstPath)
+	require.NoError(t, err)
 	os.Remove(dstPath)
 	if err = testCopyHelperFSym(t, symlinkPath1, dstPath); err != nil {
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, linkTarget, dstPath)
+	require.NoError(t, err)
 }
 
 // B. SRC specifies a file and DST (with trailing path separator) doesn't
@@ -377,9 +373,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, srcPath, dstPath)
+	require.NoError(t, err)
 }
 
 // C. Symbol link following version:
@@ -415,9 +410,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, linkTarget, dstPath)
+	require.NoError(t, err)
 }
 
 // D. SRC specifies a file and DST exists as a directory. This should place
@@ -446,9 +440,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, srcPath, dstPath)
+	require.NoError(t, err)
 
 	// Now try again but using a trailing path separator for dstDir.
 
@@ -466,9 +459,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, srcPath, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, srcPath, dstPath)
+	require.NoError(t, err)
 }
 
 // D. Symbol link following version:
@@ -499,9 +491,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, linkTarget, dstPath)
+	require.NoError(t, err)
 
 	// Now try again but using a trailing path separator for dstDir.
 
@@ -519,9 +510,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = fileContentsEqual(t, linkTarget, dstPath); err != nil {
-		t.Fatal(err)
-	}
+	err = fileContentsEqual(t, linkTarget, dstPath)
+	require.NoError(t, err)
 }
 
 // E. SRC specifies a directory and DST does not exist. This should create a
@@ -563,9 +553,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, dstDir, srcDir)
+	require.NoError(t, err)
 }
 
 // E. Symbol link following version:
@@ -609,9 +598,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, dstDir, linkTarget)
+	require.NoError(t, err)
 }
 
 // F. SRC specifies a directory and DST exists as a file. This should cause an
@@ -669,9 +657,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, resultDir, srcDir); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, resultDir, srcDir)
+	require.NoError(t, err)
 
 	// Now try again but using a trailing path separator for dstDir.
 
@@ -689,9 +676,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, resultDir, srcDir); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, resultDir, srcDir)
+	require.NoError(t, err)
 }
 
 // G. Symbol link version:
@@ -717,9 +703,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, resultDir, linkTarget); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, resultDir, linkTarget)
+	require.NoError(t, err)
 
 	// Now try again but using a trailing path separator for dstDir.
 
@@ -737,9 +722,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, resultDir, linkTarget); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, resultDir, linkTarget)
+	require.NoError(t, err)
 }
 
 // H. SRC specifies a directory's contents only and DST does not exist. This
@@ -899,9 +883,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, dstDir, srcDir)
+	require.NoError(t, err)
 
 	// Now try again but using a trailing path separator for dstDir.
 
@@ -919,9 +902,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, dstDir, srcDir); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, dstDir, srcDir)
+	require.NoError(t, err)
 }
 
 // J. Symbol link following version:
@@ -952,9 +934,8 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, dstDir, linkTarget)
+	require.NoError(t, err)
 
 	// Now try again but using a trailing path separator for dstDir.
 
@@ -972,7 +953,6 @@
 		t.Fatalf("unexpected error %T: %s", err, err)
 	}
 
-	if err = dirContentsEqual(t, dstDir, linkTarget); err != nil {
-		t.Fatal(err)
-	}
+	err = dirContentsEqual(t, dstDir, linkTarget)
+	require.NoError(t, err)
 }
diff --git a/pkg/archive/diff.go b/pkg/archive/diff.go
index a2766b5..019facd 100644
--- a/pkg/archive/diff.go
+++ b/pkg/archive/diff.go
@@ -10,10 +10,10 @@
 	"runtime"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/pools"
 	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
 )
 
 // UnpackLayer unpack `layer` to a `dest`. The stream `layer` can be
diff --git a/pkg/archive/example_changes.go b/pkg/archive/example_changes.go
index cedd46a..495db80 100644
--- a/pkg/archive/example_changes.go
+++ b/pkg/archive/example_changes.go
@@ -13,8 +13,8 @@
 	"os"
 	"path"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/archive"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/pkg/archive/wrap_test.go b/pkg/archive/wrap_test.go
index 46ab366..bd26bda 100644
--- a/pkg/archive/wrap_test.go
+++ b/pkg/archive/wrap_test.go
@@ -5,13 +5,13 @@
 	"bytes"
 	"io"
 	"testing"
+
+	"github.com/stretchr/testify/require"
 )
 
 func TestGenerateEmptyFile(t *testing.T) {
 	archive, err := Generate("emptyFile")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	if archive == nil {
 		t.Fatal("The generated archive should not be nil.")
 	}
@@ -28,9 +28,7 @@
 		if err == io.EOF {
 			break
 		}
-		if err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, err)
 		buf := new(bytes.Buffer)
 		buf.ReadFrom(tr)
 		content := buf.String()
@@ -54,9 +52,7 @@
 
 func TestGenerateWithContent(t *testing.T) {
 	archive, err := Generate("file", "content")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	if archive == nil {
 		t.Fatal("The generated archive should not be nil.")
 	}
@@ -73,9 +69,7 @@
 		if err == io.EOF {
 			break
 		}
-		if err != nil {
-			t.Fatal(err)
-		}
+		require.NoError(t, err)
 		buf := new(bytes.Buffer)
 		buf.ReadFrom(tr)
 		content := buf.String()
diff --git a/pkg/authorization/authz.go b/pkg/authorization/authz.go
index dc9a9ae..3bd2fc0 100644
--- a/pkg/authorization/authz.go
+++ b/pkg/authorization/authz.go
@@ -8,8 +8,8 @@
 	"net/http"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/ioutils"
+	"github.com/sirupsen/logrus"
 )
 
 const maxBodySize = 1048576 // 1MB
@@ -158,7 +158,7 @@
 
 // headers returns flatten version of the http headers excluding authorization
 func headers(header http.Header) map[string]string {
-	v := make(map[string]string, 0)
+	v := make(map[string]string)
 	for k, values := range header {
 		// Skip authorization headers
 		if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "X-Registry-Config") || strings.EqualFold(k, "X-Registry-Auth") {
@@ -176,10 +176,7 @@
 	error
 }
 
-// HTTPErrorStatusCode returns the authorization error status code (forbidden)
-func (e authorizationError) HTTPErrorStatusCode() int {
-	return http.StatusForbidden
-}
+func (authorizationError) Forbidden() {}
 
 func newAuthorizationError(plugin, msg string) authorizationError {
 	return authorizationError{error: fmt.Errorf("authorization denied by plugin %s: %s", plugin, msg)}
diff --git a/pkg/authorization/middleware.go b/pkg/authorization/middleware.go
index 7789a75..24a457a 100644
--- a/pkg/authorization/middleware.go
+++ b/pkg/authorization/middleware.go
@@ -4,8 +4,8 @@
 	"net/http"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/plugingetter"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/pkg/authorization/response.go b/pkg/authorization/response.go
index 129bf2f..cea64f2 100644
--- a/pkg/authorization/response.go
+++ b/pkg/authorization/response.go
@@ -8,7 +8,7 @@
 	"net"
 	"net/http"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // ResponseModifier allows authorization plugins to read and modify the content of the http.response
diff --git a/pkg/chrootarchive/archive.go b/pkg/chrootarchive/archive.go
index 7604418..d6d0788 100644
--- a/pkg/chrootarchive/archive.go
+++ b/pkg/chrootarchive/archive.go
@@ -16,7 +16,10 @@
 	if idMappings == nil {
 		idMappings = &idtools.IDMappings{}
 	}
-	return &archive.Archiver{Untar: Untar, IDMappings: idMappings}
+	return &archive.Archiver{
+		Untar:         Untar,
+		IDMappingsVar: idMappings,
+	}
 }
 
 // Untar reads a stream of bytes from `archive`, parses it as a tar archive,
diff --git a/pkg/containerfs/archiver.go b/pkg/containerfs/archiver.go
new file mode 100644
index 0000000..3eeab49
--- /dev/null
+++ b/pkg/containerfs/archiver.go
@@ -0,0 +1,198 @@
+package containerfs
+
+import (
+	"archive/tar"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+
+	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/idtools"
+	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
+)
+
+// TarFunc provides a function definition for a custom Tar function
+type TarFunc func(string, *archive.TarOptions) (io.ReadCloser, error)
+
+// UntarFunc provides a function definition for a custom Untar function
+type UntarFunc func(io.Reader, string, *archive.TarOptions) error
+
+// Archiver provides a similar implementation of the archive.Archiver package with the rootfs abstraction
+type Archiver struct {
+	SrcDriver     Driver
+	DstDriver     Driver
+	Tar           TarFunc
+	Untar         UntarFunc
+	IDMappingsVar *idtools.IDMappings
+}
+
+// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other.
+// If either Tar or Untar fails, TarUntar aborts and returns the error.
+func (archiver *Archiver) TarUntar(src, dst string) error {
+	logrus.Debugf("TarUntar(%s %s)", src, dst)
+	tarArchive, err := archiver.Tar(src, &archive.TarOptions{Compression: archive.Uncompressed})
+	if err != nil {
+		return err
+	}
+	defer tarArchive.Close()
+	options := &archive.TarOptions{
+		UIDMaps: archiver.IDMappingsVar.UIDs(),
+		GIDMaps: archiver.IDMappingsVar.GIDs(),
+	}
+	return archiver.Untar(tarArchive, dst, options)
+}
+
+// UntarPath untar a file from path to a destination, src is the source tar file path.
+func (archiver *Archiver) UntarPath(src, dst string) error {
+	tarArchive, err := archiver.SrcDriver.Open(src)
+	if err != nil {
+		return err
+	}
+	defer tarArchive.Close()
+	options := &archive.TarOptions{
+		UIDMaps: archiver.IDMappingsVar.UIDs(),
+		GIDMaps: archiver.IDMappingsVar.GIDs(),
+	}
+	return archiver.Untar(tarArchive, dst, options)
+}
+
+// CopyWithTar creates a tar archive of filesystem path `src`, and
+// unpacks it at filesystem path `dst`.
+// The archive is streamed directly with fixed buffering and no
+// intermediary disk IO.
+func (archiver *Archiver) CopyWithTar(src, dst string) error {
+	srcSt, err := archiver.SrcDriver.Stat(src)
+	if err != nil {
+		return err
+	}
+	if !srcSt.IsDir() {
+		return archiver.CopyFileWithTar(src, dst)
+	}
+
+	// if this archiver is set up with ID mapping we need to create
+	// the new destination directory with the remapped root UID/GID pair
+	// as owner
+	rootIDs := archiver.IDMappingsVar.RootPair()
+	// Create dst, copy src's content into it
+	if err := idtools.MkdirAllAndChownNew(dst, 0755, rootIDs); err != nil {
+		return err
+	}
+	logrus.Debugf("Calling TarUntar(%s, %s)", src, dst)
+	return archiver.TarUntar(src, dst)
+}
+
+// CopyFileWithTar emulates the behavior of the 'cp' command-line
+// for a single file. It copies a regular file from path `src` to
+// path `dst`, and preserves all its metadata.
+func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
+	logrus.Debugf("CopyFileWithTar(%s, %s)", src, dst)
+	srcDriver := archiver.SrcDriver
+	dstDriver := archiver.DstDriver
+
+	srcSt, err := srcDriver.Stat(src)
+	if err != nil {
+		return err
+	}
+
+	if srcSt.IsDir() {
+		return fmt.Errorf("Can't copy a directory")
+	}
+
+	// Clean up the trailing slash. This must be done in an operating
+	// system specific manner.
+	if dst[len(dst)-1] == dstDriver.Separator() {
+		dst = dstDriver.Join(dst, srcDriver.Base(src))
+	}
+
+	// The original call was system.MkdirAll, which is just
+	// os.MkdirAll on not-Windows and changed for Windows.
+	if dstDriver.OS() == "windows" {
+		// Now we are WCOW
+		if err := system.MkdirAll(filepath.Dir(dst), 0700, ""); err != nil {
+			return err
+		}
+	} else {
+		// We can just use the driver.MkdirAll function
+		if err := dstDriver.MkdirAll(dstDriver.Dir(dst), 0700); err != nil {
+			return err
+		}
+	}
+
+	r, w := io.Pipe()
+	errC := make(chan error, 1)
+
+	go func() {
+		defer close(errC)
+		errC <- func() error {
+			defer w.Close()
+
+			srcF, err := srcDriver.Open(src)
+			if err != nil {
+				return err
+			}
+			defer srcF.Close()
+
+			hdr, err := tar.FileInfoHeader(srcSt, "")
+			if err != nil {
+				return err
+			}
+			hdr.Name = dstDriver.Base(dst)
+			if dstDriver.OS() == "windows" {
+				hdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))
+			} else {
+				hdr.Mode = int64(os.FileMode(hdr.Mode))
+			}
+
+			if err := remapIDs(archiver.IDMappingsVar, hdr); err != nil {
+				return err
+			}
+
+			tw := tar.NewWriter(w)
+			defer tw.Close()
+			if err := tw.WriteHeader(hdr); err != nil {
+				return err
+			}
+			if _, err := io.Copy(tw, srcF); err != nil {
+				return err
+			}
+			return nil
+		}()
+	}()
+	defer func() {
+		if er := <-errC; err == nil && er != nil {
+			err = er
+		}
+	}()
+
+	err = archiver.Untar(r, dstDriver.Dir(dst), nil)
+	if err != nil {
+		r.CloseWithError(err)
+	}
+	return err
+}
+
+// IDMappings returns the IDMappings of the archiver.
+func (archiver *Archiver) IDMappings() *idtools.IDMappings {
+	return archiver.IDMappingsVar
+}
+
+func remapIDs(idMappings *idtools.IDMappings, hdr *tar.Header) error {
+	ids, err := idMappings.ToHost(idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid})
+	hdr.Uid, hdr.Gid = ids.UID, ids.GID
+	return err
+}
+
+// chmodTarEntry is used to adjust the file permissions used in tar header based
+// on the platform the archival is done.
+func chmodTarEntry(perm os.FileMode) os.FileMode {
+	//perm &= 0755 // this 0-ed out tar flags (like link, regular file, directory marker etc.)
+	permPart := perm & os.ModePerm
+	noPermPart := perm &^ os.ModePerm
+	// Add the x bit: make everything +x from windows
+	permPart |= 0111
+	permPart &= 0755
+
+	return noPermPart | permPart
+}
diff --git a/pkg/containerfs/containerfs.go b/pkg/containerfs/containerfs.go
new file mode 100644
index 0000000..05842ac
--- /dev/null
+++ b/pkg/containerfs/containerfs.go
@@ -0,0 +1,87 @@
+package containerfs
+
+import (
+	"path/filepath"
+	"runtime"
+
+	"github.com/containerd/continuity/driver"
+	"github.com/containerd/continuity/pathdriver"
+	"github.com/docker/docker/pkg/symlink"
+)
+
+// ContainerFS is that represents a root file system
+type ContainerFS interface {
+	// Path returns the path to the root. Note that this may not exist
+	// on the local system, so the continuity operations must be used
+	Path() string
+
+	// ResolveScopedPath evaluates the given path scoped to the root.
+	// For example, if root=/a, and path=/b/c, then this function would return /a/b/c.
+	// If rawPath is true, then the function will not preform any modifications
+	// before path resolution. Otherwise, the function will clean the given path
+	// by making it an absolute path.
+	ResolveScopedPath(path string, rawPath bool) (string, error)
+
+	Driver
+}
+
+// Driver combines both continuity's Driver and PathDriver interfaces with a Platform
+// field to determine the OS.
+type Driver interface {
+	// OS returns the OS where the rootfs is located. Essentially,
+	// runtime.GOOS for everything aside from LCOW, which is "linux"
+	OS() string
+
+	// Architecture returns the hardware architecture where the
+	// container is located.
+	Architecture() string
+
+	// Driver & PathDriver provide methods to manipulate files & paths
+	driver.Driver
+	pathdriver.PathDriver
+}
+
+// NewLocalContainerFS is a helper function to implement daemon's Mount interface
+// when the graphdriver mount point is a local path on the machine.
+func NewLocalContainerFS(path string) ContainerFS {
+	return &local{
+		path:       path,
+		Driver:     driver.LocalDriver,
+		PathDriver: pathdriver.LocalPathDriver,
+	}
+}
+
+// NewLocalDriver provides file and path drivers for a local file system. They are
+// essentially a wrapper around the `os` and `filepath` functions.
+func NewLocalDriver() Driver {
+	return &local{
+		Driver:     driver.LocalDriver,
+		PathDriver: pathdriver.LocalPathDriver,
+	}
+}
+
+type local struct {
+	path string
+	driver.Driver
+	pathdriver.PathDriver
+}
+
+func (l *local) Path() string {
+	return l.path
+}
+
+func (l *local) ResolveScopedPath(path string, rawPath bool) (string, error) {
+	cleanedPath := path
+	if !rawPath {
+		cleanedPath = cleanScopedPath(path)
+	}
+	return symlink.FollowSymlinkInScope(filepath.Join(l.path, cleanedPath), l.path)
+}
+
+func (l *local) OS() string {
+	return runtime.GOOS
+}
+
+func (l *local) Architecture() string {
+	return runtime.GOARCH
+}
diff --git a/pkg/containerfs/containerfs_unix.go b/pkg/containerfs/containerfs_unix.go
new file mode 100644
index 0000000..fbc418f
--- /dev/null
+++ b/pkg/containerfs/containerfs_unix.go
@@ -0,0 +1,10 @@
+// +build !windows
+
+package containerfs
+
+import "path/filepath"
+
+// cleanScopedPath preappends a to combine with a mnt path.
+func cleanScopedPath(path string) string {
+	return filepath.Join(string(filepath.Separator), path)
+}
diff --git a/pkg/containerfs/containerfs_windows.go b/pkg/containerfs/containerfs_windows.go
new file mode 100644
index 0000000..56f5a75
--- /dev/null
+++ b/pkg/containerfs/containerfs_windows.go
@@ -0,0 +1,15 @@
+package containerfs
+
+import "path/filepath"
+
+// cleanScopedPath removes the C:\ syntax, and prepares to combine
+// with a volume path
+func cleanScopedPath(path string) string {
+	if len(path) >= 2 {
+		c := path[0]
+		if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
+			path = path[2:]
+		}
+	}
+	return filepath.Join(string(filepath.Separator), path)
+}
diff --git a/pkg/devicemapper/devmapper.go b/pkg/devicemapper/devmapper.go
index f331970..4861876 100644
--- a/pkg/devicemapper/devmapper.go
+++ b/pkg/devicemapper/devmapper.go
@@ -9,10 +9,12 @@
 	"runtime"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
+// Same as DM_DEVICE_* enum values from libdevmapper.h
+// nolint: deadcode
 const (
 	deviceCreate TaskType = iota
 	deviceReload
@@ -349,8 +351,7 @@
 	// disable udev dm rules and delete the symlink under /dev/mapper by itself,
 	// even if the removal is deferred by the kernel.
 	cookie := new(uint)
-	var flags uint16
-	flags = DmUdevDisableLibraryFallback
+	flags := uint16(DmUdevDisableLibraryFallback)
 	if err := task.setCookie(cookie, flags); err != nil {
 		return fmt.Errorf("devicemapper: Can not set cookie: %s", err)
 	}
@@ -463,8 +464,7 @@
 	}
 
 	cookie := new(uint)
-	var flags uint16
-	flags = DmUdevDisableSubsystemRulesFlag | DmUdevDisableDiskRulesFlag | DmUdevDisableOtherRulesFlag
+	flags := uint16(DmUdevDisableSubsystemRulesFlag | DmUdevDisableDiskRulesFlag | DmUdevDisableOtherRulesFlag)
 	if err := task.setCookie(cookie, flags); err != nil {
 		return fmt.Errorf("devicemapper: Can't set cookie %s", err)
 	}
diff --git a/pkg/devicemapper/devmapper_log.go b/pkg/devicemapper/devmapper_log.go
index 098d240..f2ac7da 100644
--- a/pkg/devicemapper/devmapper_log.go
+++ b/pkg/devicemapper/devmapper_log.go
@@ -8,11 +8,11 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // DevmapperLogger defines methods required to register as a callback for
-// logging events recieved from devicemapper. Note that devicemapper will send
+// logging events received from devicemapper. Note that devicemapper will send
 // *all* logs regardless to callbacks (including debug logs) so it's
 // recommended to not spam the console with the outputs.
 type DevmapperLogger interface {
@@ -74,7 +74,7 @@
 // DMLog is the logging callback containing all of the information from
 // devicemapper. The interface is identical to the C libdm counterpart.
 func (l DefaultLogger) DMLog(level int, file string, line, dmError int, message string) {
-	if int(level) <= l.Level {
+	if level <= l.Level {
 		// Forward the log to the correct logrus level, if allowed by dmLogLevel.
 		logMsg := fmt.Sprintf("libdevmapper(%d): %s:%d (%d) %s", level, file, line, dmError, message)
 		switch level {
diff --git a/pkg/devicemapper/devmapper_wrapper.go b/pkg/devicemapper/devmapper_wrapper.go
index da3b43f..64e82df 100644
--- a/pkg/devicemapper/devmapper_wrapper.go
+++ b/pkg/devicemapper/devmapper_wrapper.go
@@ -3,7 +3,6 @@
 package devicemapper
 
 /*
-#cgo LDFLAGS: -L. -ldevmapper
 #define _GNU_SOURCE
 #include <libdevmapper.h>
 #include <linux/fs.h>   // FIXME: present only for BLKGETSIZE64, maybe we can remove it?
diff --git a/pkg/devicemapper/devmapper_wrapper_deferred_remove.go b/pkg/devicemapper/devmapper_wrapper_deferred_remove.go
index 5bdd97d..7f793c2 100644
--- a/pkg/devicemapper/devmapper_wrapper_deferred_remove.go
+++ b/pkg/devicemapper/devmapper_wrapper_deferred_remove.go
@@ -2,13 +2,10 @@
 
 package devicemapper
 
-/*
-#cgo LDFLAGS: -L. -ldevmapper
-#include <libdevmapper.h>
-*/
+// #include <libdevmapper.h>
 import "C"
 
-// LibraryDeferredRemovalSupport is supported when statically linked.
+// LibraryDeferredRemovalSupport tells if the feature is enabled in the build
 const LibraryDeferredRemovalSupport = true
 
 func dmTaskDeferredRemoveFct(task *cdmTask) int {
diff --git a/pkg/devicemapper/devmapper_wrapper_dynamic.go b/pkg/devicemapper/devmapper_wrapper_dynamic.go
new file mode 100644
index 0000000..7d84508
--- /dev/null
+++ b/pkg/devicemapper/devmapper_wrapper_dynamic.go
@@ -0,0 +1,6 @@
+// +build linux,cgo,!static_build
+
+package devicemapper
+
+// #cgo pkg-config: devmapper
+import "C"
diff --git a/pkg/devicemapper/devmapper_wrapper_no_deferred_remove.go b/pkg/devicemapper/devmapper_wrapper_no_deferred_remove.go
index 968b2ce..a880fec 100644
--- a/pkg/devicemapper/devmapper_wrapper_no_deferred_remove.go
+++ b/pkg/devicemapper/devmapper_wrapper_no_deferred_remove.go
@@ -2,7 +2,7 @@
 
 package devicemapper
 
-// LibraryDeferredRemovalSupport is not supported when statically linked.
+// LibraryDeferredRemovalSupport tells if the feature is enabled in the build
 const LibraryDeferredRemovalSupport = false
 
 func dmTaskDeferredRemoveFct(task *cdmTask) int {
diff --git a/pkg/directory/directory_unix.go b/pkg/directory/directory_unix.go
index 397251b..d4f2970 100644
--- a/pkg/directory/directory_unix.go
+++ b/pkg/directory/directory_unix.go
@@ -34,11 +34,11 @@
 		// Check inode to handle hard links correctly
 		inode := fileInfo.Sys().(*syscall.Stat_t).Ino
 		// inode is not a uint64 on all platforms. Cast it to avoid issues.
-		if _, exists := data[uint64(inode)]; exists {
+		if _, exists := data[inode]; exists {
 			return nil
 		}
 		// inode is not a uint64 on all platforms. Cast it to avoid issues.
-		data[uint64(inode)] = struct{}{}
+		data[inode] = struct{}{}
 
 		size += s
 
diff --git a/pkg/discovery/backends.go b/pkg/discovery/backends.go
index 2eab550..a25b86c 100644
--- a/pkg/discovery/backends.go
+++ b/pkg/discovery/backends.go
@@ -6,7 +6,7 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/pkg/discovery/kv/kv.go b/pkg/discovery/kv/kv.go
index 77eee7d..e860b36 100644
--- a/pkg/discovery/kv/kv.go
+++ b/pkg/discovery/kv/kv.go
@@ -6,7 +6,6 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/go-connections/tlsconfig"
 	"github.com/docker/libkv"
@@ -14,6 +13,7 @@
 	"github.com/docker/libkv/store/consul"
 	"github.com/docker/libkv/store/etcd"
 	"github.com/docker/libkv/store/zookeeper"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/pkg/discovery/kv/kv_test.go b/pkg/discovery/kv/kv_test.go
index dab3939..adc5c28 100644
--- a/pkg/discovery/kv/kv_test.go
+++ b/pkg/discovery/kv/kv_test.go
@@ -11,7 +11,6 @@
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/libkv"
 	"github.com/docker/libkv/store"
-
 	"github.com/go-check/check"
 )
 
@@ -130,7 +129,6 @@
 
 // Close mock
 func (s *Mock) Close() {
-	return
 }
 
 func (ds *DiscoverySuite) TestInitializeWithCerts(c *check.C) {
diff --git a/pkg/dmesg/dmesg_linux.go b/pkg/dmesg/dmesg_linux.go
new file mode 100644
index 0000000..7df7f3d
--- /dev/null
+++ b/pkg/dmesg/dmesg_linux.go
@@ -0,0 +1,20 @@
+// +build linux
+
+package dmesg
+
+import (
+	"unsafe"
+
+	"golang.org/x/sys/unix"
+)
+
+// Dmesg returns last messages from the kernel log, up to size bytes
+func Dmesg(size int) []byte {
+	t := uintptr(3) // SYSLOG_ACTION_READ_ALL
+	b := make([]byte, size)
+	amt, _, err := unix.Syscall(unix.SYS_SYSLOG, t, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)))
+	if err != 0 {
+		return []byte{}
+	}
+	return b[:amt]
+}
diff --git a/pkg/dmesg/dmesg_linux_test.go b/pkg/dmesg/dmesg_linux_test.go
new file mode 100644
index 0000000..c5028aa
--- /dev/null
+++ b/pkg/dmesg/dmesg_linux_test.go
@@ -0,0 +1,9 @@
+package dmesg
+
+import (
+	"testing"
+)
+
+func TestDmesg(t *testing.T) {
+	t.Logf("dmesg output follows:\n%v", string(Dmesg(512)))
+}
diff --git a/pkg/filenotify/poller.go b/pkg/filenotify/poller.go
index b90111b..1dc9482 100644
--- a/pkg/filenotify/poller.go
+++ b/pkg/filenotify/poller.go
@@ -7,7 +7,7 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 
 	"github.com/fsnotify/fsnotify"
 )
diff --git a/pkg/fileutils/fileutils.go b/pkg/fileutils/fileutils.go
index 57cc087..a129e65 100644
--- a/pkg/fileutils/fileutils.go
+++ b/pkg/fileutils/fileutils.go
@@ -10,7 +10,7 @@
 	"strings"
 	"text/scanner"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // PatternMatcher allows checking paths agaist a list of patterns
diff --git a/pkg/fileutils/fileutils_test.go b/pkg/fileutils/fileutils_test.go
index 3d61d55..2df5bdd 100644
--- a/pkg/fileutils/fileutils_test.go
+++ b/pkg/fileutils/fileutils_test.go
@@ -1,6 +1,7 @@
 package fileutils
 
 import (
+	"fmt"
 	"io/ioutil"
 	"os"
 	"path"
@@ -9,7 +10,6 @@
 	"strings"
 	"testing"
 
-	"fmt"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/pkg/fileutils/fileutils_unix.go b/pkg/fileutils/fileutils_unix.go
index d5c3abf..9e0e97b 100644
--- a/pkg/fileutils/fileutils_unix.go
+++ b/pkg/fileutils/fileutils_unix.go
@@ -7,7 +7,7 @@
 	"io/ioutil"
 	"os"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // GetTotalUsedFds Returns the number of used File Descriptors by
diff --git a/pkg/ioutils/readers_test.go b/pkg/ioutils/readers_test.go
index 9abc105..86e50d3 100644
--- a/pkg/ioutils/readers_test.go
+++ b/pkg/ioutils/readers_test.go
@@ -7,6 +7,7 @@
 	"testing"
 	"time"
 
+	"github.com/stretchr/testify/assert"
 	"golang.org/x/net/context"
 )
 
@@ -14,7 +15,7 @@
 type errorReader struct{}
 
 func (r *errorReader) Read(p []byte) (int, error) {
-	return 0, fmt.Errorf("Error reader always fail.")
+	return 0, fmt.Errorf("error reader always fail")
 }
 
 func TestReadCloserWrapperClose(t *testing.T) {
@@ -35,9 +36,7 @@
 		called = true
 	})
 	_, err := wrapper.Read([]byte{})
-	if err == nil || !strings.Contains(err.Error(), "Error reader always fail.") {
-		t.Fatalf("readErrWrapper should returned an error")
-	}
+	assert.EqualError(t, err, "error reader always fail")
 	if !called {
 		t.Fatalf("readErrWrapper should have call the anonymous function on failure")
 	}
diff --git a/pkg/jsonlog/jsonlog.go b/pkg/jsonlog/jsonlog.go
deleted file mode 100644
index 4734c31..0000000
--- a/pkg/jsonlog/jsonlog.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package jsonlog
-
-import (
-	"encoding/json"
-	"fmt"
-	"time"
-)
-
-// JSONLog represents a log message, typically a single entry from a given log stream.
-// JSONLogs can be easily serialized to and from JSON and support custom formatting.
-type JSONLog struct {
-	// Log is the log message
-	Log string `json:"log,omitempty"`
-	// Stream is the log source
-	Stream string `json:"stream,omitempty"`
-	// Created is the created timestamp of log
-	Created time.Time `json:"time"`
-	// Attrs is the list of extra attributes provided by the user
-	Attrs map[string]string `json:"attrs,omitempty"`
-}
-
-// Format returns the log formatted according to format
-// If format is nil, returns the log message
-// If format is json, returns the log marshaled in json format
-// By default, returns the log with the log time formatted according to format.
-func (jl *JSONLog) Format(format string) (string, error) {
-	if format == "" {
-		return jl.Log, nil
-	}
-	if format == "json" {
-		m, err := json.Marshal(jl)
-		return string(m), err
-	}
-	return fmt.Sprintf("%s %s", jl.Created.Format(format), jl.Log), nil
-}
-
-// Reset resets the log to nil.
-func (jl *JSONLog) Reset() {
-	jl.Log = ""
-	jl.Stream = ""
-	jl.Created = time.Time{}
-}
diff --git a/pkg/jsonlog/jsonlog_marshalling.go b/pkg/jsonlog/jsonlog_marshalling.go
deleted file mode 100644
index 83ce684..0000000
--- a/pkg/jsonlog/jsonlog_marshalling.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// This code was initially generated by ffjson <https://github.com/pquerna/ffjson>
-// This code was generated via the following steps:
-// $ go get -u github.com/pquerna/ffjson
-// $ make BIND_DIR=. shell
-// $ ffjson pkg/jsonlog/jsonlog.go
-// $ mv pkg/jsonglog/jsonlog_ffjson.go pkg/jsonlog/jsonlog_marshalling.go
-//
-// It has been modified to improve the performance of time marshalling to JSON
-// and to clean it up.
-// Should this code need to be regenerated when the JSONLog struct is changed,
-// the relevant changes which have been made are:
-// import (
-//        "bytes"
-//-
-//        "unicode/utf8"
-// )
-//
-// func (mj *JSONLog) MarshalJSON() ([]byte, error) {
-//@@ -20,13 +16,13 @@ func (mj *JSONLog) MarshalJSON() ([]byte, error) {
-//        }
-//        return buf.Bytes(), nil
-// }
-//+
-// func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
-//-       var err error
-//-       var obj []byte
-//-       var first bool = true
-//-       _ = obj
-//-       _ = err
-//-       _ = first
-//+       var (
-//+               err       error
-//+               timestamp string
-//+               first     bool = true
-//+       )
-//        buf.WriteString(`{`)
-//        if len(mj.Log) != 0 {
-//                if first == true {
-//@@ -52,11 +48,11 @@ func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
-//                buf.WriteString(`,`)
-//        }
-//        buf.WriteString(`"time":`)
-//-       obj, err = mj.Created.MarshalJSON()
-//+       timestamp, err = FastTimeMarshalJSON(mj.Created)
-//        if err != nil {
-//                return err
-//        }
-//-       buf.Write(obj)
-//+       buf.WriteString(timestamp)
-//        buf.WriteString(`}`)
-//        return nil
-// }
-// @@ -81,9 +81,10 @@ func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
-//         if len(mj.Log) != 0 {
-// -                if first == true {
-// -                       first = false
-// -               } else {
-// -                       buf.WriteString(`,`)
-// -               }
-// +               first = false
-//                 buf.WriteString(`"log":`)
-//                 ffjsonWriteJSONString(buf, mj.Log)
-//         }
-
-package jsonlog
-
-import (
-	"bytes"
-	"unicode/utf8"
-)
-
-// MarshalJSON marshals the JSONLog.
-func (mj *JSONLog) MarshalJSON() ([]byte, error) {
-	var buf bytes.Buffer
-	buf.Grow(1024)
-	if err := mj.MarshalJSONBuf(&buf); err != nil {
-		return nil, err
-	}
-	return buf.Bytes(), nil
-}
-
-// MarshalJSONBuf marshals the JSONLog and stores the result to a bytes.Buffer.
-func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
-	var (
-		err       error
-		timestamp string
-		first     = true
-	)
-	buf.WriteString(`{`)
-	if len(mj.Log) != 0 {
-		first = false
-		buf.WriteString(`"log":`)
-		ffjsonWriteJSONString(buf, mj.Log)
-	}
-	if len(mj.Stream) != 0 {
-		if first {
-			first = false
-		} else {
-			buf.WriteString(`,`)
-		}
-		buf.WriteString(`"stream":`)
-		ffjsonWriteJSONString(buf, mj.Stream)
-	}
-	if !first {
-		buf.WriteString(`,`)
-	}
-	buf.WriteString(`"time":`)
-	timestamp, err = FastTimeMarshalJSON(mj.Created)
-	if err != nil {
-		return err
-	}
-	buf.WriteString(timestamp)
-	buf.WriteString(`}`)
-	return nil
-}
-
-func ffjsonWriteJSONString(buf *bytes.Buffer, s string) {
-	const hex = "0123456789abcdef"
-
-	buf.WriteByte('"')
-	start := 0
-	for i := 0; i < len(s); {
-		if b := s[i]; b < utf8.RuneSelf {
-			if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
-				i++
-				continue
-			}
-			if start < i {
-				buf.WriteString(s[start:i])
-			}
-			switch b {
-			case '\\', '"':
-				buf.WriteByte('\\')
-				buf.WriteByte(b)
-			case '\n':
-				buf.WriteByte('\\')
-				buf.WriteByte('n')
-			case '\r':
-				buf.WriteByte('\\')
-				buf.WriteByte('r')
-			default:
-
-				buf.WriteString(`\u00`)
-				buf.WriteByte(hex[b>>4])
-				buf.WriteByte(hex[b&0xF])
-			}
-			i++
-			start = i
-			continue
-		}
-		c, size := utf8.DecodeRuneInString(s[i:])
-		if c == utf8.RuneError && size == 1 {
-			if start < i {
-				buf.WriteString(s[start:i])
-			}
-			buf.WriteString(`\ufffd`)
-			i += size
-			start = i
-			continue
-		}
-
-		if c == '\u2028' || c == '\u2029' {
-			if start < i {
-				buf.WriteString(s[start:i])
-			}
-			buf.WriteString(`\u202`)
-			buf.WriteByte(hex[c&0xF])
-			i += size
-			start = i
-			continue
-		}
-		i += size
-	}
-	if start < len(s) {
-		buf.WriteString(s[start:])
-	}
-	buf.WriteByte('"')
-}
diff --git a/pkg/jsonlog/jsonlog_marshalling_test.go b/pkg/jsonlog/jsonlog_marshalling_test.go
deleted file mode 100644
index 8b0d072..0000000
--- a/pkg/jsonlog/jsonlog_marshalling_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package jsonlog
-
-import (
-	"regexp"
-	"testing"
-)
-
-func TestJSONLogMarshalJSON(t *testing.T) {
-	logs := map[*JSONLog]string{
-		{Log: `"A log line with \\"`}:           `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":\".{20,}\"}$`,
-		{Log: "A log line"}:                     `^{\"log\":\"A log line\",\"time\":\".{20,}\"}$`,
-		{Log: "A log line with \r"}:             `^{\"log\":\"A log line with \\r\",\"time\":\".{20,}\"}$`,
-		{Log: "A log line with & < >"}:          `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":\".{20,}\"}$`,
-		{Log: "A log line with utf8 : 🚀 ψ ω β"}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":\".{20,}\"}$`,
-		{Stream: "stdout"}:                      `^{\"stream\":\"stdout\",\"time\":\".{20,}\"}$`,
-		{}:                                      `^{\"time\":\".{20,}\"}$`,
-		// These ones are a little weird
-		{Log: "\u2028 \u2029"}:      `^{\"log\":\"\\u2028 \\u2029\",\"time\":\".{20,}\"}$`,
-		{Log: string([]byte{0xaF})}: `^{\"log\":\"\\ufffd\",\"time\":\".{20,}\"}$`,
-		{Log: string([]byte{0x7F})}: `^{\"log\":\"\x7f\",\"time\":\".{20,}\"}$`,
-	}
-	for jsonLog, expression := range logs {
-		data, err := jsonLog.MarshalJSON()
-		if err != nil {
-			t.Fatal(err)
-		}
-		res := string(data)
-		t.Logf("Result of WriteLog: %q", res)
-		logRe := regexp.MustCompile(expression)
-		if !logRe.MatchString(res) {
-			t.Fatalf("Log line not in expected format [%v]: %q", expression, res)
-		}
-	}
-}
diff --git a/pkg/jsonlog/jsonlogbytes_test.go b/pkg/jsonlog/jsonlogbytes_test.go
deleted file mode 100644
index 41049aa..0000000
--- a/pkg/jsonlog/jsonlogbytes_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package jsonlog
-
-import (
-	"bytes"
-	"regexp"
-	"testing"
-)
-
-func TestJSONLogsMarshalJSONBuf(t *testing.T) {
-	logs := map[*JSONLogs]string{
-		{Log: []byte(`"A log line with \\"`)}:           `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":}$`,
-		{Log: []byte("A log line")}:                     `^{\"log\":\"A log line\",\"time\":}$`,
-		{Log: []byte("A log line with \r")}:             `^{\"log\":\"A log line with \\r\",\"time\":}$`,
-		{Log: []byte("A log line with & < >")}:          `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":}$`,
-		{Log: []byte("A log line with utf8 : 🚀 ψ ω β")}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":}$`,
-		{Stream: "stdout"}:                              `^{\"stream\":\"stdout\",\"time\":}$`,
-		{Stream: "stdout", Log: []byte("A log line")}:   `^{\"log\":\"A log line\",\"stream\":\"stdout\",\"time\":}$`,
-		{Created: "time"}:                               `^{\"time\":time}$`,
-		{}:                                              `^{\"time\":}$`,
-		// These ones are a little weird
-		{Log: []byte("\u2028 \u2029")}: `^{\"log\":\"\\u2028 \\u2029\",\"time\":}$`,
-		{Log: []byte{0xaF}}:            `^{\"log\":\"\\ufffd\",\"time\":}$`,
-		{Log: []byte{0x7F}}:            `^{\"log\":\"\x7f\",\"time\":}$`,
-		// with raw attributes
-		{Log: []byte("A log line"), RawAttrs: []byte(`{"hello":"world","value":1234}`)}: `^{\"log\":\"A log line\",\"attrs\":{\"hello\":\"world\",\"value\":1234},\"time\":}$`,
-	}
-	for jsonLog, expression := range logs {
-		var buf bytes.Buffer
-		if err := jsonLog.MarshalJSONBuf(&buf); err != nil {
-			t.Fatal(err)
-		}
-		res := buf.String()
-		t.Logf("Result of WriteLog: %q", res)
-		logRe := regexp.MustCompile(expression)
-		if !logRe.MatchString(res) {
-			t.Fatalf("Log line not in expected format [%v]: %q", expression, res)
-		}
-	}
-}
diff --git a/pkg/jsonlog/time_marshalling.go b/pkg/jsonlog/time_marshalling.go
deleted file mode 100644
index 2117338..0000000
--- a/pkg/jsonlog/time_marshalling.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Package jsonlog provides helper functions to parse and print time (time.Time) as JSON.
-package jsonlog
-
-import (
-	"errors"
-	"time"
-)
-
-const (
-	// RFC3339NanoFixed is our own version of RFC339Nano because we want one
-	// that pads the nano seconds part with zeros to ensure
-	// the timestamps are aligned in the logs.
-	RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
-	// JSONFormat is the format used by FastMarshalJSON
-	JSONFormat = `"` + time.RFC3339Nano + `"`
-)
-
-// FastTimeMarshalJSON avoids one of the extra allocations that
-// time.MarshalJSON is making.
-func FastTimeMarshalJSON(t time.Time) (string, error) {
-	if y := t.Year(); y < 0 || y >= 10000 {
-		// RFC 3339 is clear that years are 4 digits exactly.
-		// See golang.org/issue/4556#c15 for more discussion.
-		return "", errors.New("time.MarshalJSON: year outside of range [0,9999]")
-	}
-	return t.Format(JSONFormat), nil
-}
diff --git a/pkg/jsonlog/time_marshalling_test.go b/pkg/jsonlog/time_marshalling_test.go
deleted file mode 100644
index 02d0302..0000000
--- a/pkg/jsonlog/time_marshalling_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package jsonlog
-
-import (
-	"testing"
-	"time"
-)
-
-// Testing to ensure 'year' fields is between 0 and 9999
-func TestFastTimeMarshalJSONWithInvalidDate(t *testing.T) {
-	aTime := time.Date(-1, 1, 1, 0, 0, 0, 0, time.Local)
-	json, err := FastTimeMarshalJSON(aTime)
-	if err == nil {
-		t.Fatalf("FastTimeMarshalJSON should throw an error, but was '%v'", json)
-	}
-	anotherTime := time.Date(10000, 1, 1, 0, 0, 0, 0, time.Local)
-	json, err = FastTimeMarshalJSON(anotherTime)
-	if err == nil {
-		t.Fatalf("FastTimeMarshalJSON should throw an error, but was '%v'", json)
-	}
-
-}
-
-func TestFastTimeMarshalJSON(t *testing.T) {
-	aTime := time.Date(2015, 5, 29, 11, 1, 2, 3, time.UTC)
-	json, err := FastTimeMarshalJSON(aTime)
-	if err != nil {
-		t.Fatal(err)
-	}
-	expected := "\"2015-05-29T11:01:02.000000003Z\""
-	if json != expected {
-		t.Fatalf("Expected %v, got %v", expected, json)
-	}
-
-	location, err := time.LoadLocation("Europe/Paris")
-	if err != nil {
-		t.Fatal(err)
-	}
-	aTime = time.Date(2015, 5, 29, 11, 1, 2, 3, location)
-	json, err = FastTimeMarshalJSON(aTime)
-	if err != nil {
-		t.Fatal(err)
-	}
-	expected = "\"2015-05-29T11:01:02.000000003+02:00\""
-	if json != expected {
-		t.Fatalf("Expected %v, got %v", expected, json)
-	}
-}
diff --git a/pkg/jsonmessage/jsonmessage.go b/pkg/jsonmessage/jsonmessage.go
index dc785d6..6cfa464 100644
--- a/pkg/jsonmessage/jsonmessage.go
+++ b/pkg/jsonmessage/jsonmessage.go
@@ -8,13 +8,15 @@
 	"strings"
 	"time"
 
-	"github.com/Nvveen/Gotty"
-
-	"github.com/docker/docker/pkg/jsonlog"
+	gotty "github.com/Nvveen/Gotty"
 	"github.com/docker/docker/pkg/term"
-	"github.com/docker/go-units"
+	units "github.com/docker/go-units"
 )
 
+// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to
+// ensure the formatted time isalways the same number of characters.
+const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
+
 // JSONError wraps a concrete Code and Message, `Code` is
 // is an integer error code, `Message` is the error message.
 type JSONError struct {
@@ -187,7 +189,7 @@
 func (jm *JSONMessage) Display(out io.Writer, termInfo termInfo) error {
 	if jm.Error != nil {
 		if jm.Error.Code == 401 {
-			return fmt.Errorf("Authentication is required.")
+			return fmt.Errorf("authentication is required")
 		}
 		return jm.Error
 	}
@@ -200,9 +202,9 @@
 		return nil
 	}
 	if jm.TimeNano != 0 {
-		fmt.Fprintf(out, "%s ", time.Unix(0, jm.TimeNano).Format(jsonlog.RFC3339NanoFixed))
+		fmt.Fprintf(out, "%s ", time.Unix(0, jm.TimeNano).Format(RFC3339NanoFixed))
 	} else if jm.Time != 0 {
-		fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(jsonlog.RFC3339NanoFixed))
+		fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(RFC3339NanoFixed))
 	}
 	if jm.ID != "" {
 		fmt.Fprintf(out, "%s: ", jm.ID)
diff --git a/pkg/jsonmessage/jsonmessage_test.go b/pkg/jsonmessage/jsonmessage_test.go
index c3ed6c0..9740bcd 100644
--- a/pkg/jsonmessage/jsonmessage_test.go
+++ b/pkg/jsonmessage/jsonmessage_test.go
@@ -8,8 +8,8 @@
 	"testing"
 	"time"
 
-	"github.com/docker/docker/pkg/jsonlog"
 	"github.com/docker/docker/pkg/term"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestError(t *testing.T) {
@@ -114,8 +114,8 @@
 			From:   "From",
 			Status: "status",
 		}: {
-			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now.Unix(), 0).Format(jsonlog.RFC3339NanoFixed)),
-			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now.Unix(), 0).Format(jsonlog.RFC3339NanoFixed)),
+			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now.Unix(), 0).Format(RFC3339NanoFixed)),
+			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now.Unix(), 0).Format(RFC3339NanoFixed)),
 		},
 		// General, with nano precision time
 		{
@@ -124,8 +124,8 @@
 			From:     "From",
 			Status:   "status",
 		}: {
-			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
-			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
+			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(RFC3339NanoFixed)),
+			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(RFC3339NanoFixed)),
 		},
 		// General, with both times Nano is preferred
 		{
@@ -135,8 +135,8 @@
 			From:     "From",
 			Status:   "status",
 		}: {
-			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
-			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
+			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(RFC3339NanoFixed)),
+			fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(RFC3339NanoFixed)),
 		},
 		// Stream over status
 		{
@@ -198,9 +198,7 @@
 
 	jsonMessage = JSONMessage{Error: &JSONError{401, "Anything"}}
 	err = jsonMessage.Display(data, &noTermInfo{})
-	if err == nil || err.Error() != "Authentication is required." {
-		t.Fatalf("Expected an error \"Authentication is required.\", got %q", err)
-	}
+	assert.EqualError(t, err, "authentication is required")
 }
 
 func TestDisplayJSONMessagesStreamInvalidJSON(t *testing.T) {
diff --git a/pkg/locker/README.md b/pkg/locker/README.md
index c8dbddc..ce787ae 100644
--- a/pkg/locker/README.md
+++ b/pkg/locker/README.md
@@ -35,7 +35,7 @@
 func (i *important) Get(name string) interface{} {
 	i.locks.Lock(name)
 	defer i.locks.Unlock(name)
-	return data[name]
+	return i.data[name]
 }
 
 func (i *important) Create(name string, data interface{}) {
@@ -44,9 +44,9 @@
 
 	i.createImportant(data)
 
-	s.mu.Lock()
+	i.mu.Lock()
 	i.data[name] = data
-	s.mu.Unlock()
+	i.mu.Unlock()
 }
 
 func (i *important) createImportant(data interface{}) {
diff --git a/pkg/locker/locker_test.go b/pkg/locker/locker_test.go
index 5a297dd..39633c9 100644
--- a/pkg/locker/locker_test.go
+++ b/pkg/locker/locker_test.go
@@ -1,6 +1,8 @@
 package locker
 
 import (
+	"math/rand"
+	"strconv"
 	"sync"
 	"testing"
 	"time"
@@ -122,3 +124,38 @@
 		t.Fatalf("lock should not exist: %v", ctr)
 	}
 }
+
+func BenchmarkLocker(b *testing.B) {
+	l := New()
+	for i := 0; i < b.N; i++ {
+		l.Lock("test")
+		l.Unlock("test")
+	}
+}
+
+func BenchmarkLockerParallel(b *testing.B) {
+	l := New()
+	b.SetParallelism(128)
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			l.Lock("test")
+			l.Unlock("test")
+		}
+	})
+}
+
+func BenchmarkLockerMoreKeys(b *testing.B) {
+	l := New()
+	var keys []string
+	for i := 0; i < 64; i++ {
+		keys = append(keys, strconv.Itoa(i))
+	}
+	b.SetParallelism(128)
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			k := keys[rand.Intn(len(keys))]
+			l.Lock(k)
+			l.Unlock(k)
+		}
+	})
+}
diff --git a/pkg/loopback/attach_loopback.go b/pkg/loopback/attach_loopback.go
index 6ea9a30..27326d7 100644
--- a/pkg/loopback/attach_loopback.go
+++ b/pkg/loopback/attach_loopback.go
@@ -7,7 +7,7 @@
 	"fmt"
 	"os"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/pkg/loopback/ioctl.go b/pkg/loopback/ioctl.go
index fa744f0..84fcea6 100644
--- a/pkg/loopback/ioctl.go
+++ b/pkg/loopback/ioctl.go
@@ -17,10 +17,7 @@
 }
 
 func ioctlLoopSetFd(loopFd, sparseFd uintptr) error {
-	if err := unix.IoctlSetInt(int(loopFd), LoopSetFd, int(sparseFd)); err != nil {
-		return err
-	}
-	return nil
+	return unix.IoctlSetInt(int(loopFd), LoopSetFd, int(sparseFd))
 }
 
 func ioctlLoopSetStatus64(loopFd uintptr, loopInfo *loopInfo64) error {
@@ -47,8 +44,5 @@
 }
 
 func ioctlLoopSetCapacity(loopFd uintptr, value int) error {
-	if err := unix.IoctlSetInt(int(loopFd), LoopSetCapacity, value); err != nil {
-		return err
-	}
-	return nil
+	return unix.IoctlSetInt(int(loopFd), LoopSetCapacity, value)
 }
diff --git a/pkg/loopback/loopback.go b/pkg/loopback/loopback.go
index 36f433d..c620c63 100644
--- a/pkg/loopback/loopback.go
+++ b/pkg/loopback/loopback.go
@@ -6,7 +6,7 @@
 	"fmt"
 	"os"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/pkg/mount/mounter_linux_test.go b/pkg/mount/mounter_linux_test.go
index 47c03b3..f02bd13 100644
--- a/pkg/mount/mounter_linux_test.go
+++ b/pkg/mount/mounter_linux_test.go
@@ -8,6 +8,8 @@
 	"os"
 	"strings"
 	"testing"
+
+	selinux "github.com/opencontainers/selinux/go-selinux"
 )
 
 func TestMount(t *testing.T) {
@@ -101,7 +103,11 @@
 				t.Fatal(err)
 			}
 			defer ensureUnmount(t, target)
-			validateMount(t, target, tc.expectedOpts, tc.expectedOptional, tc.expectedVFS)
+			expectedVFS := tc.expectedVFS
+			if selinux.GetEnabled() && expectedVFS != "" {
+				expectedVFS = expectedVFS + ",seclabel"
+			}
+			validateMount(t, target, tc.expectedOpts, tc.expectedOptional, expectedVFS)
 		})
 	}
 }
diff --git a/pkg/mount/mounter_solaris.go b/pkg/mount/mounter_solaris.go
index c684aa8..48b8677 100644
--- a/pkg/mount/mounter_solaris.go
+++ b/pkg/mount/mounter_solaris.go
@@ -3,8 +3,9 @@
 package mount
 
 import (
-	"golang.org/x/sys/unix"
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 // #include <stdlib.h>
diff --git a/pkg/mount/mountinfo_solaris.go b/pkg/mount/mountinfo_solaris.go
index ad9ab57..069ed8f 100644
--- a/pkg/mount/mountinfo_solaris.go
+++ b/pkg/mount/mountinfo_solaris.go
@@ -4,16 +4,23 @@
 
 /*
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/mnttab.h>
 */
 import "C"
 
 import (
 	"fmt"
+	"unsafe"
 )
 
 func parseMountTable() ([]*Info, error) {
-	mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r"))
+	path := C.CString(C.MNTTAB)
+	defer C.free(unsafe.Pointer(path))
+	mode := C.CString("r")
+	defer C.free(unsafe.Pointer(mode))
+
+	mnttab := C.fopen(path, mode)
 	if mnttab == nil {
 		return nil, fmt.Errorf("Failed to open %s", C.MNTTAB)
 	}
diff --git a/pkg/parsers/kernel/kernel_unix.go b/pkg/parsers/kernel/kernel_unix.go
index bd137df..76e1e49 100644
--- a/pkg/parsers/kernel/kernel_unix.go
+++ b/pkg/parsers/kernel/kernel_unix.go
@@ -7,7 +7,7 @@
 import (
 	"bytes"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // GetKernelVersion gets the current kernel version.
diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go
index e4b0312..2845c3c 100644
--- a/pkg/platform/platform.go
+++ b/pkg/platform/platform.go
@@ -3,7 +3,7 @@
 import (
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/pkg/plugins/client.go b/pkg/plugins/client.go
index f221a46..9ee1f89 100644
--- a/pkg/plugins/client.go
+++ b/pkg/plugins/client.go
@@ -9,10 +9,10 @@
 	"net/url"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/plugins/transport"
 	"github.com/docker/go-connections/sockets"
 	"github.com/docker/go-connections/tlsconfig"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/pkg/plugins/discovery_unix_test.go b/pkg/plugins/discovery_unix_test.go
index 66f5035..e4d156d 100644
--- a/pkg/plugins/discovery_unix_test.go
+++ b/pkg/plugins/discovery_unix_test.go
@@ -10,6 +10,8 @@
 	"path/filepath"
 	"reflect"
 	"testing"
+
+	"github.com/stretchr/testify/require"
 )
 
 func TestLocalSocket(t *testing.T) {
@@ -89,6 +91,7 @@
 
 	r := newLocalRegistry()
 	p, err := r.Plugin(name)
+	require.NoError(t, err)
 
 	pluginNamesNotEmpty, err := Scan()
 	if err != nil {
diff --git a/pkg/plugins/pluginrpc-gen/fixtures/foo.go b/pkg/plugins/pluginrpc-gen/fixtures/foo.go
index 5695dcc..4dd1d6d 100644
--- a/pkg/plugins/pluginrpc-gen/fixtures/foo.go
+++ b/pkg/plugins/pluginrpc-gen/fixtures/foo.go
@@ -1,17 +1,11 @@
 package foo
 
 import (
-	"fmt"
-
 	aliasedio "io"
 
 	"github.com/docker/docker/pkg/plugins/pluginrpc-gen/fixtures/otherfixture"
 )
 
-var (
-	errFakeImport = fmt.Errorf("just to import fmt for imports tests")
-)
-
 type wobble struct {
 	Some      string
 	Val       string
diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go
index c0059cb..f9033ed 100644
--- a/pkg/plugins/plugins.go
+++ b/pkg/plugins/plugins.go
@@ -27,8 +27,8 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/go-connections/tlsconfig"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/pkg/pools/pools_test.go b/pkg/pools/pools_test.go
index d71cb99..544c499 100644
--- a/pkg/pools/pools_test.go
+++ b/pkg/pools/pools_test.go
@@ -6,6 +6,9 @@
 	"io"
 	"strings"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestBufioReaderPoolGetWithNoReaderShouldCreateOne(t *testing.T) {
@@ -92,22 +95,16 @@
 	buf := new(bytes.Buffer)
 	bw := bufio.NewWriter(buf)
 	writer := BufioWriter32KPool.Get(bw)
-	if writer == nil {
-		t.Fatalf("BufioReaderPool should not return a nil writer.")
-	}
+	require.NotNil(t, writer)
+
 	written, err := writer.Write([]byte("foobar"))
-	if err != nil {
-		t.Fatal(err)
-	}
-	if written != 6 {
-		t.Fatalf("Should have written 6 bytes, but wrote %v bytes", written)
-	}
+	require.NoError(t, err)
+	assert.Equal(t, 6, written)
+
 	// Make sure we Flush all the way ?
 	writer.Flush()
 	bw.Flush()
-	if len(buf.Bytes()) != 6 {
-		t.Fatalf("The buffer should contain 6 bytes ('foobar') but contains %v ('%v')", buf.Bytes(), string(buf.Bytes()))
-	}
+	assert.Len(t, buf.Bytes(), 6)
 	// Reset the buffer
 	buf.Reset()
 	BufioWriter32KPool.Put(writer)
diff --git a/pkg/promise/promise.go b/pkg/promise/promise.go
deleted file mode 100644
index dd52b90..0000000
--- a/pkg/promise/promise.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package promise
-
-// Go is a basic promise implementation: it wraps calls a function in a goroutine,
-// and returns a channel which will later return the function's return value.
-func Go(f func() error) chan error {
-	ch := make(chan error, 1)
-	go func() {
-		ch <- f()
-	}()
-	return ch
-}
diff --git a/pkg/promise/promise_test.go b/pkg/promise/promise_test.go
deleted file mode 100644
index 287213b..0000000
--- a/pkg/promise/promise_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package promise
-
-import (
-	"errors"
-	"testing"
-
-	"github.com/stretchr/testify/require"
-)
-
-func TestGo(t *testing.T) {
-	errCh := Go(functionWithError)
-	er := <-errCh
-	require.EqualValues(t, "Error Occurred", er.Error())
-
-	noErrCh := Go(functionWithNoError)
-	er = <-noErrCh
-	require.Nil(t, er)
-}
-
-func functionWithError() (err error) {
-	return errors.New("Error Occurred")
-}
-func functionWithNoError() (err error) {
-	return nil
-}
diff --git a/pkg/signal/signal_linux_test.go b/pkg/signal/signal_linux_test.go
index 32c056fe..da0e010 100644
--- a/pkg/signal/signal_linux_test.go
+++ b/pkg/signal/signal_linux_test.go
@@ -41,7 +41,7 @@
 }
 
 func TestStopCatch(t *testing.T) {
-	signal, _ := SignalMap["HUP"]
+	signal := SignalMap["HUP"]
 	channel := make(chan os.Signal, 1)
 	CatchAll(channel)
 	go func() {
diff --git a/pkg/signal/testfiles/main.go b/pkg/signal/testfiles/main.go
new file mode 100644
index 0000000..e56854c
--- /dev/null
+++ b/pkg/signal/testfiles/main.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+	"os"
+	"syscall"
+	"time"
+
+	"github.com/docker/docker/pkg/signal"
+	"github.com/sirupsen/logrus"
+)
+
+func main() {
+	sigmap := map[string]os.Signal{
+		"TERM": syscall.SIGTERM,
+		"QUIT": syscall.SIGQUIT,
+		"INT":  os.Interrupt,
+	}
+	signal.Trap(func() {
+		time.Sleep(time.Second)
+		os.Exit(99)
+	}, logrus.StandardLogger())
+	go func() {
+		p, err := os.FindProcess(os.Getpid())
+		if err != nil {
+			panic(err)
+		}
+		s := os.Getenv("SIGNAL_TYPE")
+		multiple := os.Getenv("IF_MULTIPLE")
+		switch s {
+		case "TERM", "INT":
+			if multiple == "1" {
+				for {
+					p.Signal(sigmap[s])
+				}
+			} else {
+				p.Signal(sigmap[s])
+			}
+		case "QUIT":
+			p.Signal(sigmap[s])
+		}
+	}()
+	time.Sleep(2 * time.Second)
+}
diff --git a/pkg/signal/trap.go b/pkg/signal/trap.go
index 638a1ab..2884dfe 100644
--- a/pkg/signal/trap.go
+++ b/pkg/signal/trap.go
@@ -11,7 +11,6 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/pkg/errors"
 )
 
@@ -27,7 +26,9 @@
 //   the docker daemon is not restarted and also running under systemd.
 //   Fixes https://github.com/docker/docker/issues/19728
 //
-func Trap(cleanup func()) {
+func Trap(cleanup func(), logger interface {
+	Info(args ...interface{})
+}) {
 	c := make(chan os.Signal, 1)
 	// we will handle INT, TERM, QUIT, SIGPIPE here
 	signals := []os.Signal{os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE}
@@ -40,7 +41,7 @@
 			}
 
 			go func(sig os.Signal) {
-				logrus.Infof("Processing signal '%v'", sig)
+				logger.Info(fmt.Sprintf("Processing signal '%v'", sig))
 				switch sig {
 				case os.Interrupt, syscall.SIGTERM:
 					if atomic.LoadUint32(&interruptCount) < 3 {
@@ -54,11 +55,11 @@
 						}
 					} else {
 						// 3 SIGTERM/INT signals received; force exit without cleanup
-						logrus.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
+						logger.Info("Forcing docker daemon shutdown without cleanup; 3 interrupts received")
 					}
 				case syscall.SIGQUIT:
 					DumpStacks("")
-					logrus.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT")
+					logger.Info("Forcing docker daemon shutdown without cleanup on SIGQUIT")
 				}
 				//for the SIGINT/TERM, and SIGQUIT non-clean shutdown case, exit with 128 + signal #
 				os.Exit(128 + int(sig.(syscall.Signal)))
diff --git a/pkg/signal/trap_linux_test.go b/pkg/signal/trap_linux_test.go
new file mode 100644
index 0000000..2622766
--- /dev/null
+++ b/pkg/signal/trap_linux_test.go
@@ -0,0 +1,82 @@
+// +build linux
+
+package signal
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"syscall"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func buildTestBinary(t *testing.T, tmpdir string, prefix string) (string, string) {
+	tmpDir, err := ioutil.TempDir(tmpdir, prefix)
+	require.NoError(t, err)
+	exePath := tmpDir + "/" + prefix
+	wd, _ := os.Getwd()
+	testHelperCode := wd + "/testfiles/main.go"
+	cmd := exec.Command("go", "build", "-o", exePath, testHelperCode)
+	err = cmd.Run()
+	require.NoError(t, err)
+	return exePath, tmpDir
+}
+
+func TestTrap(t *testing.T) {
+	var sigmap = []struct {
+		name     string
+		signal   os.Signal
+		multiple bool
+	}{
+		{"TERM", syscall.SIGTERM, false},
+		{"QUIT", syscall.SIGQUIT, true},
+		{"INT", os.Interrupt, false},
+		{"TERM", syscall.SIGTERM, true},
+		{"INT", os.Interrupt, true},
+	}
+	exePath, tmpDir := buildTestBinary(t, "", "main")
+	defer os.RemoveAll(tmpDir)
+
+	for _, v := range sigmap {
+		cmd := exec.Command(exePath)
+		cmd.Env = append(os.Environ(), fmt.Sprintf("SIGNAL_TYPE=%s", v.name))
+		if v.multiple {
+			cmd.Env = append(cmd.Env, "IF_MULTIPLE=1")
+		}
+		err := cmd.Start()
+		require.NoError(t, err)
+		err = cmd.Wait()
+		if e, ok := err.(*exec.ExitError); ok {
+			code := e.Sys().(syscall.WaitStatus).ExitStatus()
+			if v.multiple {
+				assert.Equal(t, 128+int(v.signal.(syscall.Signal)), code)
+			} else {
+				assert.Equal(t, 99, code)
+			}
+			continue
+		}
+		t.Fatal("process didn't end with any error")
+	}
+
+}
+
+func TestDumpStacks(t *testing.T) {
+	directory, err := ioutil.TempDir("", "test-dump-tasks")
+	assert.NoError(t, err)
+	defer os.RemoveAll(directory)
+	dumpPath, err := DumpStacks(directory)
+	assert.NoError(t, err)
+	readFile, _ := ioutil.ReadFile(dumpPath)
+	fileData := string(readFile)
+	assert.Contains(t, fileData, "goroutine")
+}
+
+func TestDumpStacksWithEmptyInput(t *testing.T) {
+	path, err := DumpStacks("")
+	assert.NoError(t, err)
+	assert.Equal(t, os.Stderr.Name(), path)
+}
diff --git a/pkg/streamformatter/streamwriter_test.go b/pkg/streamformatter/streamwriter_test.go
index 4935cc5..a3c026a 100644
--- a/pkg/streamformatter/streamwriter_test.go
+++ b/pkg/streamformatter/streamwriter_test.go
@@ -1,9 +1,9 @@
 package streamformatter
 
 import (
+	"bytes"
 	"testing"
 
-	"bytes"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
diff --git a/pkg/sysinfo/sysinfo_linux.go b/pkg/sysinfo/sysinfo_linux.go
index 50ae265..471f786 100644
--- a/pkg/sysinfo/sysinfo_linux.go
+++ b/pkg/sysinfo/sysinfo_linux.go
@@ -7,8 +7,8 @@
 	"path"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/opencontainers/runc/libcontainer/cgroups"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
diff --git a/pkg/system/events_windows.go b/pkg/system/events_windows.go
deleted file mode 100644
index 192e367..0000000
--- a/pkg/system/events_windows.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package system
-
-// This file implements syscalls for Win32 events which are not implemented
-// in golang.
-
-import (
-	"syscall"
-	"unsafe"
-
-	"golang.org/x/sys/windows"
-)
-
-var (
-	procCreateEvent = modkernel32.NewProc("CreateEventW")
-	procOpenEvent   = modkernel32.NewProc("OpenEventW")
-	procSetEvent    = modkernel32.NewProc("SetEvent")
-	procResetEvent  = modkernel32.NewProc("ResetEvent")
-	procPulseEvent  = modkernel32.NewProc("PulseEvent")
-)
-
-// CreateEvent implements win32 CreateEventW func in golang. It will create an event object.
-func CreateEvent(eventAttributes *windows.SecurityAttributes, manualReset bool, initialState bool, name string) (handle windows.Handle, err error) {
-	namep, _ := windows.UTF16PtrFromString(name)
-	var _p1 uint32
-	if manualReset {
-		_p1 = 1
-	}
-	var _p2 uint32
-	if initialState {
-		_p2 = 1
-	}
-	r0, _, e1 := procCreateEvent.Call(uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(namep)))
-	use(unsafe.Pointer(namep))
-	handle = windows.Handle(r0)
-	if handle == windows.InvalidHandle {
-		err = e1
-	}
-	return
-}
-
-// OpenEvent implements win32 OpenEventW func in golang. It opens an event object.
-func OpenEvent(desiredAccess uint32, inheritHandle bool, name string) (handle windows.Handle, err error) {
-	namep, _ := windows.UTF16PtrFromString(name)
-	var _p1 uint32
-	if inheritHandle {
-		_p1 = 1
-	}
-	r0, _, e1 := procOpenEvent.Call(uintptr(desiredAccess), uintptr(_p1), uintptr(unsafe.Pointer(namep)))
-	use(unsafe.Pointer(namep))
-	handle = windows.Handle(r0)
-	if handle == windows.InvalidHandle {
-		err = e1
-	}
-	return
-}
-
-// SetEvent implements win32 SetEvent func in golang.
-func SetEvent(handle windows.Handle) (err error) {
-	return setResetPulse(handle, procSetEvent)
-}
-
-// ResetEvent implements win32 ResetEvent func in golang.
-func ResetEvent(handle windows.Handle) (err error) {
-	return setResetPulse(handle, procResetEvent)
-}
-
-// PulseEvent implements win32 PulseEvent func in golang.
-func PulseEvent(handle windows.Handle) (err error) {
-	return setResetPulse(handle, procPulseEvent)
-}
-
-func setResetPulse(handle windows.Handle, proc *windows.LazyProc) (err error) {
-	r0, _, _ := proc.Call(uintptr(handle))
-	if r0 != 0 {
-		err = syscall.Errno(r0)
-	}
-	return
-}
-
-var temp unsafe.Pointer
-
-// use ensures a variable is kept alive without the GC freeing while still needed
-func use(p unsafe.Pointer) {
-	temp = p
-}
diff --git a/pkg/system/init_unix.go b/pkg/system/init_unix.go
new file mode 100644
index 0000000..a219895
--- /dev/null
+++ b/pkg/system/init_unix.go
@@ -0,0 +1,7 @@
+// +build !windows
+
+package system
+
+// InitLCOW does nothing since LCOW is a windows only feature
+func InitLCOW(experimental bool) {
+}
diff --git a/pkg/system/init_windows.go b/pkg/system/init_windows.go
index 019c664..e751837 100644
--- a/pkg/system/init_windows.go
+++ b/pkg/system/init_windows.go
@@ -8,9 +8,10 @@
 // on build number. @jhowardmsft
 var lcowSupported = false
 
-func init() {
+// InitLCOW sets whether LCOW is supported or not
+func InitLCOW(experimental bool) {
 	// LCOW initialization
-	if os.Getenv("LCOW_SUPPORTED") != "" {
+	if experimental && os.Getenv("LCOW_SUPPORTED") != "" {
 		lcowSupported = true
 	}
 
diff --git a/pkg/system/path.go b/pkg/system/path.go
index f634a6b..4160616 100644
--- a/pkg/system/path.go
+++ b/pkg/system/path.go
@@ -1,6 +1,13 @@
 package system
 
-import "runtime"
+import (
+	"fmt"
+	"path/filepath"
+	"runtime"
+	"strings"
+
+	"github.com/containerd/continuity/pathdriver"
+)
 
 const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 
@@ -19,3 +26,35 @@
 	return defaultUnixPathEnv
 
 }
+
+// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
+// is the system drive.
+// On Linux: this is a no-op.
+// On Windows: this does the following>
+// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
+// This is used, for example, when validating a user provided path in docker cp.
+// If a drive letter is supplied, it must be the system drive. The drive letter
+// is always removed. Also, it translates it to OS semantics (IOW / to \). We
+// need the path in this syntax so that it can ultimately be contatenated with
+// a Windows long-path which doesn't support drive-letters. Examples:
+// C:			--> Fail
+// C:\			--> \
+// a			--> a
+// /a			--> \a
+// d:\			--> Fail
+func CheckSystemDriveAndRemoveDriveLetter(path string, driver pathdriver.PathDriver) (string, error) {
+	if runtime.GOOS != "windows" || LCOWSupported() {
+		return path, nil
+	}
+
+	if len(path) == 2 && string(path[1]) == ":" {
+		return "", fmt.Errorf("No relative path specified in %q", path)
+	}
+	if !driver.IsAbs(path) || len(path) < 2 {
+		return filepath.FromSlash(path), nil
+	}
+	if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") {
+		return "", fmt.Errorf("The specified path is not on the system drive (C:)")
+	}
+	return filepath.FromSlash(path[2:]), nil
+}
diff --git a/pkg/system/path_unix.go b/pkg/system/path_unix.go
deleted file mode 100644
index f3762e6..0000000
--- a/pkg/system/path_unix.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build !windows
-
-package system
-
-// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
-// is the system drive. This is a no-op on Linux.
-func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
-	return path, nil
-}
diff --git a/pkg/system/path_windows.go b/pkg/system/path_windows.go
deleted file mode 100644
index aab8915..0000000
--- a/pkg/system/path_windows.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// +build windows
-
-package system
-
-import (
-	"fmt"
-	"path/filepath"
-	"strings"
-)
-
-// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
-// This is used, for example, when validating a user provided path in docker cp.
-// If a drive letter is supplied, it must be the system drive. The drive letter
-// is always removed. Also, it translates it to OS semantics (IOW / to \). We
-// need the path in this syntax so that it can ultimately be concatenated with
-// a Windows long-path which doesn't support drive-letters. Examples:
-// C:			--> Fail
-// C:\			--> \
-// a			--> a
-// /a			--> \a
-// d:\			--> Fail
-func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
-	if len(path) == 2 && string(path[1]) == ":" {
-		return "", fmt.Errorf("No relative path specified in %q", path)
-	}
-	if !filepath.IsAbs(path) || len(path) < 2 {
-		return filepath.FromSlash(path), nil
-	}
-	if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") {
-		return "", fmt.Errorf("The specified path is not on the system drive (C:)")
-	}
-	return filepath.FromSlash(path[2:]), nil
-}
diff --git a/pkg/system/path_windows_test.go b/pkg/system/path_windows_test.go
index eccb26a..0e6bcab 100644
--- a/pkg/system/path_windows_test.go
+++ b/pkg/system/path_windows_test.go
@@ -2,18 +2,23 @@
 
 package system
 
-import "testing"
+import (
+	"testing"
+
+	"github.com/containerd/continuity/pathdriver"
+)
 
 // TestCheckSystemDriveAndRemoveDriveLetter tests CheckSystemDriveAndRemoveDriveLetter
 func TestCheckSystemDriveAndRemoveDriveLetter(t *testing.T) {
 	// Fails if not C drive.
-	path, err := CheckSystemDriveAndRemoveDriveLetter(`d:\`)
+	_, err := CheckSystemDriveAndRemoveDriveLetter(`d:\`, pathdriver.LocalPathDriver)
 	if err == nil || (err != nil && err.Error() != "The specified path is not on the system drive (C:)") {
 		t.Fatalf("Expected error for d:")
 	}
 
 	// Single character is unchanged
-	if path, err = CheckSystemDriveAndRemoveDriveLetter("z"); err != nil {
+	var path string
+	if path, err = CheckSystemDriveAndRemoveDriveLetter("z", pathdriver.LocalPathDriver); err != nil {
 		t.Fatalf("Single character should pass")
 	}
 	if path != "z" {
@@ -21,7 +26,7 @@
 	}
 
 	// Two characters without colon is unchanged
-	if path, err = CheckSystemDriveAndRemoveDriveLetter("AB"); err != nil {
+	if path, err = CheckSystemDriveAndRemoveDriveLetter("AB", pathdriver.LocalPathDriver); err != nil {
 		t.Fatalf("2 characters without colon should pass")
 	}
 	if path != "AB" {
@@ -29,7 +34,7 @@
 	}
 
 	// Abs path without drive letter
-	if path, err = CheckSystemDriveAndRemoveDriveLetter(`\l`); err != nil {
+	if path, err = CheckSystemDriveAndRemoveDriveLetter(`\l`, pathdriver.LocalPathDriver); err != nil {
 		t.Fatalf("abs path no drive letter should pass")
 	}
 	if path != `\l` {
@@ -37,7 +42,7 @@
 	}
 
 	// Abs path without drive letter, linux style
-	if path, err = CheckSystemDriveAndRemoveDriveLetter(`/l`); err != nil {
+	if path, err = CheckSystemDriveAndRemoveDriveLetter(`/l`, pathdriver.LocalPathDriver); err != nil {
 		t.Fatalf("abs path no drive letter linux style should pass")
 	}
 	if path != `\l` {
@@ -45,7 +50,7 @@
 	}
 
 	// Drive-colon should be stripped
-	if path, err = CheckSystemDriveAndRemoveDriveLetter(`c:\`); err != nil {
+	if path, err = CheckSystemDriveAndRemoveDriveLetter(`c:\`, pathdriver.LocalPathDriver); err != nil {
 		t.Fatalf("An absolute path should pass")
 	}
 	if path != `\` {
@@ -53,7 +58,7 @@
 	}
 
 	// Verify with a linux-style path
-	if path, err = CheckSystemDriveAndRemoveDriveLetter(`c:/`); err != nil {
+	if path, err = CheckSystemDriveAndRemoveDriveLetter(`c:/`, pathdriver.LocalPathDriver); err != nil {
 		t.Fatalf("An absolute path should pass")
 	}
 	if path != `\` {
@@ -61,7 +66,7 @@
 	}
 
 	// Failure on c:
-	if path, err = CheckSystemDriveAndRemoveDriveLetter(`c:`); err == nil {
+	if path, err = CheckSystemDriveAndRemoveDriveLetter(`c:`, pathdriver.LocalPathDriver); err == nil {
 		t.Fatalf("c: should fail")
 	}
 	if err.Error() != `No relative path specified in "c:"` {
@@ -69,7 +74,7 @@
 	}
 
 	// Failure on d:
-	if path, err = CheckSystemDriveAndRemoveDriveLetter(`d:`); err == nil {
+	if path, err = CheckSystemDriveAndRemoveDriveLetter(`d:`, pathdriver.LocalPathDriver); err == nil {
 		t.Fatalf("c: should fail")
 	}
 	if err.Error() != `No relative path specified in "d:"` {
diff --git a/pkg/system/stat_linux.go b/pkg/system/stat_linux.go
index 66bf6e2..1939f95 100644
--- a/pkg/system/stat_linux.go
+++ b/pkg/system/stat_linux.go
@@ -5,10 +5,10 @@
 // fromStatT converts a syscall.Stat_t type to a system.Stat_t type
 func fromStatT(s *syscall.Stat_t) (*StatT, error) {
 	return &StatT{size: s.Size,
-		mode: uint32(s.Mode),
+		mode: s.Mode,
 		uid:  s.Uid,
 		gid:  s.Gid,
-		rdev: uint64(s.Rdev),
+		rdev: s.Rdev,
 		mtim: s.Mtim}, nil
 }
 
diff --git a/pkg/system/stat_unix_test.go b/pkg/system/stat_unix_test.go
index dee8d30..15c2e27 100644
--- a/pkg/system/stat_unix_test.go
+++ b/pkg/system/stat_unix_test.go
@@ -6,6 +6,8 @@
 	"os"
 	"syscall"
 	"testing"
+
+	"github.com/stretchr/testify/require"
 )
 
 // TestFromStatT tests fromStatT for a tempfile
@@ -15,11 +17,10 @@
 
 	stat := &syscall.Stat_t{}
 	err := syscall.Lstat(file, stat)
+	require.NoError(t, err)
 
 	s, err := fromStatT(stat)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	if stat.Mode != s.Mode() {
 		t.Fatal("got invalid mode")
diff --git a/pkg/system/syscall_windows.go b/pkg/system/syscall_windows.go
index eded233..23e9b20 100644
--- a/pkg/system/syscall_windows.go
+++ b/pkg/system/syscall_windows.go
@@ -3,7 +3,7 @@
 import (
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/windows"
 )
 
diff --git a/pkg/tarsum/tarsum_test.go b/pkg/tarsum/tarsum_test.go
index 86df0e2..05f00d3 100644
--- a/pkg/tarsum/tarsum_test.go
+++ b/pkg/tarsum/tarsum_test.go
@@ -16,6 +16,9 @@
 	"os"
 	"strings"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 type testLayer struct {
@@ -222,17 +225,13 @@
 func TestEmptyTar(t *testing.T) {
 	// Test without gzip.
 	ts, err := emptyTarSum(false)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	zeroBlock := make([]byte, 1024)
 	buf := new(bytes.Buffer)
 
 	n, err := io.Copy(buf, ts)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 
 	if n != int64(len(zeroBlock)) || !bytes.Equal(buf.Bytes(), zeroBlock) {
 		t.Fatalf("tarSum did not write the correct number of zeroed bytes: %d", n)
@@ -247,19 +246,16 @@
 
 	// Test with gzip.
 	ts, err = emptyTarSum(true)
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	buf.Reset()
 
-	n, err = io.Copy(buf, ts)
-	if err != nil {
-		t.Fatal(err)
-	}
+	_, err = io.Copy(buf, ts)
+	require.NoError(t, err)
 
 	bufgz := new(bytes.Buffer)
 	gz := gzip.NewWriter(bufgz)
 	n, err = io.Copy(gz, bytes.NewBuffer(zeroBlock))
+	require.NoError(t, err)
 	gz.Close()
 	gzBytes := bufgz.Bytes()
 
@@ -279,10 +275,7 @@
 	}
 
 	resultSum = ts.Sum(nil)
-
-	if resultSum != expectedSum {
-		t.Fatalf("expected [%s] but got [%s]", expectedSum, resultSum)
-	}
+	assert.Equal(t, expectedSum, resultSum)
 }
 
 var (
diff --git a/pkg/templates/templates_test.go b/pkg/templates/templates_test.go
deleted file mode 100644
index 296bcb7..0000000
--- a/pkg/templates/templates_test.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package templates
-
-import (
-	"bytes"
-	"testing"
-
-	"github.com/stretchr/testify/assert"
-)
-
-// Github #32120
-func TestParseJSONFunctions(t *testing.T) {
-	tm, err := Parse(`{{json .Ports}}`)
-	assert.NoError(t, err)
-
-	var b bytes.Buffer
-	assert.NoError(t, tm.Execute(&b, map[string]string{"Ports": "0.0.0.0:2->8/udp"}))
-	want := "\"0.0.0.0:2->8/udp\""
-	assert.Equal(t, want, b.String())
-}
-
-func TestParseStringFunctions(t *testing.T) {
-	tm, err := Parse(`{{join (split . ":") "/"}}`)
-	assert.NoError(t, err)
-
-	var b bytes.Buffer
-	assert.NoError(t, tm.Execute(&b, "text:with:colon"))
-	want := "text/with/colon"
-	assert.Equal(t, want, b.String())
-}
-
-func TestNewParse(t *testing.T) {
-	tm, err := NewParse("foo", "this is a {{ . }}")
-	assert.NoError(t, err)
-
-	var b bytes.Buffer
-	assert.NoError(t, tm.Execute(&b, "string"))
-	want := "this is a string"
-	assert.Equal(t, want, b.String())
-}
-
-func TestParseTruncateFunction(t *testing.T) {
-	source := "tupx5xzf6hvsrhnruz5cr8gwp"
-
-	testCases := []struct {
-		template string
-		expected string
-	}{
-		{
-			template: `{{truncate . 5}}`,
-			expected: "tupx5",
-		},
-		{
-			template: `{{truncate . 25}}`,
-			expected: "tupx5xzf6hvsrhnruz5cr8gwp",
-		},
-		{
-			template: `{{truncate . 30}}`,
-			expected: "tupx5xzf6hvsrhnruz5cr8gwp",
-		},
-		{
-			template: `{{pad . 3 3}}`,
-			expected: "   tupx5xzf6hvsrhnruz5cr8gwp   ",
-		},
-	}
-
-	for _, testCase := range testCases {
-		tm, err := Parse(testCase.template)
-		assert.NoError(t, err)
-
-		t.Run("Non Empty Source Test with template: "+testCase.template, func(t *testing.T) {
-			var b bytes.Buffer
-			assert.NoError(t, tm.Execute(&b, source))
-			assert.Equal(t, testCase.expected, b.String())
-		})
-
-		t.Run("Empty Source Test with template: "+testCase.template, func(t *testing.T) {
-			var c bytes.Buffer
-			assert.NoError(t, tm.Execute(&c, ""))
-			assert.Equal(t, "", c.String())
-		})
-
-		t.Run("Nil Source Test with template: "+testCase.template, func(t *testing.T) {
-			var c bytes.Buffer
-			assert.Error(t, tm.Execute(&c, nil))
-			assert.Equal(t, "", c.String())
-		})
-	}
-}
diff --git a/pkg/term/ascii.go b/pkg/term/ascii.go
index f5262bc..55873c0 100644
--- a/pkg/term/ascii.go
+++ b/pkg/term/ascii.go
@@ -59,7 +59,7 @@
 				return nil, fmt.Errorf("Unknown character: '%s'", key)
 			}
 		} else {
-			codes = append(codes, byte(key[0]))
+			codes = append(codes, key[0])
 		}
 	}
 	return codes, nil
diff --git a/pkg/term/ascii_test.go b/pkg/term/ascii_test.go
index 4a1e7f3..5078cb7 100644
--- a/pkg/term/ascii_test.go
+++ b/pkg/term/ascii_test.go
@@ -1,43 +1,25 @@
 package term
 
-import "testing"
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
 
 func TestToBytes(t *testing.T) {
 	codes, err := ToBytes("ctrl-a,a")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(codes) != 2 {
-		t.Fatalf("Expected 2 codes, got %d", len(codes))
-	}
-	if codes[0] != 1 || codes[1] != 97 {
-		t.Fatalf("Expected '1' '97', got '%d' '%d'", codes[0], codes[1])
-	}
+	require.NoError(t, err)
+	assert.Equal(t, []byte{1, 97}, codes)
 
-	codes, err = ToBytes("shift-z")
-	if err == nil {
-		t.Fatalf("Expected error, got none")
-	}
+	_, err = ToBytes("shift-z")
+	assert.Error(t, err)
 
 	codes, err = ToBytes("ctrl-@,ctrl-[,~,ctrl-o")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(codes) != 4 {
-		t.Fatalf("Expected 4 codes, got %d", len(codes))
-	}
-	if codes[0] != 0 || codes[1] != 27 || codes[2] != 126 || codes[3] != 15 {
-		t.Fatalf("Expected '0' '27' '126', '15', got '%d' '%d' '%d' '%d'", codes[0], codes[1], codes[2], codes[3])
-	}
+	require.NoError(t, err)
+	assert.Equal(t, []byte{0, 27, 126, 15}, codes)
 
 	codes, err = ToBytes("DEL,+")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(codes) != 2 {
-		t.Fatalf("Expected 2 codes, got %d", len(codes))
-	}
-	if codes[0] != 127 || codes[1] != 43 {
-		t.Fatalf("Expected '127 '43'', got '%d' '%d'", codes[0], codes[1])
-	}
+	require.NoError(t, err)
+	assert.Equal(t, []byte{127, 43}, codes)
 }
diff --git a/pkg/term/term_linux_test.go b/pkg/term/term_linux_test.go
index f907ff5..0bb6f1c 100644
--- a/pkg/term/term_linux_test.go
+++ b/pkg/term/term_linux_test.go
@@ -68,6 +68,7 @@
 	require.Equal(t, inFd, tty.Fd())
 	require.Equal(t, isTerminal, true)
 	tmpFile, err := newTempFile()
+	require.NoError(t, err)
 	defer tmpFile.Close()
 	inFd, isTerminal = GetFdInfo(tmpFile)
 	require.Equal(t, inFd, tmpFile.Fd())
@@ -81,6 +82,7 @@
 	isTerminal := IsTerminal(tty.Fd())
 	require.Equal(t, isTerminal, true)
 	tmpFile, err := newTempFile()
+	require.NoError(t, err)
 	defer tmpFile.Close()
 	isTerminal = IsTerminal(tmpFile.Fd())
 	require.Equal(t, isTerminal, false)
@@ -94,6 +96,7 @@
 	require.NoError(t, err)
 	require.NotNil(t, state)
 	tty, err = newTtyForTest(t)
+	require.NoError(t, err)
 	defer tty.Close()
 	err = RestoreTerminal(tty.Fd(), state)
 	require.NoError(t, err)
diff --git a/pkg/term/termios_linux.go b/pkg/term/termios_linux.go
index 3e25eb7..0f21abc 100644
--- a/pkg/term/termios_linux.go
+++ b/pkg/term/termios_linux.go
@@ -29,6 +29,8 @@
 	termios.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
 	termios.Cflag &^= (unix.CSIZE | unix.PARENB)
 	termios.Cflag |= unix.CS8
+	termios.Cc[unix.VMIN] = 1
+	termios.Cc[unix.VTIME] = 0
 
 	if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil {
 		return nil, err
diff --git a/pkg/term/windows/windows.go b/pkg/term/windows/windows.go
index d67021e..c02a93a 100644
--- a/pkg/term/windows/windows.go
+++ b/pkg/term/windows/windows.go
@@ -10,7 +10,7 @@
 	"sync"
 
 	ansiterm "github.com/Azure/go-ansiterm"
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var logger *logrus.Logger
diff --git a/pkg/term/winsize.go b/pkg/term/winsize.go
index f58367f..85c4d9d 100644
--- a/pkg/term/winsize.go
+++ b/pkg/term/winsize.go
@@ -3,28 +3,18 @@
 package term
 
 import (
-	"unsafe"
-
 	"golang.org/x/sys/unix"
 )
 
 // GetWinsize returns the window size based on the specified file descriptor.
 func GetWinsize(fd uintptr) (*Winsize, error) {
-	ws := &Winsize{}
-	_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
-	// Skipp errno = 0
-	if err == 0 {
-		return ws, nil
-	}
+	uws, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ)
+	ws := &Winsize{Height: uws.Row, Width: uws.Col, x: uws.Xpixel, y: uws.Ypixel}
 	return ws, err
 }
 
 // SetWinsize tries to set the specified window size for the specified file descriptor.
 func SetWinsize(fd uintptr, ws *Winsize) error {
-	_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
-	// Skipp errno = 0
-	if err == 0 {
-		return nil
-	}
-	return err
+	uws := &unix.Winsize{Row: ws.Height, Col: ws.Width, Xpixel: ws.x, Ypixel: ws.y}
+	return unix.IoctlSetWinsize(int(fd), unix.TIOCSWINSZ, uws)
 }
diff --git a/pkg/testutil/cmd/command_test.go b/pkg/testutil/cmd/command_test.go
deleted file mode 100644
index d24b42b..0000000
--- a/pkg/testutil/cmd/command_test.go
+++ /dev/null
@@ -1,118 +0,0 @@
-package cmd
-
-import (
-	"runtime"
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-)
-
-func TestRunCommand(t *testing.T) {
-	// TODO Windows: Port this test
-	if runtime.GOOS == "windows" {
-		t.Skip("Needs porting to Windows")
-	}
-
-	var cmd string
-	if runtime.GOOS == "solaris" {
-		cmd = "gls"
-	} else {
-		cmd = "ls"
-	}
-	result := RunCommand(cmd)
-	result.Assert(t, Expected{})
-
-	result = RunCommand("doesnotexists")
-	expectedError := `exec: "doesnotexists": executable file not found`
-	result.Assert(t, Expected{ExitCode: 127, Error: expectedError})
-
-	result = RunCommand(cmd, "-z")
-	result.Assert(t, Expected{
-		ExitCode: 2,
-		Error:    "exit status 2",
-		Err:      "invalid option",
-	})
-	assert.Contains(t, result.Combined(), "invalid option")
-}
-
-func TestRunCommandWithCombined(t *testing.T) {
-	// TODO Windows: Port this test
-	if runtime.GOOS == "windows" {
-		t.Skip("Needs porting to Windows")
-	}
-
-	result := RunCommand("ls", "-a")
-	result.Assert(t, Expected{})
-
-	assert.Contains(t, result.Combined(), "..")
-	assert.Contains(t, result.Stdout(), "..")
-}
-
-func TestRunCommandWithTimeoutFinished(t *testing.T) {
-	// TODO Windows: Port this test
-	if runtime.GOOS == "windows" {
-		t.Skip("Needs porting to Windows")
-	}
-
-	result := RunCmd(Cmd{
-		Command: []string{"ls", "-a"},
-		Timeout: 50 * time.Millisecond,
-	})
-	result.Assert(t, Expected{Out: ".."})
-}
-
-func TestRunCommandWithTimeoutKilled(t *testing.T) {
-	// TODO Windows: Port this test
-	if runtime.GOOS == "windows" {
-		t.Skip("Needs porting to Windows")
-	}
-
-	command := []string{"sh", "-c", "while true ; do echo 1 ; sleep .5 ; done"}
-	result := RunCmd(Cmd{Command: command, Timeout: 1250 * time.Millisecond})
-	result.Assert(t, Expected{Timeout: true})
-
-	ones := strings.Split(result.Stdout(), "\n")
-	assert.Len(t, ones, 4)
-}
-
-func TestRunCommandWithErrors(t *testing.T) {
-	result := RunCommand("/foobar")
-	result.Assert(t, Expected{Error: "foobar", ExitCode: 127})
-}
-
-func TestRunCommandWithStdoutStderr(t *testing.T) {
-	result := RunCommand("echo", "hello", "world")
-	result.Assert(t, Expected{Out: "hello world\n", Err: None})
-}
-
-func TestRunCommandWithStdoutStderrError(t *testing.T) {
-	result := RunCommand("doesnotexists")
-
-	expected := `exec: "doesnotexists": executable file not found`
-	result.Assert(t, Expected{Out: None, Err: None, ExitCode: 127, Error: expected})
-
-	switch runtime.GOOS {
-	case "windows":
-		expected = "ls: unknown option"
-	case "solaris":
-		expected = "gls: invalid option"
-	default:
-		expected = "ls: invalid option"
-	}
-
-	var cmd string
-	if runtime.GOOS == "solaris" {
-		cmd = "gls"
-	} else {
-		cmd = "ls"
-	}
-	result = RunCommand(cmd, "-z")
-	result.Assert(t, Expected{
-		Out:      None,
-		Err:      expected,
-		ExitCode: 2,
-		Error:    "exit status 2",
-	})
-}
diff --git a/pkg/testutil/golden/golden.go b/pkg/testutil/golden/golden.go
deleted file mode 100644
index 8f725da..0000000
--- a/pkg/testutil/golden/golden.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Package golden provides function and helpers to use golden file for
-// testing purpose.
-package golden
-
-import (
-	"flag"
-	"io/ioutil"
-	"path/filepath"
-	"testing"
-)
-
-var update = flag.Bool("test.update", false, "update golden file")
-
-// Get returns the golden file content. If the `test.update` is specified, it updates the
-// file with the current output and returns it.
-func Get(t *testing.T, actual []byte, filename string) []byte {
-	golden := filepath.Join("testdata", filename)
-	if *update {
-		if err := ioutil.WriteFile(golden, actual, 0644); err != nil {
-			t.Fatal(err)
-		}
-	}
-	expected, err := ioutil.ReadFile(golden)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return expected
-}
diff --git a/pkg/testutil/helpers.go b/pkg/testutil/helpers.go
deleted file mode 100644
index c291148..0000000
--- a/pkg/testutil/helpers.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package testutil
-
-import (
-	"strings"
-	"unicode"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-)
-
-// ErrorContains checks that the error is not nil, and contains the expected
-// substring.
-func ErrorContains(t require.TestingT, err error, expectedError string) {
-	require.Error(t, err)
-	assert.Contains(t, err.Error(), expectedError)
-}
-
-// EqualNormalizedString compare the actual value to the expected value after applying the specified
-// transform function. It fails the test if these two transformed string are not equal.
-// For example `EqualNormalizedString(t, RemoveSpace, "foo\n", "foo")` wouldn't fail the test as
-// spaces (and thus '\n') are removed before comparing the string.
-func EqualNormalizedString(t require.TestingT, transformFun func(rune) rune, actual, expected string) {
-	require.Equal(t, strings.Map(transformFun, expected), strings.Map(transformFun, actual))
-}
-
-// RemoveSpace returns -1 if the specified runes is considered as a space (unicode)
-// and the rune itself otherwise.
-func RemoveSpace(r rune) rune {
-	if unicode.IsSpace(r) {
-		return -1
-	}
-	return r
-}
diff --git a/pkg/testutil/tempfile/tempfile.go b/pkg/testutil/tempfile/tempfile.go
deleted file mode 100644
index 01474ba..0000000
--- a/pkg/testutil/tempfile/tempfile.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package tempfile
-
-import (
-	"io/ioutil"
-	"os"
-
-	"github.com/stretchr/testify/require"
-)
-
-// TempFile is a temporary file that can be used with unit tests. TempFile
-// reduces the boilerplate setup required in each test case by handling
-// setup errors.
-type TempFile struct {
-	File *os.File
-}
-
-// NewTempFile returns a new temp file with contents
-func NewTempFile(t require.TestingT, prefix string, content string) *TempFile {
-	file, err := ioutil.TempFile("", prefix+"-")
-	require.NoError(t, err)
-
-	_, err = file.Write([]byte(content))
-	require.NoError(t, err)
-	file.Close()
-	return &TempFile{File: file}
-}
-
-// Name returns the filename
-func (f *TempFile) Name() string {
-	return f.File.Name()
-}
-
-// Remove removes the file
-func (f *TempFile) Remove() {
-	os.Remove(f.Name())
-}
-
-// TempDir is a temporary directory that can be used with unit tests. TempDir
-// reduces the boilerplate setup required in each test case by handling
-// setup errors.
-type TempDir struct {
-	Path string
-}
-
-// NewTempDir returns a new temp file with contents
-func NewTempDir(t require.TestingT, prefix string) *TempDir {
-	path, err := ioutil.TempDir("", prefix+"-")
-	require.NoError(t, err)
-
-	return &TempDir{Path: path}
-}
-
-// Remove removes the file
-func (f *TempDir) Remove() {
-	os.Remove(f.Path)
-}
diff --git a/pkg/testutil/utils.go b/pkg/testutil/utils.go
deleted file mode 100644
index 0522dde..0000000
--- a/pkg/testutil/utils.go
+++ /dev/null
@@ -1,218 +0,0 @@
-package testutil
-
-import (
-	"archive/tar"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"reflect"
-	"strings"
-	"syscall"
-	"time"
-
-	"github.com/docker/docker/pkg/stringutils"
-	"github.com/docker/docker/pkg/system"
-)
-
-// IsKilled process the specified error and returns whether the process was killed or not.
-func IsKilled(err error) bool {
-	if exitErr, ok := err.(*exec.ExitError); ok {
-		status, ok := exitErr.Sys().(syscall.WaitStatus)
-		if !ok {
-			return false
-		}
-		// status.ExitStatus() is required on Windows because it does not
-		// implement Signal() nor Signaled(). Just check it had a bad exit
-		// status could mean it was killed (and in tests we do kill)
-		return (status.Signaled() && status.Signal() == os.Kill) || status.ExitStatus() != 0
-	}
-	return false
-}
-
-func runCommandWithOutput(cmd *exec.Cmd) (output string, exitCode int, err error) {
-	out, err := cmd.CombinedOutput()
-	exitCode = system.ProcessExitCode(err)
-	output = string(out)
-	return
-}
-
-// RunCommandPipelineWithOutput runs the array of commands with the output
-// of each pipelined with the following (like cmd1 | cmd2 | cmd3 would do).
-// It returns the final output, the exitCode different from 0 and the error
-// if something bad happened.
-func RunCommandPipelineWithOutput(cmds ...*exec.Cmd) (output string, exitCode int, err error) {
-	if len(cmds) < 2 {
-		return "", 0, errors.New("pipeline does not have multiple cmds")
-	}
-
-	// connect stdin of each cmd to stdout pipe of previous cmd
-	for i, cmd := range cmds {
-		if i > 0 {
-			prevCmd := cmds[i-1]
-			cmd.Stdin, err = prevCmd.StdoutPipe()
-
-			if err != nil {
-				return "", 0, fmt.Errorf("cannot set stdout pipe for %s: %v", cmd.Path, err)
-			}
-		}
-	}
-
-	// start all cmds except the last
-	for _, cmd := range cmds[:len(cmds)-1] {
-		if err = cmd.Start(); err != nil {
-			return "", 0, fmt.Errorf("starting %s failed with error: %v", cmd.Path, err)
-		}
-	}
-
-	defer func() {
-		var pipeErrMsgs []string
-		// wait all cmds except the last to release their resources
-		for _, cmd := range cmds[:len(cmds)-1] {
-			if pipeErr := cmd.Wait(); pipeErr != nil {
-				pipeErrMsgs = append(pipeErrMsgs, fmt.Sprintf("command %s failed with error: %v", cmd.Path, pipeErr))
-			}
-		}
-		if len(pipeErrMsgs) > 0 && err == nil {
-			err = fmt.Errorf("pipelineError from Wait: %v", strings.Join(pipeErrMsgs, ", "))
-		}
-	}()
-
-	// wait on last cmd
-	return runCommandWithOutput(cmds[len(cmds)-1])
-}
-
-// ConvertSliceOfStringsToMap converts a slices of string in a map
-// with the strings as key and an empty string as values.
-func ConvertSliceOfStringsToMap(input []string) map[string]struct{} {
-	output := make(map[string]struct{})
-	for _, v := range input {
-		output[v] = struct{}{}
-	}
-	return output
-}
-
-// CompareDirectoryEntries compares two sets of FileInfo (usually taken from a directory)
-// and returns an error if different.
-func CompareDirectoryEntries(e1 []os.FileInfo, e2 []os.FileInfo) error {
-	var (
-		e1Entries = make(map[string]struct{})
-		e2Entries = make(map[string]struct{})
-	)
-	for _, e := range e1 {
-		e1Entries[e.Name()] = struct{}{}
-	}
-	for _, e := range e2 {
-		e2Entries[e.Name()] = struct{}{}
-	}
-	if !reflect.DeepEqual(e1Entries, e2Entries) {
-		return fmt.Errorf("entries differ")
-	}
-	return nil
-}
-
-// ListTar lists the entries of a tar.
-func ListTar(f io.Reader) ([]string, error) {
-	tr := tar.NewReader(f)
-	var entries []string
-
-	for {
-		th, err := tr.Next()
-		if err == io.EOF {
-			// end of tar archive
-			return entries, nil
-		}
-		if err != nil {
-			return entries, err
-		}
-		entries = append(entries, th.Name)
-	}
-}
-
-// RandomTmpDirPath provides a temporary path with rand string appended.
-// does not create or checks if it exists.
-func RandomTmpDirPath(s string, platform string) string {
-	tmp := "/tmp"
-	if platform == "windows" {
-		tmp = os.Getenv("TEMP")
-	}
-	path := filepath.Join(tmp, fmt.Sprintf("%s.%s", s, stringutils.GenerateRandomAlphaOnlyString(10)))
-	if platform == "windows" {
-		return filepath.FromSlash(path) // Using \
-	}
-	return filepath.ToSlash(path) // Using /
-}
-
-// ConsumeWithSpeed reads chunkSize bytes from reader before sleeping
-// for interval duration. Returns total read bytes. Send true to the
-// stop channel to return before reading to EOF on the reader.
-func ConsumeWithSpeed(reader io.Reader, chunkSize int, interval time.Duration, stop chan bool) (n int, err error) {
-	buffer := make([]byte, chunkSize)
-	for {
-		var readBytes int
-		readBytes, err = reader.Read(buffer)
-		n += readBytes
-		if err != nil {
-			if err == io.EOF {
-				err = nil
-			}
-			return
-		}
-		select {
-		case <-stop:
-			return
-		case <-time.After(interval):
-		}
-	}
-}
-
-// ParseCgroupPaths parses 'procCgroupData', which is output of '/proc/<pid>/cgroup', and returns
-// a map which cgroup name as key and path as value.
-func ParseCgroupPaths(procCgroupData string) map[string]string {
-	cgroupPaths := map[string]string{}
-	for _, line := range strings.Split(procCgroupData, "\n") {
-		parts := strings.Split(line, ":")
-		if len(parts) != 3 {
-			continue
-		}
-		cgroupPaths[parts[1]] = parts[2]
-	}
-	return cgroupPaths
-}
-
-// ChannelBuffer holds a chan of byte array that can be populate in a goroutine.
-type ChannelBuffer struct {
-	C chan []byte
-}
-
-// Write implements Writer.
-func (c *ChannelBuffer) Write(b []byte) (int, error) {
-	c.C <- b
-	return len(b), nil
-}
-
-// Close closes the go channel.
-func (c *ChannelBuffer) Close() error {
-	close(c.C)
-	return nil
-}
-
-// ReadTimeout reads the content of the channel in the specified byte array with
-// the specified duration as timeout.
-func (c *ChannelBuffer) ReadTimeout(p []byte, n time.Duration) (int, error) {
-	select {
-	case b := <-c.C:
-		return copy(p[0:], b), nil
-	case <-time.After(n):
-		return -1, fmt.Errorf("timeout reading from channel")
-	}
-}
-
-// ReadBody read the specified ReadCloser content and returns it
-func ReadBody(b io.ReadCloser) ([]byte, error) {
-	defer b.Close()
-	return ioutil.ReadAll(b)
-}
diff --git a/pkg/testutil/utils_test.go b/pkg/testutil/utils_test.go
deleted file mode 100644
index d37f3f4..0000000
--- a/pkg/testutil/utils_test.go
+++ /dev/null
@@ -1,341 +0,0 @@
-package testutil
-
-import (
-	"io"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"testing"
-	"time"
-)
-
-func TestIsKilledFalseWithNonKilledProcess(t *testing.T) {
-	var lsCmd *exec.Cmd
-	if runtime.GOOS != "windows" {
-		lsCmd = exec.Command("ls")
-	} else {
-		lsCmd = exec.Command("cmd", "/c", "dir")
-	}
-
-	err := lsCmd.Run()
-	if IsKilled(err) {
-		t.Fatalf("Expected the ls command to not be killed, was.")
-	}
-}
-
-func TestIsKilledTrueWithKilledProcess(t *testing.T) {
-	var longCmd *exec.Cmd
-	if runtime.GOOS != "windows" {
-		longCmd = exec.Command("top")
-	} else {
-		longCmd = exec.Command("powershell", "while ($true) { sleep 1 }")
-	}
-
-	// Start a command
-	err := longCmd.Start()
-	if err != nil {
-		t.Fatal(err)
-	}
-	// Capture the error when *dying*
-	done := make(chan error, 1)
-	go func() {
-		done <- longCmd.Wait()
-	}()
-	// Then kill it
-	longCmd.Process.Kill()
-	// Get the error
-	err = <-done
-	if !IsKilled(err) {
-		t.Fatalf("Expected the command to be killed, was not.")
-	}
-}
-
-func TestRunCommandPipelineWithOutputWithNotEnoughCmds(t *testing.T) {
-	_, _, err := RunCommandPipelineWithOutput(exec.Command("ls"))
-	expectedError := "pipeline does not have multiple cmds"
-	if err == nil || err.Error() != expectedError {
-		t.Fatalf("Expected an error with %s, got err:%s", expectedError, err)
-	}
-}
-
-func TestRunCommandPipelineWithOutputErrors(t *testing.T) {
-	p := "$PATH"
-	if runtime.GOOS == "windows" {
-		p = "%PATH%"
-	}
-	cmd1 := exec.Command("ls")
-	cmd1.Stdout = os.Stdout
-	cmd2 := exec.Command("anything really")
-	_, _, err := RunCommandPipelineWithOutput(cmd1, cmd2)
-	if err == nil || err.Error() != "cannot set stdout pipe for anything really: exec: Stdout already set" {
-		t.Fatalf("Expected an error, got %v", err)
-	}
-
-	cmdWithError := exec.Command("doesnotexists")
-	cmdCat := exec.Command("cat")
-	_, _, err = RunCommandPipelineWithOutput(cmdWithError, cmdCat)
-	if err == nil || err.Error() != `starting doesnotexists failed with error: exec: "doesnotexists": executable file not found in `+p {
-		t.Fatalf("Expected an error, got %v", err)
-	}
-}
-
-func TestRunCommandPipelineWithOutput(t *testing.T) {
-	//TODO: Should run on Solaris
-	if runtime.GOOS == "solaris" {
-		t.Skip()
-	}
-	cmds := []*exec.Cmd{
-		// Print 2 characters
-		exec.Command("echo", "-n", "11"),
-		// Count the number or char from stdin (previous command)
-		exec.Command("wc", "-m"),
-	}
-	out, exitCode, err := RunCommandPipelineWithOutput(cmds...)
-	expectedOutput := "2\n"
-	if out != expectedOutput || exitCode != 0 || err != nil {
-		t.Fatalf("Expected %s for commands %v, got out:%s, exitCode:%d, err:%v", expectedOutput, cmds, out, exitCode, err)
-	}
-}
-
-func TestConvertSliceOfStringsToMap(t *testing.T) {
-	input := []string{"a", "b"}
-	actual := ConvertSliceOfStringsToMap(input)
-	for _, key := range input {
-		if _, ok := actual[key]; !ok {
-			t.Fatalf("Expected output to contains key %s, did not: %v", key, actual)
-		}
-	}
-}
-
-func TestCompareDirectoryEntries(t *testing.T) {
-	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-compare-directories")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpFolder)
-
-	file1 := filepath.Join(tmpFolder, "file1")
-	file2 := filepath.Join(tmpFolder, "file2")
-	os.Create(file1)
-	os.Create(file2)
-
-	fi1, err := os.Stat(file1)
-	if err != nil {
-		t.Fatal(err)
-	}
-	fi1bis, err := os.Stat(file1)
-	if err != nil {
-		t.Fatal(err)
-	}
-	fi2, err := os.Stat(file2)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	cases := []struct {
-		e1          []os.FileInfo
-		e2          []os.FileInfo
-		shouldError bool
-	}{
-		// Empty directories
-		{
-			[]os.FileInfo{},
-			[]os.FileInfo{},
-			false,
-		},
-		// Same FileInfos
-		{
-			[]os.FileInfo{fi1},
-			[]os.FileInfo{fi1},
-			false,
-		},
-		// Different FileInfos but same names
-		{
-			[]os.FileInfo{fi1},
-			[]os.FileInfo{fi1bis},
-			false,
-		},
-		// Different FileInfos, different names
-		{
-			[]os.FileInfo{fi1},
-			[]os.FileInfo{fi2},
-			true,
-		},
-	}
-	for _, elt := range cases {
-		err := CompareDirectoryEntries(elt.e1, elt.e2)
-		if elt.shouldError && err == nil {
-			t.Fatalf("Should have return an error, did not with %v and %v", elt.e1, elt.e2)
-		}
-		if !elt.shouldError && err != nil {
-			t.Fatalf("Should have not returned an error, but did : %v with %v and %v", err, elt.e1, elt.e2)
-		}
-	}
-}
-
-// FIXME make an "unhappy path" test for ListTar without "panicking" :-)
-func TestListTar(t *testing.T) {
-	// TODO Windows: Figure out why this fails. Should be portable.
-	if runtime.GOOS == "windows" {
-		t.Skip("Failing on Windows - needs further investigation")
-	}
-	tmpFolder, err := ioutil.TempDir("", "integration-cli-utils-list-tar")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpFolder)
-
-	// Let's create a Tar file
-	srcFile := filepath.Join(tmpFolder, "src")
-	tarFile := filepath.Join(tmpFolder, "src.tar")
-	os.Create(srcFile)
-	cmd := exec.Command("sh", "-c", "tar cf "+tarFile+" "+srcFile)
-	_, err = cmd.CombinedOutput()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	reader, err := os.Open(tarFile)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer reader.Close()
-
-	entries, err := ListTar(reader)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(entries) != 1 && entries[0] != "src" {
-		t.Fatalf("Expected a tar file with 1 entry (%s), got %v", srcFile, entries)
-	}
-}
-
-func TestRandomTmpDirPath(t *testing.T) {
-	path := RandomTmpDirPath("something", runtime.GOOS)
-
-	prefix := "/tmp/something"
-	if runtime.GOOS == "windows" {
-		prefix = os.Getenv("TEMP") + `\something`
-	}
-	expectedSize := len(prefix) + 11
-
-	if !strings.HasPrefix(path, prefix) {
-		t.Fatalf("Expected generated path to have '%s' as prefix, got %s'", prefix, path)
-	}
-	if len(path) != expectedSize {
-		t.Fatalf("Expected generated path to be %d, got %d", expectedSize, len(path))
-	}
-}
-
-func TestConsumeWithSpeed(t *testing.T) {
-	reader := strings.NewReader("1234567890")
-	chunksize := 2
-
-	bytes1, err := ConsumeWithSpeed(reader, chunksize, 10*time.Millisecond, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if bytes1 != 10 {
-		t.Fatalf("Expected to have read 10 bytes, got %d", bytes1)
-	}
-
-}
-
-func TestConsumeWithSpeedWithStop(t *testing.T) {
-	reader := strings.NewReader("1234567890")
-	chunksize := 2
-
-	stopIt := make(chan bool)
-
-	go func() {
-		time.Sleep(1 * time.Millisecond)
-		stopIt <- true
-	}()
-
-	bytes1, err := ConsumeWithSpeed(reader, chunksize, 20*time.Millisecond, stopIt)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if bytes1 != 2 {
-		t.Fatalf("Expected to have read 2 bytes, got %d", bytes1)
-	}
-
-}
-
-func TestParseCgroupPathsEmpty(t *testing.T) {
-	cgroupMap := ParseCgroupPaths("")
-	if len(cgroupMap) != 0 {
-		t.Fatalf("Expected an empty map, got %v", cgroupMap)
-	}
-	cgroupMap = ParseCgroupPaths("\n")
-	if len(cgroupMap) != 0 {
-		t.Fatalf("Expected an empty map, got %v", cgroupMap)
-	}
-	cgroupMap = ParseCgroupPaths("something:else\nagain:here")
-	if len(cgroupMap) != 0 {
-		t.Fatalf("Expected an empty map, got %v", cgroupMap)
-	}
-}
-
-func TestParseCgroupPaths(t *testing.T) {
-	cgroupMap := ParseCgroupPaths("2:memory:/a\n1:cpuset:/b")
-	if len(cgroupMap) != 2 {
-		t.Fatalf("Expected a map with 2 entries, got %v", cgroupMap)
-	}
-	if value, ok := cgroupMap["memory"]; !ok || value != "/a" {
-		t.Fatalf("Expected cgroupMap to contains an entry for 'memory' with value '/a', got %v", cgroupMap)
-	}
-	if value, ok := cgroupMap["cpuset"]; !ok || value != "/b" {
-		t.Fatalf("Expected cgroupMap to contains an entry for 'cpuset' with value '/b', got %v", cgroupMap)
-	}
-}
-
-func TestChannelBufferTimeout(t *testing.T) {
-	expected := "11"
-
-	buf := &ChannelBuffer{make(chan []byte, 1)}
-	defer buf.Close()
-
-	done := make(chan struct{}, 1)
-	go func() {
-		time.Sleep(100 * time.Millisecond)
-		io.Copy(buf, strings.NewReader(expected))
-		done <- struct{}{}
-	}()
-
-	// Wait long enough
-	b := make([]byte, 2)
-	_, err := buf.ReadTimeout(b, 50*time.Millisecond)
-	if err == nil && err.Error() != "timeout reading from channel" {
-		t.Fatalf("Expected an error, got %s", err)
-	}
-	<-done
-}
-
-func TestChannelBuffer(t *testing.T) {
-	expected := "11"
-
-	buf := &ChannelBuffer{make(chan []byte, 1)}
-	defer buf.Close()
-
-	go func() {
-		time.Sleep(100 * time.Millisecond)
-		io.Copy(buf, strings.NewReader(expected))
-	}()
-
-	// Wait long enough
-	b := make([]byte, 2)
-	_, err := buf.ReadTimeout(b, 200*time.Millisecond)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if string(b) != expected {
-		t.Fatalf("Expected '%s', got '%s'", expected, string(b))
-	}
-}
diff --git a/pkg/tlsconfig/tlsconfig_clone.go b/pkg/tlsconfig/tlsconfig_clone.go
deleted file mode 100644
index e4dec3a..0000000
--- a/pkg/tlsconfig/tlsconfig_clone.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build go1.8
-
-package tlsconfig
-
-import "crypto/tls"
-
-// Clone returns a clone of tls.Config. This function is provided for
-// compatibility for go1.7 that doesn't include this method in stdlib.
-func Clone(c *tls.Config) *tls.Config {
-	return c.Clone()
-}
diff --git a/plugin/backend_linux.go b/plugin/backend_linux.go
index 055b8e3..66de6cb 100644
--- a/plugin/backend_linux.go
+++ b/plugin/backend_linux.go
@@ -6,7 +6,6 @@
 	"archive/tar"
 	"compress/gzip"
 	"encoding/json"
-	"fmt"
 	"io"
 	"io/ioutil"
 	"net/http"
@@ -15,7 +14,6 @@
 	"path/filepath"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/manifest/schema2"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
@@ -34,8 +32,9 @@
 	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/plugin/v2"
 	refstore "github.com/docker/docker/reference"
-	"github.com/opencontainers/go-digest"
+	digest "github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -55,7 +54,7 @@
 	pm.mu.RUnlock()
 
 	if !config.ForceDisable && p.GetRefCount() > 0 {
-		return fmt.Errorf("plugin %s is in use", p.Name())
+		return errors.WithStack(inUseError(p.Name()))
 	}
 
 	for _, typ := range p.GetTypes() {
@@ -142,7 +141,7 @@
 
 func (s *tempConfigStore) Get(d digest.Digest) ([]byte, error) {
 	if d != s.configDigest {
-		return nil, fmt.Errorf("digest not found")
+		return nil, errNotFound("digest not found")
 	}
 	return s.config, nil
 }
@@ -151,7 +150,7 @@
 	return configToRootFS(c)
 }
 
-func computePrivileges(c types.PluginConfig) (types.PluginPrivileges, error) {
+func computePrivileges(c types.PluginConfig) types.PluginPrivileges {
 	var privileges types.PluginPrivileges
 	if c.Network.Type != "null" && c.Network.Type != "bridge" && c.Network.Type != "" {
 		privileges = append(privileges, types.PluginPrivilege{
@@ -207,7 +206,7 @@
 		})
 	}
 
-	return privileges, nil
+	return privileges
 }
 
 // Privileges pulls a plugin config and computes the privileges required to install it.
@@ -236,21 +235,21 @@
 	}
 	var config types.PluginConfig
 	if err := json.Unmarshal(cs.config, &config); err != nil {
-		return nil, err
+		return nil, systemError{err}
 	}
 
-	return computePrivileges(config)
+	return computePrivileges(config), nil
 }
 
 // Upgrade upgrades a plugin
 func (pm *Manager) Upgrade(ctx context.Context, ref reference.Named, name string, metaHeader http.Header, authConfig *types.AuthConfig, privileges types.PluginPrivileges, outStream io.Writer) (err error) {
 	p, err := pm.config.Store.GetV2Plugin(name)
 	if err != nil {
-		return errors.Wrap(err, "plugin must be installed before upgrading")
+		return err
 	}
 
 	if p.IsEnabled() {
-		return fmt.Errorf("plugin must be disabled before upgrading")
+		return errors.Wrap(enabledError(p.Name()), "plugin must be disabled before upgrading")
 	}
 
 	pm.muGC.RLock()
@@ -258,12 +257,12 @@
 
 	// revalidate because Pull is public
 	if _, err := reference.ParseNormalizedNamed(name); err != nil {
-		return errors.Wrapf(err, "failed to parse %q", name)
+		return errors.Wrapf(validationError{err}, "failed to parse %q", name)
 	}
 
 	tmpRootFSDir, err := ioutil.TempDir(pm.tmpDir(), ".rootfs")
 	if err != nil {
-		return err
+		return errors.Wrap(systemError{err}, "error preparing upgrade")
 	}
 	defer os.RemoveAll(tmpRootFSDir)
 
@@ -305,17 +304,17 @@
 	// revalidate because Pull is public
 	nameref, err := reference.ParseNormalizedNamed(name)
 	if err != nil {
-		return errors.Wrapf(err, "failed to parse %q", name)
+		return errors.Wrapf(validationError{err}, "failed to parse %q", name)
 	}
 	name = reference.FamiliarString(reference.TagNameOnly(nameref))
 
 	if err := pm.config.Store.validateName(name); err != nil {
-		return err
+		return validationError{err}
 	}
 
 	tmpRootFSDir, err := ioutil.TempDir(pm.tmpDir(), ".rootfs")
 	if err != nil {
-		return err
+		return errors.Wrap(systemError{err}, "error preparing pull")
 	}
 	defer os.RemoveAll(tmpRootFSDir)
 
@@ -366,13 +365,13 @@
 
 	enabledOnly := false
 	disabledOnly := false
-	if pluginFilters.Include("enabled") {
+	if pluginFilters.Contains("enabled") {
 		if pluginFilters.ExactMatch("enabled", "true") {
 			enabledOnly = true
 		} else if pluginFilters.ExactMatch("enabled", "false") {
 			disabledOnly = true
 		} else {
-			return nil, fmt.Errorf("Invalid filter 'enabled=%s'", pluginFilters.Get("enabled"))
+			return nil, invalidFilter{"enabled", pluginFilters.Get("enabled")}
 		}
 	}
 
@@ -387,7 +386,7 @@
 		if disabledOnly && p.PluginObj.Enabled {
 			continue
 		}
-		if pluginFilters.Include("capability") {
+		if pluginFilters.Contains("capability") {
 			for _, f := range p.GetTypes() {
 				if !pluginFilters.Match("capability", f.Capability) {
 					continue next
@@ -615,10 +614,10 @@
 
 	if !config.ForceRemove {
 		if p.GetRefCount() > 0 {
-			return fmt.Errorf("plugin %s is in use", p.Name())
+			return inUseError(p.Name())
 		}
 		if p.IsEnabled() {
-			return fmt.Errorf("plugin %s is enabled", p.Name())
+			return enabledError(p.Name())
 		}
 	}
 
@@ -653,22 +652,6 @@
 	return nil
 }
 
-func getMounts(root string) ([]string, error) {
-	infos, err := mount.GetMounts()
-	if err != nil {
-		return nil, errors.Wrap(err, "failed to read mount table")
-	}
-
-	var mounts []string
-	for _, m := range infos {
-		if strings.HasPrefix(m.Mountpoint, root) {
-			mounts = append(mounts, m.Mountpoint)
-		}
-	}
-
-	return mounts, nil
-}
-
 // Set sets plugin args
 func (pm *Manager) Set(name string, args []string) error {
 	p, err := pm.config.Store.GetV2Plugin(name)
diff --git a/plugin/blobstore.go b/plugin/blobstore.go
index 2b79a44..c1259b6 100644
--- a/plugin/blobstore.go
+++ b/plugin/blobstore.go
@@ -7,7 +7,6 @@
 	"os"
 	"path/filepath"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/distribution/xfer"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
@@ -16,6 +15,7 @@
 	"github.com/docker/docker/pkg/progress"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/plugin/errors.go b/plugin/errors.go
new file mode 100644
index 0000000..0a101d4
--- /dev/null
+++ b/plugin/errors.go
@@ -0,0 +1,94 @@
+package plugin
+
+import "fmt"
+
+type errNotFound string
+
+func (name errNotFound) Error() string {
+	return fmt.Sprintf("plugin %q not found", string(name))
+}
+
+func (errNotFound) NotFound() {}
+
+type errAmbiguous string
+
+func (name errAmbiguous) Error() string {
+	return fmt.Sprintf("multiple plugins found for %q", string(name))
+}
+
+func (name errAmbiguous) InvalidParameter() {}
+
+type errDisabled string
+
+func (name errDisabled) Error() string {
+	return fmt.Sprintf("plugin %s found but disabled", string(name))
+}
+
+func (name errDisabled) Conflict() {}
+
+type validationError struct {
+	cause error
+}
+
+func (e validationError) Error() string {
+	return e.cause.Error()
+}
+
+func (validationError) Conflict() {}
+
+func (e validationError) Cause() error {
+	return e.cause
+}
+
+type systemError struct {
+	cause error
+}
+
+func (e systemError) Error() string {
+	return e.cause.Error()
+}
+
+func (systemError) SystemError() {}
+
+func (e systemError) Cause() error {
+	return e.cause
+}
+
+type invalidFilter struct {
+	filter string
+	value  []string
+}
+
+func (e invalidFilter) Error() string {
+	msg := "Invalid filter '" + e.filter
+	if len(e.value) > 0 {
+		msg += fmt.Sprintf("=%s", e.value)
+	}
+	return msg + "'"
+}
+
+func (invalidFilter) InvalidParameter() {}
+
+type inUseError string
+
+func (e inUseError) Error() string {
+	return "plugin " + string(e) + " is in use"
+}
+
+func (inUseError) Conflict() {}
+
+type enabledError string
+
+func (e enabledError) Error() string {
+	return "plugin " + string(e) + " is enabled"
+}
+
+func (enabledError) Conflict() {}
+
+type alreadyExistsError string
+
+func (e alreadyExistsError) Error() string {
+	return "plugin " + string(e) + " already exists"
+}
+
+func (alreadyExistsError) Conflict() {}
diff --git a/plugin/executor/containerd/containerd.go b/plugin/executor/containerd/containerd.go
new file mode 100644
index 0000000..74cf530
--- /dev/null
+++ b/plugin/executor/containerd/containerd.go
@@ -0,0 +1,77 @@
+package containerd
+
+import (
+	"io"
+
+	"github.com/docker/docker/libcontainerd"
+	"github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/pkg/errors"
+)
+
+// ExitHandler represents an object that is called when the exit event is received from containerd
+type ExitHandler interface {
+	HandleExitEvent(id string) error
+}
+
+// New creates a new containerd plugin executor
+func New(remote libcontainerd.Remote, exitHandler ExitHandler) (*Executor, error) {
+	e := &Executor{exitHandler: exitHandler}
+	client, err := remote.Client(e)
+	if err != nil {
+		return nil, errors.Wrap(err, "error creating containerd exec client")
+	}
+	e.client = client
+	return e, nil
+}
+
+// Executor is the containerd client implementation of a plugin executor
+type Executor struct {
+	client      libcontainerd.Client
+	exitHandler ExitHandler
+}
+
+// Create creates a new container
+func (e *Executor) Create(id string, spec specs.Spec, stdout, stderr io.WriteCloser) error {
+	return e.client.Create(id, "", "", spec, attachStreamsFunc(stdout, stderr))
+}
+
+// Restore restores a container
+func (e *Executor) Restore(id string, stdout, stderr io.WriteCloser) error {
+	return e.client.Restore(id, attachStreamsFunc(stdout, stderr))
+}
+
+// IsRunning returns if the container with the given id is running
+func (e *Executor) IsRunning(id string) (bool, error) {
+	pids, err := e.client.GetPidsForContainer(id)
+	return len(pids) > 0, err
+}
+
+// Signal sends the specified signal to the container
+func (e *Executor) Signal(id string, signal int) error {
+	return e.client.Signal(id, signal)
+}
+
+// StateChanged handles state changes from containerd
+// All events are ignored except the exit event, which is sent of to the stored handler
+func (e *Executor) StateChanged(id string, event libcontainerd.StateInfo) error {
+	switch event.State {
+	case libcontainerd.StateExit:
+		return e.exitHandler.HandleExitEvent(id)
+	}
+	return nil
+}
+
+func attachStreamsFunc(stdout, stderr io.WriteCloser) func(libcontainerd.IOPipe) error {
+	return func(iop libcontainerd.IOPipe) error {
+		iop.Stdin.Close()
+		go func() {
+			io.Copy(stdout, iop.Stdout)
+			stdout.Close()
+		}()
+		go func() {
+			io.Copy(stderr, iop.Stderr)
+			stderr.Close()
+		}()
+		return nil
+	}
+}
diff --git a/plugin/manager.go b/plugin/manager.go
index fada0d6..0c03192 100644
--- a/plugin/manager.go
+++ b/plugin/manager.go
@@ -13,12 +13,10 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
-	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/pkg/authorization"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/mount"
@@ -27,7 +25,9 @@
 	"github.com/docker/docker/plugin/v2"
 	"github.com/docker/docker/registry"
 	"github.com/opencontainers/go-digest"
+	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 const configFileName = "config.json"
@@ -35,6 +35,14 @@
 
 var validFullID = regexp.MustCompile(`^([a-f0-9]{64})$`)
 
+// Executor is the interface that the plugin manager uses to interact with for starting/stopping plugins
+type Executor interface {
+	Create(id string, spec specs.Spec, stdout, stderr io.WriteCloser) error
+	Restore(id string, stdout, stderr io.WriteCloser) error
+	IsRunning(id string) (bool, error)
+	Signal(id string, signal int) error
+}
+
 func (pm *Manager) restorePlugin(p *v2.Plugin) error {
 	if p.IsEnabled() {
 		return pm.restore(p)
@@ -47,24 +55,27 @@
 // ManagerConfig defines configuration needed to start new manager.
 type ManagerConfig struct {
 	Store              *Store // remove
-	Executor           libcontainerd.Remote
 	RegistryService    registry.Service
 	LiveRestoreEnabled bool // TODO: remove
 	LogPluginEvent     eventLogger
 	Root               string
 	ExecRoot           string
+	CreateExecutor     ExecutorCreator
 	AuthzMiddleware    *authorization.Middleware
 }
 
+// ExecutorCreator is used in the manager config to pass in an `Executor`
+type ExecutorCreator func(*Manager) (Executor, error)
+
 // Manager controls the plugin subsystem.
 type Manager struct {
-	config           ManagerConfig
-	mu               sync.RWMutex // protects cMap
-	muGC             sync.RWMutex // protects blobstore deletions
-	cMap             map[*v2.Plugin]*controller
-	containerdClient libcontainerd.Client
-	blobStore        *basicBlobStore
-	publisher        *pubsub.Publisher
+	config    ManagerConfig
+	mu        sync.RWMutex // protects cMap
+	muGC      sync.RWMutex // protects blobstore deletions
+	cMap      map[*v2.Plugin]*controller
+	blobStore *basicBlobStore
+	publisher *pubsub.Publisher
+	executor  Executor
 }
 
 // controller represents the manager's control on a plugin.
@@ -105,11 +116,17 @@
 	if err := os.MkdirAll(manager.tmpDir(), 0700); err != nil {
 		return nil, errors.Wrapf(err, "failed to mkdir %v", manager.tmpDir())
 	}
-	var err error
-	manager.containerdClient, err = config.Executor.Client(manager) // todo: move to another struct
-	if err != nil {
-		return nil, errors.Wrap(err, "failed to create containerd client")
+
+	if err := setupRoot(manager.config.Root); err != nil {
+		return nil, err
 	}
+
+	var err error
+	manager.executor, err = config.CreateExecutor(manager)
+	if err != nil {
+		return nil, err
+	}
+
 	manager.blobStore, err = newBasicBlobStore(filepath.Join(manager.config.Root, "storage/blobs"))
 	if err != nil {
 		return nil, err
@@ -128,42 +145,37 @@
 	return filepath.Join(pm.config.Root, "tmp")
 }
 
-// StateChanged updates plugin internals using libcontainerd events.
-func (pm *Manager) StateChanged(id string, e libcontainerd.StateInfo) error {
-	logrus.Debugf("plugin state changed %s %#v", id, e)
+// HandleExitEvent is called when the executor receives the exit event
+// In the future we may change this, but for now all we care about is the exit event.
+func (pm *Manager) HandleExitEvent(id string) error {
+	p, err := pm.config.Store.GetV2Plugin(id)
+	if err != nil {
+		return err
+	}
 
-	switch e.State {
-	case libcontainerd.StateExit:
-		p, err := pm.config.Store.GetV2Plugin(id)
-		if err != nil {
-			return err
+	os.RemoveAll(filepath.Join(pm.config.ExecRoot, id))
+
+	if p.PropagatedMount != "" {
+		if err := mount.Unmount(p.PropagatedMount); err != nil {
+			logrus.Warnf("Could not unmount %s: %v", p.PropagatedMount, err)
 		}
-
-		os.RemoveAll(filepath.Join(pm.config.ExecRoot, id))
-
-		if p.PropagatedMount != "" {
-			if err := mount.Unmount(p.PropagatedMount); err != nil {
-				logrus.Warnf("Could not unmount %s: %v", p.PropagatedMount, err)
-			}
-			propRoot := filepath.Join(filepath.Dir(p.Rootfs), "propagated-mount")
-			if err := mount.Unmount(propRoot); err != nil {
-				logrus.Warn("Could not unmount %s: %v", propRoot, err)
-			}
-		}
-
-		pm.mu.RLock()
-		c := pm.cMap[p]
-		if c.exitChan != nil {
-			close(c.exitChan)
-		}
-		restart := c.restart
-		pm.mu.RUnlock()
-
-		if restart {
-			pm.enable(p, c, true)
+		propRoot := filepath.Join(filepath.Dir(p.Rootfs), "propagated-mount")
+		if err := mount.Unmount(propRoot); err != nil {
+			logrus.Warn("Could not unmount %s: %v", propRoot, err)
 		}
 	}
 
+	pm.mu.RLock()
+	c := pm.cMap[p]
+	if c.exitChan != nil {
+		close(c.exitChan)
+	}
+	restart := c.restart
+	pm.mu.RUnlock()
+
+	if restart {
+		pm.enable(p, c, true)
+	}
 	return nil
 }
 
@@ -328,23 +340,10 @@
 	return nil
 }
 
-func attachToLog(id string) func(libcontainerd.IOPipe) error {
-	return func(iop libcontainerd.IOPipe) error {
-		iop.Stdin.Close()
-
-		logger := logrus.New()
-		logger.Hooks.Add(logHook{id})
-		// TODO: cache writer per id
-		w := logger.Writer()
-		go func() {
-			io.Copy(w, iop.Stdout)
-		}()
-		go func() {
-			// TODO: update logrus and use logger.WriterLevel
-			io.Copy(w, iop.Stderr)
-		}()
-		return nil
-	}
+func makeLoggerStreams(id string) (stdout, stderr io.WriteCloser) {
+	logger := logrus.New()
+	logger.Hooks.Add(logHook{id})
+	return logger.WriterLevel(logrus.InfoLevel), logger.WriterLevel(logrus.ErrorLevel)
 }
 
 func validatePrivileges(requiredPrivileges, privileges types.PluginPrivileges) error {
diff --git a/plugin/manager_linux.go b/plugin/manager_linux.go
index 9b84af6..beefc3d 100644
--- a/plugin/manager_linux.go
+++ b/plugin/manager_linux.go
@@ -4,31 +4,29 @@
 
 import (
 	"encoding/json"
-	"fmt"
 	"net"
 	"os"
 	"path/filepath"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/daemon/initlayer"
-	"github.com/docker/docker/libcontainerd"
+	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/plugin/v2"
 	"github.com/opencontainers/go-digest"
-	specs "github.com/opencontainers/runtime-spec/specs-go"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
 func (pm *Manager) enable(p *v2.Plugin, c *controller, force bool) error {
 	p.Rootfs = filepath.Join(pm.config.Root, p.PluginObj.ID, "rootfs")
 	if p.IsEnabled() && !force {
-		return fmt.Errorf("plugin %s is already enabled", p.Name())
+		return errors.Wrap(enabledError(p.Name()), "plugin already enabled")
 	}
 	spec, err := p.InitSpec(pm.config.ExecRoot)
 	if err != nil {
@@ -59,11 +57,13 @@
 		}
 	}
 
-	if err := initlayer.Setup(filepath.Join(pm.config.Root, p.PluginObj.ID, rootFSFileName), idtools.IDPair{0, 0}); err != nil {
+	rootFS := containerfs.NewLocalContainerFS(filepath.Join(pm.config.Root, p.PluginObj.ID, rootFSFileName))
+	if err := initlayer.Setup(rootFS, idtools.IDPair{0, 0}); err != nil {
 		return errors.WithStack(err)
 	}
 
-	if err := pm.containerdClient.Create(p.GetID(), "", "", specs.Spec(*spec), attachToLog(p.GetID())); err != nil {
+	stdout, stderr := makeLoggerStreams(p.GetID())
+	if err := pm.executor.Create(p.GetID(), *spec, stdout, stderr); err != nil {
 		if p.PropagatedMount != "" {
 			if err := mount.Unmount(p.PropagatedMount); err != nil {
 				logrus.Warnf("Could not unmount %s: %v", p.PropagatedMount, err)
@@ -83,7 +83,7 @@
 	client, err := plugins.NewClientWithTimeout("unix://"+sockAddr, nil, time.Duration(c.timeoutInSecs)*time.Second)
 	if err != nil {
 		c.restart = false
-		shutdownPlugin(p, c, pm.containerdClient)
+		shutdownPlugin(p, c, pm.executor)
 		return errors.WithStack(err)
 	}
 
@@ -109,7 +109,7 @@
 			c.restart = false
 			// While restoring plugins, we need to explicitly set the state to disabled
 			pm.config.Store.SetState(p, false)
-			shutdownPlugin(p, c, pm.containerdClient)
+			shutdownPlugin(p, c, pm.executor)
 			return err
 		}
 
@@ -121,13 +121,14 @@
 }
 
 func (pm *Manager) restore(p *v2.Plugin) error {
-	if err := pm.containerdClient.Restore(p.GetID(), attachToLog(p.GetID())); err != nil {
+	stdout, stderr := makeLoggerStreams(p.GetID())
+	if err := pm.executor.Restore(p.GetID(), stdout, stderr); err != nil {
 		return err
 	}
 
 	if pm.config.LiveRestoreEnabled {
 		c := &controller{}
-		if pids, _ := pm.containerdClient.GetPidsForContainer(p.GetID()); len(pids) == 0 {
+		if isRunning, _ := pm.executor.IsRunning(p.GetID()); !isRunning {
 			// plugin is not running, so follow normal startup procedure
 			return pm.enable(p, c, true)
 		}
@@ -143,10 +144,10 @@
 	return nil
 }
 
-func shutdownPlugin(p *v2.Plugin, c *controller, containerdClient libcontainerd.Client) {
+func shutdownPlugin(p *v2.Plugin, c *controller, executor Executor) {
 	pluginID := p.GetID()
 
-	err := containerdClient.Signal(pluginID, int(unix.SIGTERM))
+	err := executor.Signal(pluginID, int(unix.SIGTERM))
 	if err != nil {
 		logrus.Errorf("Sending SIGTERM to plugin failed with error: %v", err)
 	} else {
@@ -155,20 +156,27 @@
 			logrus.Debug("Clean shutdown of plugin")
 		case <-time.After(time.Second * 10):
 			logrus.Debug("Force shutdown plugin")
-			if err := containerdClient.Signal(pluginID, int(unix.SIGKILL)); err != nil {
+			if err := executor.Signal(pluginID, int(unix.SIGKILL)); err != nil {
 				logrus.Errorf("Sending SIGKILL to plugin failed with error: %v", err)
 			}
 		}
 	}
 }
 
+func setupRoot(root string) error {
+	if err := mount.MakePrivate(root); err != nil {
+		return errors.Wrap(err, "error setting plugin manager root to private")
+	}
+	return nil
+}
+
 func (pm *Manager) disable(p *v2.Plugin, c *controller) error {
 	if !p.IsEnabled() {
-		return fmt.Errorf("plugin %s is already disabled", p.Name())
+		return errors.Wrap(errDisabled(p.Name()), "plugin is already disabled")
 	}
 
 	c.restart = false
-	shutdownPlugin(p, c, pm.containerdClient)
+	shutdownPlugin(p, c, pm.executor)
 	pm.config.Store.SetState(p, false)
 	return pm.save(p)
 }
@@ -185,11 +193,12 @@
 			logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
 			continue
 		}
-		if pm.containerdClient != nil && p.IsEnabled() {
+		if pm.executor != nil && p.IsEnabled() {
 			c.restart = false
-			shutdownPlugin(p, c, pm.containerdClient)
+			shutdownPlugin(p, c, pm.executor)
 		}
 	}
+	mount.Unmount(pm.config.Root)
 }
 
 func (pm *Manager) upgradePlugin(p *v2.Plugin, configDigest digest.Digest, blobsums []digest.Digest, tmpRootFSDir string, privileges *types.PluginPrivileges) (err error) {
@@ -205,12 +214,12 @@
 	// This could happen if the plugin was disabled with `-f` with active mounts.
 	// If there is anything in `orig` is still mounted, this should error out.
 	if err := mount.RecursiveUnmount(orig); err != nil {
-		return err
+		return systemError{err}
 	}
 
 	backup := orig + "-old"
 	if err := os.Rename(orig, backup); err != nil {
-		return errors.Wrap(err, "error backing up plugin data before upgrade")
+		return errors.Wrap(systemError{err}, "error backing up plugin data before upgrade")
 	}
 
 	defer func() {
@@ -236,7 +245,7 @@
 	}()
 
 	if err := os.Rename(tmpRootFSDir, orig); err != nil {
-		return errors.Wrap(err, "error upgrading")
+		return errors.Wrap(systemError{err}, "error upgrading")
 	}
 
 	p.PluginObj.Config = config
@@ -260,7 +269,7 @@
 		return types.PluginConfig{}, errors.New("invalid config json")
 	}
 
-	requiredPrivileges, err := computePrivileges(config)
+	requiredPrivileges := computePrivileges(config)
 	if err != nil {
 		return types.PluginConfig{}, err
 	}
@@ -276,7 +285,7 @@
 // createPlugin creates a new plugin. take lock before calling.
 func (pm *Manager) createPlugin(name string, configDigest digest.Digest, blobsums []digest.Digest, rootFSDir string, privileges *types.PluginPrivileges, opts ...CreateOpt) (p *v2.Plugin, err error) {
 	if err := pm.config.Store.validateName(name); err != nil { // todo: this check is wrong. remove store
-		return nil, err
+		return nil, validationError{err}
 	}
 
 	config, err := pm.setupNewPlugin(configDigest, blobsums, privileges)
diff --git a/plugin/manager_solaris.go b/plugin/manager_solaris.go
index 72ccae7..ac03d6e 100644
--- a/plugin/manager_solaris.go
+++ b/plugin/manager_solaris.go
@@ -26,3 +26,5 @@
 // Shutdown plugins
 func (pm *Manager) Shutdown() {
 }
+
+func setupRoot(root string) error { return nil }
diff --git a/plugin/manager_windows.go b/plugin/manager_windows.go
index 4469a67..56a7ee3 100644
--- a/plugin/manager_windows.go
+++ b/plugin/manager_windows.go
@@ -28,3 +28,5 @@
 // Shutdown plugins
 func (pm *Manager) Shutdown() {
 }
+
+func setupRoot(root string) error { return nil }
diff --git a/plugin/store.go b/plugin/store.go
index 7f6e954..adc0e26 100644
--- a/plugin/store.go
+++ b/plugin/store.go
@@ -4,12 +4,12 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/plugin/v2"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 /* allowV1PluginsFallback determines daemon's support for V1 plugins.
@@ -24,25 +24,6 @@
 */
 const defaultAPIVersion string = "1.0"
 
-// ErrNotFound indicates that a plugin was not found locally.
-type ErrNotFound string
-
-func (name ErrNotFound) Error() string { return fmt.Sprintf("plugin %q not found", string(name)) }
-
-// ErrAmbiguous indicates that more than one plugin was found
-type ErrAmbiguous string
-
-func (name ErrAmbiguous) Error() string {
-	return fmt.Sprintf("multiple plugins found for %q", string(name))
-}
-
-// ErrDisabled indicates that a plugin was found but it is disabled
-type ErrDisabled string
-
-func (name ErrDisabled) Error() string {
-	return fmt.Sprintf("plugin %s found but disabled", string(name))
-}
-
 // GetV2Plugin retrieves a plugin by name, id or partial ID.
 func (ps *Store) GetV2Plugin(refOrID string) (*v2.Plugin, error) {
 	ps.RLock()
@@ -55,7 +36,7 @@
 
 	p, idOk := ps.plugins[id]
 	if !idOk {
-		return nil, errors.WithStack(ErrNotFound(id))
+		return nil, errors.WithStack(errNotFound(id))
 	}
 
 	return p, nil
@@ -65,7 +46,7 @@
 func (ps *Store) validateName(name string) error {
 	for _, p := range ps.plugins {
 		if p.Name() == name {
-			return errors.Errorf("plugin %q already exists", name)
+			return alreadyExistsError(name)
 		}
 	}
 	return nil
@@ -145,9 +126,9 @@
 			}
 			// Plugin was found but it is disabled, so we should not fall back to legacy plugins
 			// but we should error out right away
-			return nil, ErrDisabled(name)
+			return nil, errDisabled(name)
 		}
-		if _, ok := errors.Cause(err).(ErrNotFound); !ok {
+		if _, ok := errors.Cause(err).(errNotFound); !ok {
 			return nil, err
 		}
 	}
@@ -156,7 +137,10 @@
 	if allowV1PluginsFallback {
 		p, err := plugins.Get(name, capability)
 		if err != nil {
-			return nil, fmt.Errorf("legacy plugin: %v", err)
+			if errors.Cause(err) == plugins.ErrNotFound {
+				return nil, errNotFound(name)
+			}
+			return nil, errors.Wrap(systemError{err}, "legacy plugin")
 		}
 		return p, nil
 	}
@@ -189,7 +173,7 @@
 	if allowV1PluginsFallback {
 		pl, err := plugins.GetAll(capability)
 		if err != nil {
-			return nil, fmt.Errorf("legacy plugin: %v", err)
+			return nil, errors.Wrap(systemError{err}, "legacy plugin")
 		}
 		for _, p := range pl {
 			result = append(result, p)
@@ -239,11 +223,11 @@
 
 	ref, err := reference.ParseNormalizedNamed(idOrName)
 	if err != nil {
-		return "", errors.WithStack(ErrNotFound(idOrName))
+		return "", errors.WithStack(errNotFound(idOrName))
 	}
 	if _, ok := ref.(reference.Canonical); ok {
 		logrus.Warnf("canonical references cannot be resolved: %v", reference.FamiliarString(ref))
-		return "", errors.WithStack(ErrNotFound(idOrName))
+		return "", errors.WithStack(errNotFound(idOrName))
 	}
 
 	ref = reference.TagNameOnly(ref)
@@ -258,13 +242,13 @@
 	for id, p := range ps.plugins { // this can be optimized
 		if strings.HasPrefix(id, idOrName) {
 			if found != nil {
-				return "", errors.WithStack(ErrAmbiguous(idOrName))
+				return "", errors.WithStack(errAmbiguous(idOrName))
 			}
 			found = p
 		}
 	}
 	if found == nil {
-		return "", errors.WithStack(ErrNotFound(idOrName))
+		return "", errors.WithStack(errNotFound(idOrName))
 	}
 	return found.PluginObj.ID, nil
 }
diff --git a/plugin/v2/plugin_linux.go b/plugin/v2/plugin_linux.go
index 9cae180..be82363 100644
--- a/plugin/v2/plugin_linux.go
+++ b/plugin/v2/plugin_linux.go
@@ -18,7 +18,7 @@
 // InitSpec creates an OCI spec from the plugin's config.
 func (p *Plugin) InitSpec(execRoot string) (*specs.Spec, error) {
 	s := oci.DefaultSpec()
-	s.Root = specs.Root{
+	s.Root = &specs.Root{
 		Path:     p.Rootfs,
 		Readonly: false, // TODO: all plugins should be readonly? settable in config?
 	}
diff --git a/profiles/apparmor/apparmor.go b/profiles/apparmor/apparmor.go
index 48b41c5..e957727 100644
--- a/profiles/apparmor/apparmor.go
+++ b/profiles/apparmor/apparmor.go
@@ -9,9 +9,9 @@
 	"os"
 	"path"
 	"strings"
+	"text/template"
 
 	"github.com/docker/docker/pkg/aaparser"
-	"github.com/docker/docker/pkg/templates"
 )
 
 var (
@@ -33,7 +33,7 @@
 
 // generateDefault creates an apparmor profile from ProfileData.
 func (p *profileData) generateDefault(out io.Writer) error {
-	compiled, err := templates.NewParse("apparmor_profile", baseTemplate)
+	compiled, err := template.New("apparmor_profile").Parse(baseTemplate)
 	if err != nil {
 		return err
 	}
diff --git a/profiles/seccomp/default.json b/profiles/seccomp/default.json
index b71a871..38467c7 100755
--- a/profiles/seccomp/default.json
+++ b/profiles/seccomp/default.json
@@ -57,7 +57,6 @@
 				"access",
 				"adjtimex",
 				"alarm",
-				"alarm",
 				"bind",
 				"brk",
 				"capget",
@@ -557,6 +556,7 @@
 				"mount",
 				"name_to_handle_at",
 				"perf_event_open",
+				"quotactl",
 				"setdomainname",
 				"sethostname",
 				"setns",
diff --git a/profiles/seccomp/seccomp_default.go b/profiles/seccomp/seccomp_default.go
index 1e6ea90..1b5179c 100644
--- a/profiles/seccomp/seccomp_default.go
+++ b/profiles/seccomp/seccomp_default.go
@@ -50,7 +50,6 @@
 				"access",
 				"adjtimex",
 				"alarm",
-				"alarm",
 				"bind",
 				"brk",
 				"capget",
@@ -488,6 +487,7 @@
 				"mount",
 				"name_to_handle_at",
 				"perf_event_open",
+				"quotactl",
 				"setdomainname",
 				"sethostname",
 				"setns",
diff --git a/project/ARM.md b/project/ARM.md
index e61e3b1..c876231 100644
--- a/project/ARM.md
+++ b/project/ARM.md
@@ -17,7 +17,7 @@
 - make default
 - make shell
 - make test-unit
-- make test-integration-cli
+- make test-integration
 - make
 
 The Makefile does include logic to determine on which OS and architecture the Docker Development Image is built.
diff --git a/reference/errors.go b/reference/errors.go
new file mode 100644
index 0000000..a16f124
--- /dev/null
+++ b/reference/errors.go
@@ -0,0 +1,25 @@
+package reference
+
+type notFoundError string
+
+func (e notFoundError) Error() string {
+	return string(e)
+}
+
+func (notFoundError) NotFound() {}
+
+type invalidTagError string
+
+func (e invalidTagError) Error() string {
+	return string(e)
+}
+
+func (invalidTagError) InvalidParameter() {}
+
+type conflictingTagError string
+
+func (e conflictingTagError) Error() string {
+	return string(e)
+}
+
+func (conflictingTagError) Conflict() {}
diff --git a/reference/store.go b/reference/store.go
index 5b68c43..bde5951 100644
--- a/reference/store.go
+++ b/reference/store.go
@@ -2,7 +2,6 @@
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -12,12 +11,13 @@
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/opencontainers/go-digest"
+	"github.com/pkg/errors"
 )
 
 var (
 	// ErrDoesNotExist is returned if a reference is not found in the
 	// store.
-	ErrDoesNotExist = errors.New("reference does not exist")
+	ErrDoesNotExist notFoundError = "reference does not exist"
 )
 
 // An Association is a tuple associating a reference with an image ID.
@@ -26,7 +26,7 @@
 	ID  digest.Digest
 }
 
-// Store provides the set of methods which can operate on a tag store.
+// Store provides the set of methods which can operate on a reference store.
 type Store interface {
 	References(id digest.Digest) []reference.Named
 	ReferencesByName(ref reference.Named) []Association
@@ -46,9 +46,6 @@
 	// referencesByIDCache is a cache of references indexed by ID, to speed
 	// up References.
 	referencesByIDCache map[digest.Digest]map[string]reference.Named
-	// platform is the container target platform for this store (which may be
-	// different to the host operating system
-	platform string
 }
 
 // Repository maps tags to digests. The key is a stringified Reference,
@@ -73,7 +70,7 @@
 
 // NewReferenceStore creates a new reference store, tied to a file path where
 // the set of references are serialized in JSON format.
-func NewReferenceStore(jsonPath, platform string) (Store, error) {
+func NewReferenceStore(jsonPath string) (Store, error) {
 	abspath, err := filepath.Abs(jsonPath)
 	if err != nil {
 		return nil, err
@@ -83,7 +80,6 @@
 		jsonPath:            abspath,
 		Repositories:        make(map[string]repository),
 		referencesByIDCache: make(map[digest.Digest]map[string]reference.Named),
-		platform:            platform,
 	}
 	// Load the json file if it exists, otherwise create it.
 	if err := store.reload(); os.IsNotExist(err) {
@@ -100,7 +96,7 @@
 // references can be overwritten. This only works for tags, not digests.
 func (store *store) AddTag(ref reference.Named, id digest.Digest, force bool) error {
 	if _, isCanonical := ref.(reference.Canonical); isCanonical {
-		return errors.New("refusing to create a tag with a digest reference")
+		return errors.WithStack(invalidTagError("refusing to create a tag with a digest reference"))
 	}
 	return store.addReference(reference.TagNameOnly(ref), id, force)
 }
@@ -138,7 +134,7 @@
 	refStr := reference.FamiliarString(ref)
 
 	if refName == string(digest.Canonical) {
-		return errors.New("refusing to create an ambiguous tag using digest algorithm as name")
+		return errors.WithStack(invalidTagError("refusing to create an ambiguous tag using digest algorithm as name"))
 	}
 
 	store.mu.Lock()
@@ -155,11 +151,15 @@
 	if exists {
 		// force only works for tags
 		if digested, isDigest := ref.(reference.Canonical); isDigest {
-			return fmt.Errorf("Cannot overwrite digest %s", digested.Digest().String())
+			return errors.WithStack(conflictingTagError("Cannot overwrite digest " + digested.Digest().String()))
 		}
 
 		if !force {
-			return fmt.Errorf("Conflict: Tag %s is already set to image %s, if you want to replace it, please use -f option", refStr, oldID.String())
+			return errors.WithStack(
+				conflictingTagError(
+					fmt.Sprintf("Conflict: Tag %s is already set to image %s, if you want to replace it, please use the force option", refStr, oldID.String()),
+				),
+			)
 		}
 
 		if store.referencesByIDCache[oldID] != nil {
diff --git a/reference/store_test.go b/reference/store_test.go
index 2c796e7..72a19d6 100644
--- a/reference/store_test.go
+++ b/reference/store_test.go
@@ -5,12 +5,13 @@
 	"io/ioutil"
 	"os"
 	"path/filepath"
-	"runtime"
 	"strings"
 	"testing"
 
 	"github.com/docker/distribution/reference"
-	"github.com/opencontainers/go-digest"
+	digest "github.com/opencontainers/go-digest"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 var (
@@ -41,7 +42,7 @@
 	}
 	jsonFile.Close()
 
-	store, err := NewReferenceStore(jsonFile.Name(), runtime.GOOS)
+	store, err := NewReferenceStore(jsonFile.Name())
 	if err != nil {
 		t.Fatalf("error creating tag store: %v", err)
 	}
@@ -63,14 +64,14 @@
 
 func TestSave(t *testing.T) {
 	jsonFile, err := ioutil.TempFile("", "tag-store-test")
-	if err != nil {
-		t.Fatalf("error creating temp file: %v", err)
-	}
+	require.NoError(t, err)
+
 	_, err = jsonFile.Write([]byte(`{}`))
+	require.NoError(t, err)
 	jsonFile.Close()
 	defer os.RemoveAll(jsonFile.Name())
 
-	store, err := NewReferenceStore(jsonFile.Name(), runtime.GOOS)
+	store, err := NewReferenceStore(jsonFile.Name())
 	if err != nil {
 		t.Fatalf("error creating tag store: %v", err)
 	}
@@ -112,7 +113,7 @@
 	jsonFile.Close()
 	defer os.RemoveAll(jsonFile.Name())
 
-	store, err := NewReferenceStore(jsonFile.Name(), runtime.GOOS)
+	store, err := NewReferenceStore(jsonFile.Name())
 	if err != nil {
 		t.Fatalf("error creating tag store: %v", err)
 	}
@@ -305,19 +306,19 @@
 	}
 
 	// Delete a few references
-	if deleted, err := store.Delete(ref1); err != nil || deleted != true {
+	if deleted, err := store.Delete(ref1); err != nil || !deleted {
 		t.Fatal("Delete failed")
 	}
 	if _, err := store.Get(ref1); err != ErrDoesNotExist {
 		t.Fatal("Expected ErrDoesNotExist from Get")
 	}
-	if deleted, err := store.Delete(ref5); err != nil || deleted != true {
+	if deleted, err := store.Delete(ref5); err != nil || !deleted {
 		t.Fatal("Delete failed")
 	}
 	if _, err := store.Get(ref5); err != ErrDoesNotExist {
 		t.Fatal("Expected ErrDoesNotExist from Get")
 	}
-	if deleted, err := store.Delete(nameOnly); err != nil || deleted != true {
+	if deleted, err := store.Delete(nameOnly); err != nil || !deleted {
 		t.Fatal("Delete failed")
 	}
 	if _, err := store.Get(nameOnly); err != ErrDoesNotExist {
@@ -327,32 +328,23 @@
 
 func TestInvalidTags(t *testing.T) {
 	tmpDir, err := ioutil.TempDir("", "tag-store-test")
+	require.NoError(t, err)
 	defer os.RemoveAll(tmpDir)
 
-	store, err := NewReferenceStore(filepath.Join(tmpDir, "repositories.json"), runtime.GOOS)
-	if err != nil {
-		t.Fatalf("error creating tag store: %v", err)
-	}
+	store, err := NewReferenceStore(filepath.Join(tmpDir, "repositories.json"))
+	require.NoError(t, err)
 	id := digest.Digest("sha256:470022b8af682154f57a2163d030eb369549549cba00edc69e1b99b46bb924d6")
 
 	// sha256 as repo name
 	ref, err := reference.ParseNormalizedNamed("sha256:abc")
-	if err != nil {
-		t.Fatal(err)
-	}
+	require.NoError(t, err)
 	err = store.AddTag(ref, id, true)
-	if err == nil {
-		t.Fatalf("expected setting tag %q to fail", ref)
-	}
+	assert.Error(t, err)
 
 	// setting digest as a tag
 	ref, err = reference.ParseNormalizedNamed("registry@sha256:367eb40fd0330a7e464777121e39d2f5b3e8e23a1e159342e53ab05c9e4d94e6")
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = store.AddTag(ref, id, true)
-	if err == nil {
-		t.Fatalf("expected setting tag %q to fail", ref)
-	}
+	require.NoError(t, err)
 
+	err = store.AddTag(ref, id, true)
+	assert.Error(t, err)
 }
diff --git a/registry/auth.go b/registry/auth.go
index 8cadd51..b0a03d0 100644
--- a/registry/auth.go
+++ b/registry/auth.go
@@ -1,19 +1,19 @@
 package registry
 
 import (
-	"fmt"
 	"io/ioutil"
 	"net/http"
 	"net/url"
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/registry/client/auth"
 	"github.com/docker/distribution/registry/client/auth/challenge"
 	"github.com/docker/distribution/registry/client/transport"
 	"github.com/docker/docker/api/types"
 	registrytypes "github.com/docker/docker/api/types/registry"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -23,21 +23,15 @@
 
 // loginV1 tries to register/login to the v1 registry server.
 func loginV1(authConfig *types.AuthConfig, apiEndpoint APIEndpoint, userAgent string) (string, string, error) {
-	registryEndpoint, err := apiEndpoint.ToV1Endpoint(userAgent, nil)
-	if err != nil {
-		return "", "", err
-	}
-
+	registryEndpoint := apiEndpoint.ToV1Endpoint(userAgent, nil)
 	serverAddress := registryEndpoint.String()
 
 	logrus.Debugf("attempting v1 login to registry endpoint %s", serverAddress)
 
 	if serverAddress == "" {
-		return "", "", fmt.Errorf("Server Error: Server Address not set.")
+		return "", "", systemError{errors.New("server Error: Server Address not set")}
 	}
 
-	loginAgainstOfficialIndex := serverAddress == IndexServer
-
 	req, err := http.NewRequest("GET", serverAddress+"users/", nil)
 	if err != nil {
 		return "", "", err
@@ -53,27 +47,23 @@
 	defer resp.Body.Close()
 	body, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
-		return "", "", err
+		return "", "", systemError{err}
 	}
-	if resp.StatusCode == http.StatusOK {
+
+	switch resp.StatusCode {
+	case http.StatusOK:
 		return "Login Succeeded", "", nil
-	} else if resp.StatusCode == http.StatusUnauthorized {
-		if loginAgainstOfficialIndex {
-			return "", "", fmt.Errorf("Wrong login/password, please try again. Haven't got a Docker ID? Create one at https://hub.docker.com")
-		}
-		return "", "", fmt.Errorf("Wrong login/password, please try again")
-	} else if resp.StatusCode == http.StatusForbidden {
-		if loginAgainstOfficialIndex {
-			return "", "", fmt.Errorf("Login: Account is not active. Please check your e-mail for a confirmation link.")
-		}
+	case http.StatusUnauthorized:
+		return "", "", unauthorizedError{errors.New("Wrong login/password, please try again")}
+	case http.StatusForbidden:
 		// *TODO: Use registry configuration to determine what this says, if anything?
-		return "", "", fmt.Errorf("Login: Account is not active. Please see the documentation of the registry %s for instructions how to activate it.", serverAddress)
-	} else if resp.StatusCode == http.StatusInternalServerError { // Issue #14326
+		return "", "", notActivatedError{errors.Errorf("Login: Account is not active. Please see the documentation of the registry %s for instructions how to activate it.", serverAddress)}
+	case http.StatusInternalServerError:
 		logrus.Errorf("%s returned status code %d. Response Body :\n%s", req.URL.String(), resp.StatusCode, body)
-		return "", "", fmt.Errorf("Internal Server Error")
+		return "", "", systemError{errors.New("Internal Server Error")}
 	}
-	return "", "", fmt.Errorf("Login: %s (Code: %d; Headers: %s)", body,
-		resp.StatusCode, resp.Header)
+	return "", "", systemError{errors.Errorf("Login: %s (Code: %d; Headers: %s)", body,
+		resp.StatusCode, resp.Header)}
 }
 
 type loginCredentialStore struct {
@@ -159,24 +149,25 @@
 
 	resp, err := loginClient.Do(req)
 	if err != nil {
+		err = translateV2AuthError(err)
 		if !foundV2 {
 			err = fallbackError{err: err}
 		}
+
 		return "", "", err
 	}
 	defer resp.Body.Close()
 
-	if resp.StatusCode != http.StatusOK {
-		// TODO(dmcgowan): Attempt to further interpret result, status code and error code string
-		err := fmt.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode))
-		if !foundV2 {
-			err = fallbackError{err: err}
-		}
-		return "", "", err
+	if resp.StatusCode == http.StatusOK {
+		return "Login Succeeded", credentialAuthConfig.IdentityToken, nil
 	}
 
-	return "Login Succeeded", credentialAuthConfig.IdentityToken, nil
-
+	// TODO(dmcgowan): Attempt to further interpret result, status code and error code string
+	err = errors.Errorf("login attempt to %s failed with status: %d %s", endpointStr, resp.StatusCode, http.StatusText(resp.StatusCode))
+	if !foundV2 {
+		err = fallbackError{err: err}
+	}
+	return "", "", err
 }
 
 func v2AuthHTTPClient(endpoint *url.URL, authTransport http.RoundTripper, modifiers []transport.RequestModifier, creds auth.CredentialStore, scopes []auth.Scope) (*http.Client, bool, error) {
@@ -256,6 +247,7 @@
 // challenge manager for the supported authentication types and
 // whether v2 was confirmed by the response. If a response is received but
 // cannot be interpreted a PingResponseError will be returned.
+// nolint: interfacer
 func PingV2Registry(endpoint *url.URL, transport http.RoundTripper) (challenge.Manager, bool, error) {
 	var (
 		foundV2   = false
diff --git a/registry/config.go b/registry/config.go
index 182599e..5246faa 100644
--- a/registry/config.go
+++ b/registry/config.go
@@ -8,12 +8,10 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	registrytypes "github.com/docker/docker/api/types/registry"
-	"github.com/docker/docker/opts"
 	"github.com/pkg/errors"
-	"github.com/spf13/pflag"
+	"github.com/sirupsen/logrus"
 )
 
 // ServiceOptions holds command line options.
@@ -62,7 +60,7 @@
 	// not have the correct form
 	ErrInvalidRepositoryName = errors.New("Invalid repository name (ex: \"registry.domain.tld/myrepos\")")
 
-	emptyServiceConfig = newServiceConfig(ServiceOptions{})
+	emptyServiceConfig, _ = newServiceConfig(ServiceOptions{})
 )
 
 var (
@@ -72,37 +70,28 @@
 // for mocking in unit tests
 var lookupIP = net.LookupIP
 
-// InstallCliFlags adds command-line options to the top-level flag parser for
-// the current process.
-func (options *ServiceOptions) InstallCliFlags(flags *pflag.FlagSet) {
-	ana := opts.NewNamedListOptsRef("allow-nondistributable-artifacts", &options.AllowNondistributableArtifacts, ValidateIndexName)
-	mirrors := opts.NewNamedListOptsRef("registry-mirrors", &options.Mirrors, ValidateMirror)
-	insecureRegistries := opts.NewNamedListOptsRef("insecure-registries", &options.InsecureRegistries, ValidateIndexName)
-
-	flags.Var(ana, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry")
-	flags.Var(mirrors, "registry-mirror", "Preferred Docker registry mirror")
-	flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication")
-
-	options.installCliPlatformFlags(flags)
-}
-
 // newServiceConfig returns a new instance of ServiceConfig
-func newServiceConfig(options ServiceOptions) *serviceConfig {
+func newServiceConfig(options ServiceOptions) (*serviceConfig, error) {
 	config := &serviceConfig{
 		ServiceConfig: registrytypes.ServiceConfig{
 			InsecureRegistryCIDRs: make([]*registrytypes.NetIPNet, 0),
-			IndexConfigs:          make(map[string]*registrytypes.IndexInfo, 0),
+			IndexConfigs:          make(map[string]*registrytypes.IndexInfo),
 			// Hack: Bypass setting the mirrors to IndexConfigs since they are going away
 			// and Mirrors are only for the official registry anyways.
 		},
 		V2Only: options.V2Only,
 	}
+	if err := config.LoadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts); err != nil {
+		return nil, err
+	}
+	if err := config.LoadMirrors(options.Mirrors); err != nil {
+		return nil, err
+	}
+	if err := config.LoadInsecureRegistries(options.InsecureRegistries); err != nil {
+		return nil, err
+	}
 
-	config.LoadAllowNondistributableArtifacts(options.AllowNondistributableArtifacts)
-	config.LoadMirrors(options.Mirrors)
-	config.LoadInsecureRegistries(options.InsecureRegistries)
-
-	return config
+	return config, nil
 }
 
 // LoadAllowNondistributableArtifacts loads allow-nondistributable-artifacts registries into config.
@@ -187,7 +176,7 @@
 	originalIndexInfos := config.ServiceConfig.IndexConfigs
 
 	config.ServiceConfig.InsecureRegistryCIDRs = make([]*registrytypes.NetIPNet, 0)
-	config.ServiceConfig.IndexConfigs = make(map[string]*registrytypes.IndexInfo, 0)
+	config.ServiceConfig.IndexConfigs = make(map[string]*registrytypes.IndexInfo)
 
 skip:
 	for _, r := range registries {
@@ -354,7 +343,7 @@
 		val = "docker.io"
 	}
 	if strings.HasPrefix(val, "-") || strings.HasSuffix(val, "-") {
-		return "", fmt.Errorf("Invalid index name (%s). Cannot begin or end with a hyphen.", val)
+		return "", fmt.Errorf("invalid index name (%s). Cannot begin or end with a hyphen", val)
 	}
 	return val, nil
 }
diff --git a/registry/config_test.go b/registry/config_test.go
index 8cb7e5a..0899e17 100644
--- a/registry/config_test.go
+++ b/registry/config_test.go
@@ -5,6 +5,8 @@
 	"sort"
 	"strings"
 	"testing"
+
+	"github.com/stretchr/testify/assert"
 )
 
 func TestLoadAllowNondistributableArtifacts(t *testing.T) {
@@ -90,7 +92,7 @@
 		},
 	}
 	for _, testCase := range testCases {
-		config := newServiceConfig(ServiceOptions{})
+		config := emptyServiceConfig
 		err := config.LoadAllowNondistributableArtifacts(testCase.registries)
 		if testCase.err == "" {
 			if err != nil {
@@ -233,7 +235,7 @@
 		},
 	}
 	for _, testCase := range testCases {
-		config := newServiceConfig(ServiceOptions{})
+		config := emptyServiceConfig
 		err := config.LoadInsecureRegistries(testCase.registries)
 		if testCase.err == "" {
 			if err != nil {
@@ -258,3 +260,60 @@
 		}
 	}
 }
+
+func TestNewServiceConfig(t *testing.T) {
+	testCases := []struct {
+		opts   ServiceOptions
+		errStr string
+	}{
+		{
+			ServiceOptions{},
+			"",
+		},
+		{
+			ServiceOptions{
+				Mirrors: []string{"example.com:5000"},
+			},
+			`invalid mirror: unsupported scheme "example.com" in "example.com:5000"`,
+		},
+		{
+			ServiceOptions{
+				Mirrors: []string{"http://example.com:5000"},
+			},
+			"",
+		},
+		{
+			ServiceOptions{
+				InsecureRegistries: []string{"[fe80::]/64"},
+			},
+			`insecure registry [fe80::]/64 is not valid: invalid host "[fe80::]/64"`,
+		},
+		{
+			ServiceOptions{
+				InsecureRegistries: []string{"102.10.8.1/24"},
+			},
+			"",
+		},
+		{
+			ServiceOptions{
+				AllowNondistributableArtifacts: []string{"[fe80::]/64"},
+			},
+			`allow-nondistributable-artifacts registry [fe80::]/64 is not valid: invalid host "[fe80::]/64"`,
+		},
+		{
+			ServiceOptions{
+				AllowNondistributableArtifacts: []string{"102.10.8.1/24"},
+			},
+			"",
+		},
+	}
+
+	for _, testCase := range testCases {
+		_, err := newServiceConfig(testCase.opts)
+		if testCase.errStr != "" {
+			assert.EqualError(t, err, testCase.errStr)
+		} else {
+			assert.Nil(t, err)
+		}
+	}
+}
diff --git a/registry/config_unix.go b/registry/config_unix.go
index fdc39a1..b81d249 100644
--- a/registry/config_unix.go
+++ b/registry/config_unix.go
@@ -2,10 +2,6 @@
 
 package registry
 
-import (
-	"github.com/spf13/pflag"
-)
-
 var (
 	// CertsDir is the directory where certificates are stored
 	CertsDir = "/etc/docker/certs.d"
@@ -18,8 +14,3 @@
 func cleanPath(s string) string {
 	return s
 }
-
-// installCliPlatformFlags handles any platform specific flags for the service.
-func (options *ServiceOptions) installCliPlatformFlags(flags *pflag.FlagSet) {
-	flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries")
-}
diff --git a/registry/config_windows.go b/registry/config_windows.go
index d1b313d..82bc4af 100644
--- a/registry/config_windows.go
+++ b/registry/config_windows.go
@@ -4,8 +4,6 @@
 	"os"
 	"path/filepath"
 	"strings"
-
-	"github.com/spf13/pflag"
 )
 
 // CertsDir is the directory where certificates are stored
@@ -18,8 +16,3 @@
 func cleanPath(s string) string {
 	return filepath.FromSlash(strings.Replace(s, ":", "", -1))
 }
-
-// installCliPlatformFlags handles any platform specific flags for the service.
-func (options *ServiceOptions) installCliPlatformFlags(flags *pflag.FlagSet) {
-	// No Windows specific flags.
-}
diff --git a/registry/endpoint_v1.go b/registry/endpoint_v1.go
index c5ca961..d6a51bf 100644
--- a/registry/endpoint_v1.go
+++ b/registry/endpoint_v1.go
@@ -9,9 +9,9 @@
 	"net/url"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/registry/client/transport"
 	registrytypes "github.com/docker/docker/api/types/registry"
+	"github.com/sirupsen/logrus"
 )
 
 // V1Endpoint stores basic information about a V1 registry endpoint.
@@ -67,7 +67,7 @@
 	return nil
 }
 
-func newV1Endpoint(address url.URL, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) (*V1Endpoint, error) {
+func newV1Endpoint(address url.URL, tlsConfig *tls.Config, userAgent string, metaHeaders http.Header) *V1Endpoint {
 	endpoint := &V1Endpoint{
 		IsSecure: (tlsConfig == nil || !tlsConfig.InsecureSkipVerify),
 		URL:      new(url.URL),
@@ -78,7 +78,7 @@
 	// TODO(tiborvass): make sure a ConnectTimeout transport is used
 	tr := NewTransport(tlsConfig)
 	endpoint.client = HTTPClient(transport.NewTransport(tr, DockerHeaders(userAgent, metaHeaders)...))
-	return endpoint, nil
+	return endpoint
 }
 
 // trimV1Address trims the version off the address and returns the
@@ -123,7 +123,7 @@
 		return nil, err
 	}
 
-	endpoint, err := newV1Endpoint(*uri, tlsConfig, userAgent, metaHeaders)
+	endpoint := newV1Endpoint(*uri, tlsConfig, userAgent, metaHeaders)
 	if err != nil {
 		return nil, err
 	}
diff --git a/registry/errors.go b/registry/errors.go
new file mode 100644
index 0000000..b388efc
--- /dev/null
+++ b/registry/errors.go
@@ -0,0 +1,86 @@
+package registry
+
+import (
+	"net/url"
+
+	"github.com/docker/distribution/registry/api/errcode"
+)
+
+type notFoundError string
+
+func (e notFoundError) Error() string {
+	return string(e)
+}
+
+func (notFoundError) NotFound() {}
+
+type validationError struct {
+	cause error
+}
+
+func (e validationError) Error() string {
+	return e.cause.Error()
+}
+
+func (e validationError) InvalidParameter() {}
+
+func (e validationError) Cause() error {
+	return e.cause
+}
+
+type unauthorizedError struct {
+	cause error
+}
+
+func (e unauthorizedError) Error() string {
+	return e.cause.Error()
+}
+
+func (e unauthorizedError) Unauthorized() {}
+
+func (e unauthorizedError) Cause() error {
+	return e.cause
+}
+
+type systemError struct {
+	cause error
+}
+
+func (e systemError) Error() string {
+	return e.cause.Error()
+}
+
+func (e systemError) SystemError() {}
+
+func (e systemError) Cause() error {
+	return e.cause
+}
+
+type notActivatedError struct {
+	cause error
+}
+
+func (e notActivatedError) Error() string {
+	return e.cause.Error()
+}
+
+func (e notActivatedError) Forbidden() {}
+
+func (e notActivatedError) Cause() error {
+	return e.cause
+}
+
+func translateV2AuthError(err error) error {
+	switch e := err.(type) {
+	case *url.Error:
+		switch e2 := e.Err.(type) {
+		case errcode.Error:
+			switch e2.Code {
+			case errcode.ErrorCodeUnauthorized:
+				return unauthorizedError{err}
+			}
+		}
+	}
+
+	return err
+}
diff --git a/registry/registry.go b/registry/registry.go
index 17fa97c..5fef0db 100644
--- a/registry/registry.go
+++ b/registry/registry.go
@@ -13,10 +13,10 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/registry/client/transport"
 	"github.com/docker/go-connections/sockets"
 	"github.com/docker/go-connections/tlsconfig"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -81,7 +81,7 @@
 			keyName := certName[:len(certName)-5] + ".key"
 			logrus.Debugf("cert: %s", filepath.Join(directory, f.Name()))
 			if !hasFile(fs, keyName) {
-				return fmt.Errorf("Missing key %s for client certificate %s. Note that CA certificates should use the extension .crt.", keyName, certName)
+				return fmt.Errorf("missing key %s for client certificate %s. Note that CA certificates should use the extension .crt", keyName, certName)
 			}
 			cert, err := tls.LoadX509KeyPair(filepath.Join(directory, certName), filepath.Join(directory, keyName))
 			if err != nil {
diff --git a/registry/registry_mock_test.go b/registry/registry_mock_test.go
index 58b05d3..cf1cd19 100644
--- a/registry/registry_mock_test.go
+++ b/registry/registry_mock_test.go
@@ -21,7 +21,7 @@
 	registrytypes "github.com/docker/docker/api/types/registry"
 	"github.com/gorilla/mux"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -175,7 +175,7 @@
 	return index
 }
 
-func makeServiceConfig(mirrors []string, insecureRegistries []string) *serviceConfig {
+func makeServiceConfig(mirrors []string, insecureRegistries []string) (*serviceConfig, error) {
 	options := ServiceOptions{
 		Mirrors:            mirrors,
 		InsecureRegistries: insecureRegistries,
diff --git a/registry/registry_test.go b/registry/registry_test.go
index d89c46c..e9c407d 100644
--- a/registry/registry_test.go
+++ b/registry/registry_test.go
@@ -14,6 +14,7 @@
 	"github.com/docker/distribution/registry/client/transport"
 	"github.com/docker/docker/api/types"
 	registrytypes "github.com/docker/docker/api/types/registry"
+	"github.com/stretchr/testify/assert"
 )
 
 var (
@@ -539,7 +540,7 @@
 		}
 	}
 
-	config := newServiceConfig(ServiceOptions{})
+	config := emptyServiceConfig
 	noMirrors := []string{}
 	expectedIndexInfos := map[string]*registrytypes.IndexInfo{
 		IndexName: {
@@ -570,7 +571,11 @@
 	testIndexInfo(config, expectedIndexInfos)
 
 	publicMirrors := []string{"http://mirror1.local", "http://mirror2.local"}
-	config = makeServiceConfig(publicMirrors, []string{"example.com"})
+	var err error
+	config, err = makeServiceConfig(publicMirrors, []string{"example.com"})
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	expectedIndexInfos = map[string]*registrytypes.IndexInfo{
 		IndexName: {
@@ -618,7 +623,10 @@
 	}
 	testIndexInfo(config, expectedIndexInfos)
 
-	config = makeServiceConfig(nil, []string{"42.42.0.0/16"})
+	config, err = makeServiceConfig(nil, []string{"42.42.0.0/16"})
+	if err != nil {
+		t.Fatal(err)
+	}
 	expectedIndexInfos = map[string]*registrytypes.IndexInfo{
 		"example.com": {
 			Name:     "example.com",
@@ -663,7 +671,11 @@
 		}
 		return false
 	}
-	s := DefaultService{config: makeServiceConfig([]string{"https://my.mirror"}, nil)}
+	cfg, err := makeServiceConfig([]string{"https://my.mirror"}, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	s := DefaultService{config: cfg}
 
 	imageName, err := reference.WithName(IndexName + "/test/image")
 	if err != nil {
@@ -747,16 +759,12 @@
 func TestTrustedLocation(t *testing.T) {
 	for _, url := range []string{"http://example.com", "https://example.com:7777", "http://docker.io", "http://test.docker.com", "https://fakedocker.com"} {
 		req, _ := http.NewRequest("GET", url, nil)
-		if trustedLocation(req) == true {
-			t.Fatalf("'%s' shouldn't be detected as a trusted location", url)
-		}
+		assert.False(t, trustedLocation(req))
 	}
 
 	for _, url := range []string{"https://docker.io", "https://test.docker.com:80"} {
 		req, _ := http.NewRequest("GET", url, nil)
-		if trustedLocation(req) == false {
-			t.Fatalf("'%s' should be detected as a trusted location", url)
-		}
+		assert.True(t, trustedLocation(req))
 	}
 }
 
@@ -844,9 +852,12 @@
 		{"invalid.domain.com:5000", []string{"invalid.domain.com:5000"}, true},
 	}
 	for _, tt := range tests {
-		config := newServiceConfig(ServiceOptions{
+		config, err := newServiceConfig(ServiceOptions{
 			AllowNondistributableArtifacts: tt.registries,
 		})
+		if err != nil {
+			t.Error(err)
+		}
 		if v := allowNondistributableArtifacts(config, tt.addr); v != tt.expected {
 			t.Errorf("allowNondistributableArtifacts failed for %q %v, expected %v got %v", tt.addr, tt.registries, tt.expected, v)
 		}
@@ -886,7 +897,10 @@
 		{"invalid.domain.com:5000", []string{"invalid.domain.com:5000"}, false},
 	}
 	for _, tt := range tests {
-		config := makeServiceConfig(nil, tt.insecureRegistries)
+		config, err := makeServiceConfig(nil, tt.insecureRegistries)
+		if err != nil {
+			t.Error(err)
+		}
 		if sec := isSecureIndex(config, tt.addr); sec != tt.expected {
 			t.Errorf("isSecureIndex failed for %q %v, expected %v got %v", tt.addr, tt.insecureRegistries, tt.expected, sec)
 		}
diff --git a/registry/resumable/resumablerequestreader.go b/registry/resumable/resumablerequestreader.go
index 5403c76..12075e5 100644
--- a/registry/resumable/resumablerequestreader.go
+++ b/registry/resumable/resumablerequestreader.go
@@ -6,7 +6,7 @@
 	"net/http"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 type requestReader struct {
diff --git a/registry/resumable/resumablerequestreader_test.go b/registry/resumable/resumablerequestreader_test.go
index a632bc6..9b3a6dc 100644
--- a/registry/resumable/resumablerequestreader_test.go
+++ b/registry/resumable/resumablerequestreader_test.go
@@ -2,8 +2,6 @@
 
 import (
 	"fmt"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 	"io"
 	"io/ioutil"
 	"net/http"
@@ -11,6 +9,9 @@
 	"strings"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestResumableRequestHeaderSimpleErrors(t *testing.T) {
diff --git a/registry/service.go b/registry/service.go
index 34e8a13..a991a8f 100644
--- a/registry/service.go
+++ b/registry/service.go
@@ -2,7 +2,6 @@
 
 import (
 	"crypto/tls"
-	"fmt"
 	"net/http"
 	"net/url"
 	"strings"
@@ -10,11 +9,12 @@
 
 	"golang.org/x/net/context"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/distribution/registry/client/auth"
 	"github.com/docker/docker/api/types"
 	registrytypes "github.com/docker/docker/api/types/registry"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -45,10 +45,10 @@
 
 // NewService returns a new instance of DefaultService ready to be
 // installed into an engine.
-func NewService(options ServiceOptions) *DefaultService {
-	return &DefaultService{
-		config: newServiceConfig(options),
-	}
+func NewService(options ServiceOptions) (*DefaultService, error) {
+	config, err := newServiceConfig(options)
+
+	return &DefaultService{config: config}, err
 }
 
 // ServiceConfig returns the public registry service configuration.
@@ -117,12 +117,12 @@
 	}
 	u, err := url.Parse(serverAddress)
 	if err != nil {
-		return "", "", fmt.Errorf("unable to parse server address: %v", err)
+		return "", "", validationError{errors.Errorf("unable to parse server address: %v", err)}
 	}
 
 	endpoints, err := s.LookupPushEndpoints(u.Host)
 	if err != nil {
-		return "", "", err
+		return "", "", validationError{err}
 	}
 
 	for _, endpoint := range endpoints {
@@ -140,6 +140,7 @@
 			logrus.Infof("Error logging in to %s endpoint, trying next endpoint: %v", endpoint.Version, err)
 			continue
 		}
+
 		return "", "", err
 	}
 
@@ -258,7 +259,7 @@
 }
 
 // ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint
-func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) (*V1Endpoint, error) {
+func (e APIEndpoint) ToV1Endpoint(userAgent string, metaHeaders http.Header) *V1Endpoint {
 	return newV1Endpoint(*e.URL, e.TLSConfig, userAgent, metaHeaders)
 }
 
diff --git a/registry/service_v1_test.go b/registry/service_v1_test.go
index bd15dff..6ea846e 100644
--- a/registry/service_v1_test.go
+++ b/registry/service_v1_test.go
@@ -3,7 +3,10 @@
 import "testing"
 
 func TestLookupV1Endpoints(t *testing.T) {
-	s := NewService(ServiceOptions{})
+	s, err := NewService(ServiceOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
 
 	cases := []struct {
 		hostname    string
diff --git a/registry/session.go b/registry/session.go
index 9d7f321..e619d9f 100644
--- a/registry/session.go
+++ b/registry/session.go
@@ -3,7 +3,6 @@
 import (
 	"bytes"
 	"crypto/sha256"
-	"errors"
 	"sync"
 	// this is required for some certificates
 	_ "crypto/sha512"
@@ -18,7 +17,6 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/distribution/registry/api/errcode"
 	"github.com/docker/docker/api/types"
@@ -28,12 +26,14 @@
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/tarsum"
 	"github.com/docker/docker/registry/resumable"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 var (
 	// ErrRepoNotFound is returned if the repository didn't exist on the
 	// remote side
-	ErrRepoNotFound = errors.New("Repository not found")
+	ErrRepoNotFound notFoundError = "Repository not found"
 )
 
 // A Session is used to communicate with a V1 registry
@@ -434,7 +434,7 @@
 		// "Get https://index.docker.io/v1/repositories/library/busybox/images: i/o timeout"
 		// was a top search on the docker user forum
 		if isTimeout(err) {
-			return nil, fmt.Errorf("Network timed out while trying to connect to %s. You may want to check your internet connection or if you are behind a proxy.", repositoryTarget)
+			return nil, fmt.Errorf("network timed out while trying to connect to %s. You may want to check your internet connection or if you are behind a proxy", repositoryTarget)
 		}
 		return nil, fmt.Errorf("Error while pulling image: %v", err)
 	}
@@ -734,27 +734,27 @@
 // SearchRepositories performs a search against the remote repository
 func (r *Session) SearchRepositories(term string, limit int) (*registrytypes.SearchResults, error) {
 	if limit < 1 || limit > 100 {
-		return nil, fmt.Errorf("Limit %d is outside the range of [1, 100]", limit)
+		return nil, validationError{errors.Errorf("Limit %d is outside the range of [1, 100]", limit)}
 	}
 	logrus.Debugf("Index server: %s", r.indexEndpoint)
 	u := r.indexEndpoint.String() + "search?q=" + url.QueryEscape(term) + "&n=" + url.QueryEscape(fmt.Sprintf("%d", limit))
 
 	req, err := http.NewRequest("GET", u, nil)
 	if err != nil {
-		return nil, fmt.Errorf("Error while getting from the server: %v", err)
+		return nil, errors.Wrap(validationError{err}, "Error building request")
 	}
 	// Have the AuthTransport send authentication, when logged in.
 	req.Header.Set("X-Docker-Token", "true")
 	res, err := r.client.Do(req)
 	if err != nil {
-		return nil, err
+		return nil, systemError{err}
 	}
 	defer res.Body.Close()
 	if res.StatusCode != 200 {
 		return nil, newJSONError(fmt.Sprintf("Unexpected status code %d", res.StatusCode), res)
 	}
 	result := new(registrytypes.SearchResults)
-	return result, json.NewDecoder(res.Body).Decode(result)
+	return result, errors.Wrap(json.NewDecoder(res.Body).Decode(result), "error decoding registry search results")
 }
 
 func isTimeout(err error) bool {
diff --git a/reports/builder/2017-07-17.md b/reports/builder/2017-07-17.md
new file mode 100644
index 0000000..96cc8d1
--- /dev/null
+++ b/reports/builder/2017-07-17.md
@@ -0,0 +1,79 @@
+# Development Report for July 17, 2017
+
+
+### BuildKit
+
+[Repo](https://github.com/moby/buildkit)
+[Proposal](https://github.com/moby/moby/issues/32925)
+
+Following features were added last week:
+
+#### Git source
+
+Source code from git repositories can now be accessed directly, similarly for images can be accessed, without the need to execute `git clone`. This has many performance and caching advantages. It accesses the remote repository using shallow fetches to only pull the required data and a uses a shared bare repository for intermediate cache between build invocations. The instruction cache for the git source is based on a commit hash and not string arguments. This means that you can always be sure that you are building the correct source and that you never build the same source twice.
+
+#### Containerd exporter
+
+Exporters are used for getting build artifacts out of buildkit. The first exporter that was implemented allows exposing the image to containerd so it can be run and pushed with `ctr` tool. `buildctl` has `--exporter` flag for specifying the exporter and `--exporter-opt` for custom values passed to the exporter. In the case of image exporter an image name can be specified.
+
+For example:
+
+```
+go run ./examples/buildkit2/buildkit.go | buildctl build --exporter image --exporter-opt name=docker.io/moby/buildkit:dev
+```
+
+Accessing from ctr/dist:
+
+```
+ctr --namespace buildkit images ls
+ctr --namespace buildkit rootfs unpack <manifest-sha>
+ctr --namespace buildkit run -t docker.io/moby/buildkit:dev id ash
+```
+
+#### Local source
+
+Buildkit now supports building from local sources. Snapshot of the local source files is created similarly to `docker build` build context. The implementation is based on the [incremental context send](https://github.com/moby/moby/pull/32677) feature in `docker-v17.07`. To use in `buildctl` the source definition needs to define a name for local endpoint, and `buildctl build` command provides a mapping from this name to a local directory with a `--local` flag.
+
+```
+go run ./examples/buildkit3/buildkit.go --local  | buildctl build --local buildkit-src=.
+``` 
+
+### Typed Dockerfile parsing
+
+[PR](https://github.com/moby/moby/pull/33492)
+
+Didn't manage to merge this PR yet. Still in code-review.
+
+
+### Feedback for `RUN --mount` / `COPY --chown`
+
+There was some new discussion around [`RUN --mount`](https://github.com/moby/moby/issues/32507) or [`COPY --chown`](https://github.com/moby/moby/issues/30110) feature. Currently, it seems that it may be best to try the shared cache capabilities described in `RUN --mount` in https://github.com/moby/buildkit first(it already supports the generic mounting capabilities). So to unblock the people waiting only on the file owner change features it may make sense to implement `COPY --chown` first. Another related candidate for `v17.08` release is https://github.com/moby/moby/issues/32816. 
+
+
+### Proposals for new Dockerfile features that need design feedback:
+
+[Add IMPORT/EXPORT commands to Dockerfile](https://github.com/moby/moby/issues/32100)
+
+[Add `DOCKEROS/DOCKERARCH` default ARG to Dockerfile](https://github.com/moby/moby/issues/32487)
+
+[Add support for `RUN --mount`](https://github.com/moby/moby/issues/32507)
+
+[DAG image builder](https://github.com/moby/moby/issues/32550)
+
+[Option to export the hash of the build context](https://github.com/moby/moby/issues/32963) (new)
+
+[Allow --cache-from=*](https://github.com/moby/moby/issues/33002#issuecomment-299041162) (new)
+
+[Provide advanced .dockeringore use-cases](https://github.com/moby/moby/issues/12886) [2](https://github.com/moby/moby/issues/12886#issuecomment-306247989)
+
+New: [RFC: Distributed BuildKit](https://github.com/moby/buildkit/issues/62)
+
+If you are interested in implementing any of them, leave a comment on the specific issues.
+
+### Builder features currently in code-review:
+
+[Fix shallow git clone in docker-build](https://github.com/moby/moby/pull/33704)
+
+### Backlog
+
+[Build secrets](https://github.com/moby/moby/issues/33343) has not got much traction. If you want this feature to become a reality, please make yourself heard.
\ No newline at end of file
diff --git a/runconfig/config.go b/runconfig/config.go
index c9dc6e9..56eb946 100644
--- a/runconfig/config.go
+++ b/runconfig/config.go
@@ -2,13 +2,11 @@
 
 import (
 	"encoding/json"
-	"fmt"
 	"io"
 
 	"github.com/docker/docker/api/types/container"
 	networktypes "github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/pkg/sysinfo"
-	"github.com/docker/docker/volume"
 )
 
 // ContainerDecoder implements httputils.ContainerDecoder
@@ -17,19 +15,19 @@
 
 // DecodeConfig makes ContainerDecoder to implement httputils.ContainerDecoder
 func (r ContainerDecoder) DecodeConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
-	return DecodeContainerConfig(src)
+	return decodeContainerConfig(src)
 }
 
 // DecodeHostConfig makes ContainerDecoder to implement httputils.ContainerDecoder
 func (r ContainerDecoder) DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
-	return DecodeHostConfig(src)
+	return decodeHostConfig(src)
 }
 
-// DecodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
+// decodeContainerConfig decodes a json encoded config into a ContainerConfigWrapper
 // struct and returns both a Config and a HostConfig struct
 // Be aware this function is not checking whether the resulted structs are nil,
 // it's your business to do so
-func DecodeContainerConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
+func decodeContainerConfig(src io.Reader) (*container.Config, *container.HostConfig, *networktypes.NetworkingConfig, error) {
 	var w ContainerConfigWrapper
 
 	decoder := json.NewDecoder(src)
@@ -46,11 +44,6 @@
 		if w.Config.Volumes == nil {
 			w.Config.Volumes = make(map[string]struct{})
 		}
-
-		// Now validate all the volumes and binds
-		if err := validateMountSettings(w.Config, hc); err != nil {
-			return nil, nil, nil, err
-		}
 	}
 
 	// Certain parameters need daemon-side validation that cannot be done
@@ -86,23 +79,3 @@
 
 	return w.Config, hc, w.NetworkingConfig, nil
 }
-
-// validateMountSettings validates each of the volumes and bind settings
-// passed by the caller to ensure they are valid.
-func validateMountSettings(c *container.Config, hc *container.HostConfig) error {
-	// it is ok to have len(hc.Mounts) > 0 && (len(hc.Binds) > 0 || len (c.Volumes) > 0 || len (hc.Tmpfs) > 0 )
-
-	// Ensure all volumes and binds are valid.
-	for spec := range c.Volumes {
-		if _, err := volume.ParseMountRaw(spec, hc.VolumeDriver); err != nil {
-			return fmt.Errorf("invalid volume spec %q: %v", spec, err)
-		}
-	}
-	for _, spec := range hc.Binds {
-		if _, err := volume.ParseMountRaw(spec, hc.VolumeDriver); err != nil {
-			return fmt.Errorf("invalid bind mount spec %q: %v", spec, err)
-		}
-	}
-
-	return nil
-}
diff --git a/runconfig/config_test.go b/runconfig/config_test.go
index 83ec363..0a4ee1f 100644
--- a/runconfig/config_test.go
+++ b/runconfig/config_test.go
@@ -12,6 +12,8 @@
 	"github.com/docker/docker/api/types/container"
 	networktypes "github.com/docker/docker/api/types/network"
 	"github.com/docker/docker/api/types/strslice"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 type f struct {
@@ -51,7 +53,7 @@
 			t.Fatal(err)
 		}
 
-		c, h, _, err := DecodeContainerConfig(bytes.NewReader(b))
+		c, h, _, err := decodeContainerConfig(bytes.NewReader(b))
 		if err != nil {
 			t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
 		}
@@ -135,5 +137,59 @@
 	if b, err = json.Marshal(w); err != nil {
 		return nil, nil, nil, fmt.Errorf("Error on marshal %s", err.Error())
 	}
-	return DecodeContainerConfig(bytes.NewReader(b))
+	return decodeContainerConfig(bytes.NewReader(b))
+}
+
+type decodeConfigTestcase struct {
+	doc                string
+	wrapper            ContainerConfigWrapper
+	expectedErr        string
+	expectedConfig     *container.Config
+	expectedHostConfig *container.HostConfig
+	goos               string
+}
+
+func runDecodeContainerConfigTestCase(testcase decodeConfigTestcase) func(t *testing.T) {
+	return func(t *testing.T) {
+		raw := marshal(t, testcase.wrapper, testcase.doc)
+		config, hostConfig, _, err := decodeContainerConfig(bytes.NewReader(raw))
+		if testcase.expectedErr != "" {
+			if !assert.Error(t, err) {
+				return
+			}
+			assert.Contains(t, err.Error(), testcase.expectedErr)
+			return
+		}
+		assert.NoError(t, err)
+		assert.Equal(t, testcase.expectedConfig, config)
+		assert.Equal(t, testcase.expectedHostConfig, hostConfig)
+	}
+}
+
+func marshal(t *testing.T, w ContainerConfigWrapper, doc string) []byte {
+	b, err := json.Marshal(w)
+	require.NoError(t, err, "%s: failed to encode config wrapper", doc)
+	return b
+}
+
+func containerWrapperWithVolume(volume string) ContainerConfigWrapper {
+	return ContainerConfigWrapper{
+		Config: &container.Config{
+			Volumes: map[string]struct{}{
+				volume: {},
+			},
+		},
+		HostConfig: &container.HostConfig{},
+	}
+}
+
+func containerWrapperWithBind(bind string) ContainerConfigWrapper {
+	return ContainerConfigWrapper{
+		Config: &container.Config{
+			Volumes: map[string]struct{}{},
+		},
+		HostConfig: &container.HostConfig{
+			Binds: []string{bind},
+		},
+	}
 }
diff --git a/runconfig/errors.go b/runconfig/errors.go
index c95a291..78b0a88 100644
--- a/runconfig/errors.go
+++ b/runconfig/errors.go
@@ -1,38 +1,42 @@
 package runconfig
 
-import (
-	"fmt"
+const (
+	// ErrConflictContainerNetworkAndLinks conflict between --net=container and links
+	ErrConflictContainerNetworkAndLinks validationError = "conflicting options: container type network can't be used with links. This would result in undefined behavior"
+	// ErrConflictSharedNetwork conflict between private and other networks
+	ErrConflictSharedNetwork validationError = "container sharing network namespace with another container or host cannot be connected to any other network"
+	// ErrConflictHostNetwork conflict from being disconnected from host network or connected to host network.
+	ErrConflictHostNetwork validationError = "container cannot be disconnected from host network or connected to host network"
+	// ErrConflictNoNetwork conflict between private and other networks
+	ErrConflictNoNetwork validationError = "container cannot be connected to multiple networks with one of the networks in private (none) mode"
+	// ErrConflictNetworkAndDNS conflict between --dns and the network mode
+	ErrConflictNetworkAndDNS validationError = "conflicting options: dns and the network mode"
+	// ErrConflictNetworkHostname conflict between the hostname and the network mode
+	ErrConflictNetworkHostname validationError = "conflicting options: hostname and the network mode"
+	// ErrConflictHostNetworkAndLinks conflict between --net=host and links
+	ErrConflictHostNetworkAndLinks validationError = "conflicting options: host type networking can't be used with links. This would result in undefined behavior"
+	// ErrConflictContainerNetworkAndMac conflict between the mac address and the network mode
+	ErrConflictContainerNetworkAndMac validationError = "conflicting options: mac-address and the network mode"
+	// ErrConflictNetworkHosts conflict between add-host and the network mode
+	ErrConflictNetworkHosts validationError = "conflicting options: custom host-to-IP mapping and the network mode"
+	// ErrConflictNetworkPublishPorts conflict between the publish options and the network mode
+	ErrConflictNetworkPublishPorts validationError = "conflicting options: port publishing and the container type network mode"
+	// ErrConflictNetworkExposePorts conflict between the expose option and the network mode
+	ErrConflictNetworkExposePorts validationError = "conflicting options: port exposing and the container type network mode"
+	// ErrUnsupportedNetworkAndIP conflict between network mode and requested ip address
+	ErrUnsupportedNetworkAndIP validationError = "user specified IP address is supported on user defined networks only"
+	// ErrUnsupportedNetworkNoSubnetAndIP conflict between network with no configured subnet and requested ip address
+	ErrUnsupportedNetworkNoSubnetAndIP validationError = "user specified IP address is supported only when connecting to networks with user configured subnets"
+	// ErrUnsupportedNetworkAndAlias conflict between network mode and alias
+	ErrUnsupportedNetworkAndAlias validationError = "network-scoped alias is supported only for containers in user defined networks"
+	// ErrConflictUTSHostname conflict between the hostname and the UTS mode
+	ErrConflictUTSHostname validationError = "conflicting options: hostname and the UTS mode"
 )
 
-var (
-	// ErrConflictContainerNetworkAndLinks conflict between --net=container and links
-	ErrConflictContainerNetworkAndLinks = fmt.Errorf("conflicting options: container type network can't be used with links. This would result in undefined behavior")
-	// ErrConflictSharedNetwork conflict between private and other networks
-	ErrConflictSharedNetwork = fmt.Errorf("container sharing network namespace with another container or host cannot be connected to any other network")
-	// ErrConflictHostNetwork conflict from being disconnected from host network or connected to host network.
-	ErrConflictHostNetwork = fmt.Errorf("container cannot be disconnected from host network or connected to host network")
-	// ErrConflictNoNetwork conflict between private and other networks
-	ErrConflictNoNetwork = fmt.Errorf("container cannot be connected to multiple networks with one of the networks in private (none) mode")
-	// ErrConflictNetworkAndDNS conflict between --dns and the network mode
-	ErrConflictNetworkAndDNS = fmt.Errorf("conflicting options: dns and the network mode")
-	// ErrConflictNetworkHostname conflict between the hostname and the network mode
-	ErrConflictNetworkHostname = fmt.Errorf("conflicting options: hostname and the network mode")
-	// ErrConflictHostNetworkAndLinks conflict between --net=host and links
-	ErrConflictHostNetworkAndLinks = fmt.Errorf("conflicting options: host type networking can't be used with links. This would result in undefined behavior")
-	// ErrConflictContainerNetworkAndMac conflict between the mac address and the network mode
-	ErrConflictContainerNetworkAndMac = fmt.Errorf("conflicting options: mac-address and the network mode")
-	// ErrConflictNetworkHosts conflict between add-host and the network mode
-	ErrConflictNetworkHosts = fmt.Errorf("conflicting options: custom host-to-IP mapping and the network mode")
-	// ErrConflictNetworkPublishPorts conflict between the publish options and the network mode
-	ErrConflictNetworkPublishPorts = fmt.Errorf("conflicting options: port publishing and the container type network mode")
-	// ErrConflictNetworkExposePorts conflict between the expose option and the network mode
-	ErrConflictNetworkExposePorts = fmt.Errorf("conflicting options: port exposing and the container type network mode")
-	// ErrUnsupportedNetworkAndIP conflict between network mode and requested ip address
-	ErrUnsupportedNetworkAndIP = fmt.Errorf("user specified IP address is supported on user defined networks only")
-	// ErrUnsupportedNetworkNoSubnetAndIP conflict between network with no configured subnet and requested ip address
-	ErrUnsupportedNetworkNoSubnetAndIP = fmt.Errorf("user specified IP address is supported only when connecting to networks with user configured subnets")
-	// ErrUnsupportedNetworkAndAlias conflict between network mode and alias
-	ErrUnsupportedNetworkAndAlias = fmt.Errorf("network-scoped alias is supported only for containers in user defined networks")
-	// ErrConflictUTSHostname conflict between the hostname and the UTS mode
-	ErrConflictUTSHostname = fmt.Errorf("conflicting options: hostname and the UTS mode")
-)
+type validationError string
+
+func (e validationError) Error() string {
+	return string(e)
+}
+
+func (e validationError) InvalidParameter() {}
diff --git a/runconfig/hostconfig.go b/runconfig/hostconfig.go
index 24aed19..cfc5383 100644
--- a/runconfig/hostconfig.go
+++ b/runconfig/hostconfig.go
@@ -2,7 +2,6 @@
 
 import (
 	"encoding/json"
-	"fmt"
 	"io"
 	"strings"
 
@@ -11,7 +10,7 @@
 
 // DecodeHostConfig creates a HostConfig based on the specified Reader.
 // It assumes the content of the reader will be JSON, and decodes it.
-func DecodeHostConfig(src io.Reader) (*container.HostConfig, error) {
+func decodeHostConfig(src io.Reader) (*container.HostConfig, error) {
 	decoder := json.NewDecoder(src)
 
 	var w ContainerConfigWrapper
@@ -45,7 +44,7 @@
 	parts := strings.Split(string(hc.NetworkMode), ":")
 	if parts[0] == "container" {
 		if len(parts) < 2 || parts[1] == "" {
-			return fmt.Errorf("Invalid network mode: invalid container format container:<name|id>")
+			return validationError("Invalid network mode: invalid container format container:<name|id>")
 		}
 	}
 
@@ -69,7 +68,7 @@
 		return ErrConflictContainerNetworkAndMac
 	}
 
-	if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts == true) {
+	if hc.NetworkMode.IsContainer() && (len(hc.PortBindings) > 0 || hc.PublishAllPorts) {
 		return ErrConflictNetworkPublishPorts
 	}
 
diff --git a/runconfig/hostconfig_test.go b/runconfig/hostconfig_test.go
index a6a3eef..76c3fa2 100644
--- a/runconfig/hostconfig_test.go
+++ b/runconfig/hostconfig_test.go
@@ -10,6 +10,7 @@
 
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/pkg/sysinfo"
+	"github.com/stretchr/testify/assert"
 )
 
 // TODO Windows: This will need addressing for a Windows daemon.
@@ -61,43 +62,33 @@
 }
 
 func TestIpcModeTest(t *testing.T) {
-	ipcModes := map[container.IpcMode][]bool{
-		// private, host, container, valid
-		"":                         {true, false, false, true},
-		"something:weird":          {true, false, false, false},
-		":weird":                   {true, false, false, true},
-		"host":                     {false, true, false, true},
-		"container:name":           {false, false, true, true},
-		"container:name:something": {false, false, true, false},
-		"container:":               {false, false, true, false},
+	ipcModes := map[container.IpcMode]struct {
+		private   bool
+		host      bool
+		container bool
+		shareable bool
+		valid     bool
+		ctrName   string
+	}{
+		"":                      {valid: true},
+		"private":               {private: true, valid: true},
+		"something:weird":       {},
+		":weird":                {},
+		"host":                  {host: true, valid: true},
+		"container":             {},
+		"container:":            {container: true, valid: true, ctrName: ""},
+		"container:name":        {container: true, valid: true, ctrName: "name"},
+		"container:name1:name2": {container: true, valid: true, ctrName: "name1:name2"},
+		"shareable":             {shareable: true, valid: true},
 	}
+
 	for ipcMode, state := range ipcModes {
-		if ipcMode.IsPrivate() != state[0] {
-			t.Fatalf("IpcMode.IsPrivate for %v should have been %v but was %v", ipcMode, state[0], ipcMode.IsPrivate())
-		}
-		if ipcMode.IsHost() != state[1] {
-			t.Fatalf("IpcMode.IsHost for %v should have been %v but was %v", ipcMode, state[1], ipcMode.IsHost())
-		}
-		if ipcMode.IsContainer() != state[2] {
-			t.Fatalf("IpcMode.IsContainer for %v should have been %v but was %v", ipcMode, state[2], ipcMode.IsContainer())
-		}
-		if ipcMode.Valid() != state[3] {
-			t.Fatalf("IpcMode.Valid for %v should have been %v but was %v", ipcMode, state[3], ipcMode.Valid())
-		}
-	}
-	containerIpcModes := map[container.IpcMode]string{
-		"":                      "",
-		"something":             "",
-		"something:weird":       "weird",
-		"container":             "",
-		"container:":            "",
-		"container:name":        "name",
-		"container:name1:name2": "name1:name2",
-	}
-	for ipcMode, container := range containerIpcModes {
-		if ipcMode.Container() != container {
-			t.Fatalf("Expected %v for %v but was %v", container, ipcMode, ipcMode.Container())
-		}
+		assert.Equal(t, state.private, ipcMode.IsPrivate(), "IpcMode.IsPrivate() parsing failed for %q", ipcMode)
+		assert.Equal(t, state.host, ipcMode.IsHost(), "IpcMode.IsHost()  parsing failed for %q", ipcMode)
+		assert.Equal(t, state.container, ipcMode.IsContainer(), "IpcMode.IsContainer()  parsing failed for %q", ipcMode)
+		assert.Equal(t, state.shareable, ipcMode.IsShareable(), "IpcMode.IsShareable()  parsing failed for %q", ipcMode)
+		assert.Equal(t, state.valid, ipcMode.Valid(), "IpcMode.Valid()  parsing failed for %q", ipcMode)
+		assert.Equal(t, state.ctrName, ipcMode.Container(), "IpcMode.Container() parsing failed for %q", ipcMode)
 	}
 }
 
@@ -199,14 +190,12 @@
 			t.Fatal(err)
 		}
 
-		c, err := DecodeHostConfig(bytes.NewReader(b))
+		c, err := decodeHostConfig(bytes.NewReader(b))
 		if err != nil {
 			t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err))
 		}
 
-		if c.Privileged != false {
-			t.Fatalf("Expected privileged false, found %v\n", c.Privileged)
-		}
+		assert.False(t, c.Privileged)
 
 		if l := len(c.Binds); l != 1 {
 			t.Fatalf("Expected 1 bind, found %d\n", l)
diff --git a/vendor.conf b/vendor.conf
index 98fbc9f..78ea999 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -1,33 +1,38 @@
 # the following lines are in sorted order, FYI
-github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
-github.com/Microsoft/hcsshim v0.5.25
-github.com/Microsoft/go-winio v0.4.2
-github.com/Sirupsen/logrus v0.11.0
+github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e
+github.com/Microsoft/hcsshim v0.6.5
+github.com/Microsoft/go-winio v0.4.5
 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
 github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
 github.com/gorilla/context v1.1
 github.com/gorilla/mux v1.1
-github.com/jhowardmsft/opengcs v0.0.9
+github.com/Microsoft/opengcs v0.3.4
 github.com/kr/pty 5cf931ef8f
 github.com/mattn/go-shellwords v1.0.3
+github.com/sirupsen/logrus v1.0.3
 github.com/tchap/go-patricia v2.2.6
 github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
 golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
-golang.org/x/sys 739734461d1c916b6c72a63d7efda2b27edb369f
+golang.org/x/sys 07c182904dbd53199946ba614a412c61d3c548f5
 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
 github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756
 github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987
 github.com/pmezard/go-difflib v1.0.0
+github.com/gotestyourself/gotestyourself v1.1.0
 
 github.com/RackSec/srslog 456df3a81436d29ba874f3590eeeee25d666f8a5
 github.com/imdario/mergo 0.2.1
 golang.org/x/sync de49d9dcd27d4f764488181bea099dfe6179bcf0
 
+github.com/containerd/continuity 22694c680ee48fb8f50015b44618517e2bde77e8
+github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8
+github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2
+
 #get libnetwork packages
-github.com/docker/libnetwork e23c06b2917c82f6eed18c368f515060af78a09f
-github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
+github.com/docker/libnetwork 0f08d31bf0e640e0cdc6d5161227f87602d605c5
+github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
@@ -50,7 +55,7 @@
 github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
 
 # get graph and distribution packages
-github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621
+github.com/docker/distribution edc3ab29cdff8694dd6feb85cfeb4b5f1b38ed9c
 github.com/vbatts/tar-split v0.10.1
 github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
 
@@ -61,9 +66,9 @@
 google.golang.org/grpc v1.3.0
 
 # When updating, also update RUNC_COMMIT in hack/dockerfile/binaries-commits accordingly
-github.com/opencontainers/runc 2d41c047c83e09a6d61d464906feb2a2f3c52aa4 https://github.com/docker/runc
+github.com/opencontainers/runc 0351df1c5a66838d0c392b4ac4cf9450de844e2d
 github.com/opencontainers/image-spec 372ad780f63454fbbbbcc7cf80e5b90245c13e13
-github.com/opencontainers/runtime-spec d42f1eb741e6361e858d83fc75aa6893b66292c4 # specs
+github.com/opencontainers/runtime-spec v1.0.0
 
 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
 
@@ -82,7 +87,7 @@
 github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c
 
 # fsnotify
-github.com/fsnotify/fsnotify v1.2.11
+github.com/fsnotify/fsnotify v1.4.2
 
 # awslogs deps
 github.com/aws/aws-sdk-go v1.4.22
@@ -100,17 +105,15 @@
 google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
 
 # containerd
-github.com/containerd/containerd 3addd840653146c90a254301d6c3a663c7fd6429
+github.com/containerd/containerd 06b9cb35161009dcb7123345749fef02f7cea8e0
 github.com/tonistiigi/fifo 1405643975692217d6720f8b54aeee1bf2cd5cf4
-github.com/stevvooe/continuity cd7a8e21e2b6f84799f5dd4b65faf49c8d3ee02d
-github.com/tonistiigi/fsutil 0ac4c11b053b9c5c7c47558f81f96c7100ce50fb
 
 # cluster
-github.com/docker/swarmkit 3e2dd3c0a76149b1620b42d28dd6ff48270404e5
+github.com/docker/swarmkit 941a01844b89c56aa61086fecb167ab3af1de22b
 github.com/gogo/protobuf v0.4
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
 github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e
-golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2
+golang.org/x/crypto 558b6879de74bc843225cde5686419267ff707ca
 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
 github.com/hashicorp/go-memdb cb9a474f84cc5e41b273b20c6927680b2a8776ad
 github.com/hashicorp/go-immutable-radix 8e8ed81f8f0bf1bdd829593fdd5c29922c1ea990
diff --git a/vendor/github.com/Azure/go-ansiterm/README.md b/vendor/github.com/Azure/go-ansiterm/README.md
index e25e382..261c041 100644
--- a/vendor/github.com/Azure/go-ansiterm/README.md
+++ b/vendor/github.com/Azure/go-ansiterm/README.md
@@ -7,3 +7,6 @@
 The parser (parser.go) is a partial implementation of this state machine (http://vt100.net/emu/vt500_parser.png).  There are also two event handler implementations, one for tests (test_event_handler.go) to validate that the expected events are being produced and called, the other is a Windows implementation (winterm/win_event_handler.go).
 
 See parser_test.go for examples exercising the state machine and generating appropriate function calls.
+
+-----
+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
diff --git a/vendor/github.com/Azure/go-ansiterm/parser.go b/vendor/github.com/Azure/go-ansiterm/parser.go
index 169f68d..3286a9c 100644
--- a/vendor/github.com/Azure/go-ansiterm/parser.go
+++ b/vendor/github.com/Azure/go-ansiterm/parser.go
@@ -5,7 +5,7 @@
 	"io/ioutil"
 	"os"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var logger *logrus.Logger
diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
index 4d858ed..48998bb 100644
--- a/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
+++ b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go
@@ -9,7 +9,7 @@
 	"strconv"
 
 	"github.com/Azure/go-ansiterm"
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var logger *logrus.Logger
diff --git a/vendor/github.com/Microsoft/go-winio/backup.go b/vendor/github.com/Microsoft/go-winio/backup.go
index 27d6ace..2be34af 100644
--- a/vendor/github.com/Microsoft/go-winio/backup.go
+++ b/vendor/github.com/Microsoft/go-winio/backup.go
@@ -68,10 +68,20 @@
 	return &BackupStreamReader{r, 0}
 }
 
-// Next returns the next backup stream and prepares for calls to Write(). It skips the remainder of the current stream if
+// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if
 // it was not completely read.
 func (r *BackupStreamReader) Next() (*BackupHeader, error) {
 	if r.bytesLeft > 0 {
+		if s, ok := r.r.(io.Seeker); ok {
+			// Make sure Seek on io.SeekCurrent sometimes succeeds
+			// before trying the actual seek.
+			if _, err := s.Seek(0, io.SeekCurrent); err == nil {
+				if _, err = s.Seek(r.bytesLeft, io.SeekCurrent); err != nil {
+					return nil, err
+				}
+				r.bytesLeft = 0
+			}
+		}
 		if _, err := io.Copy(ioutil.Discard, r); err != nil {
 			return nil, err
 		}
@@ -220,7 +230,7 @@
 	ctx             uintptr
 }
 
-// NewBackupFileWrtier returns a new BackupFileWriter from a file handle. If includeSecurity is true,
+// NewBackupFileWriter returns a new BackupFileWriter from a file handle. If includeSecurity is true,
 // Write() will attempt to restore the security descriptor from the stream.
 func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
 	w := &BackupFileWriter{f, includeSecurity, 0}
diff --git a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go
index cfbcedf..53da908 100644
--- a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go
+++ b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go
@@ -36,6 +36,7 @@
 	hdrSecurityDescriptor    = "sd"
 	hdrRawSecurityDescriptor = "rawsd"
 	hdrMountPoint            = "mountpoint"
+	hdrEaPrefix              = "xattr."
 )
 
 func writeZeroes(w io.Writer, count int64) error {
@@ -118,6 +119,21 @@
 func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size int64, fileInfo *winio.FileBasicInfo) error {
 	name = filepath.ToSlash(name)
 	hdr := BasicInfoHeader(name, size, fileInfo)
+
+	// If r can be seeked, then this function is two-pass: pass 1 collects the
+	// tar header data, and pass 2 copies the data stream. If r cannot be
+	// seeked, then some header data (in particular EAs) will be silently lost.
+	var (
+		restartPos int64
+		err        error
+	)
+	sr, readTwice := r.(io.Seeker)
+	if readTwice {
+		if restartPos, err = sr.Seek(0, io.SeekCurrent); err != nil {
+			readTwice = false
+		}
+	}
+
 	br := winio.NewBackupStreamReader(r)
 	var dataHdr *winio.BackupHeader
 	for dataHdr == nil {
@@ -131,7 +147,9 @@
 		switch bhdr.Id {
 		case winio.BackupData:
 			hdr.Mode |= c_ISREG
-			dataHdr = bhdr
+			if !readTwice {
+				dataHdr = bhdr
+			}
 		case winio.BackupSecurity:
 			sd, err := ioutil.ReadAll(br)
 			if err != nil {
@@ -151,18 +169,54 @@
 				hdr.Winheaders[hdrMountPoint] = "1"
 			}
 			hdr.Linkname = rp.Target
-		case winio.BackupEaData, winio.BackupLink, winio.BackupPropertyData, winio.BackupObjectId, winio.BackupTxfsData:
+
+		case winio.BackupEaData:
+			eab, err := ioutil.ReadAll(br)
+			if err != nil {
+				return err
+			}
+			eas, err := winio.DecodeExtendedAttributes(eab)
+			if err != nil {
+				return err
+			}
+			for _, ea := range eas {
+				// Use base64 encoding for the binary value. Note that there
+				// is no way to encode the EA's flags, since their use doesn't
+				// make any sense for persisted EAs.
+				hdr.Winheaders[hdrEaPrefix+ea.Name] = base64.StdEncoding.EncodeToString(ea.Value)
+			}
+
+		case winio.BackupAlternateData, winio.BackupLink, winio.BackupPropertyData, winio.BackupObjectId, winio.BackupTxfsData:
 			// ignore these streams
 		default:
 			return fmt.Errorf("%s: unknown stream ID %d", name, bhdr.Id)
 		}
 	}
 
-	err := t.WriteHeader(hdr)
+	err = t.WriteHeader(hdr)
 	if err != nil {
 		return err
 	}
 
+	if readTwice {
+		// Get back to the data stream.
+		if _, err = sr.Seek(restartPos, io.SeekStart); err != nil {
+			return err
+		}
+		for dataHdr == nil {
+			bhdr, err := br.Next()
+			if err == io.EOF {
+				break
+			}
+			if err != nil {
+				return err
+			}
+			if bhdr.Id == winio.BackupData {
+				dataHdr = bhdr
+			}
+		}
+	}
+
 	if dataHdr != nil {
 		// A data stream was found. Copy the data.
 		if (dataHdr.Attributes & winio.StreamSparseAttributes) == 0 {
@@ -293,6 +347,38 @@
 			return nil, err
 		}
 	}
+	var eas []winio.ExtendedAttribute
+	for k, v := range hdr.Winheaders {
+		if !strings.HasPrefix(k, hdrEaPrefix) {
+			continue
+		}
+		data, err := base64.StdEncoding.DecodeString(v)
+		if err != nil {
+			return nil, err
+		}
+		eas = append(eas, winio.ExtendedAttribute{
+			Name:  k[len(hdrEaPrefix):],
+			Value: data,
+		})
+	}
+	if len(eas) != 0 {
+		eadata, err := winio.EncodeExtendedAttributes(eas)
+		if err != nil {
+			return nil, err
+		}
+		bhdr := winio.BackupHeader{
+			Id:   winio.BackupEaData,
+			Size: int64(len(eadata)),
+		}
+		err = bw.WriteHeader(&bhdr)
+		if err != nil {
+			return nil, err
+		}
+		_, err = bw.Write(eadata)
+		if err != nil {
+			return nil, err
+		}
+	}
 	if hdr.Typeflag == tar.TypeSymlink {
 		_, isMountPoint := hdr.Winheaders[hdrMountPoint]
 		rp := winio.ReparsePoint{
diff --git a/vendor/github.com/Microsoft/go-winio/ea.go b/vendor/github.com/Microsoft/go-winio/ea.go
new file mode 100644
index 0000000..b37e930
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/ea.go
@@ -0,0 +1,137 @@
+package winio

+

+import (

+	"bytes"

+	"encoding/binary"

+	"errors"

+)

+

+type fileFullEaInformation struct {

+	NextEntryOffset uint32

+	Flags           uint8

+	NameLength      uint8

+	ValueLength     uint16

+}

+

+var (

+	fileFullEaInformationSize = binary.Size(&fileFullEaInformation{})

+

+	errInvalidEaBuffer = errors.New("invalid extended attribute buffer")

+	errEaNameTooLarge  = errors.New("extended attribute name too large")

+	errEaValueTooLarge = errors.New("extended attribute value too large")

+)

+

+// ExtendedAttribute represents a single Windows EA.

+type ExtendedAttribute struct {

+	Name  string

+	Value []byte

+	Flags uint8

+}

+

+func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {

+	var info fileFullEaInformation

+	err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)

+	if err != nil {

+		err = errInvalidEaBuffer

+		return

+	}

+

+	nameOffset := fileFullEaInformationSize

+	nameLen := int(info.NameLength)

+	valueOffset := nameOffset + int(info.NameLength) + 1

+	valueLen := int(info.ValueLength)

+	nextOffset := int(info.NextEntryOffset)

+	if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {

+		err = errInvalidEaBuffer

+		return

+	}

+

+	ea.Name = string(b[nameOffset : nameOffset+nameLen])

+	ea.Value = b[valueOffset : valueOffset+valueLen]

+	ea.Flags = info.Flags

+	if info.NextEntryOffset != 0 {

+		nb = b[info.NextEntryOffset:]

+	}

+	return

+}

+

+// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION

+// buffer retrieved from BackupRead, ZwQueryEaFile, etc.

+func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {

+	for len(b) != 0 {

+		ea, nb, err := parseEa(b)

+		if err != nil {

+			return nil, err

+		}

+

+		eas = append(eas, ea)

+		b = nb

+	}

+	return

+}

+

+func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {

+	if int(uint8(len(ea.Name))) != len(ea.Name) {

+		return errEaNameTooLarge

+	}

+	if int(uint16(len(ea.Value))) != len(ea.Value) {

+		return errEaValueTooLarge

+	}

+	entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))

+	withPadding := (entrySize + 3) &^ 3

+	nextOffset := uint32(0)

+	if !last {

+		nextOffset = withPadding

+	}

+	info := fileFullEaInformation{

+		NextEntryOffset: nextOffset,

+		Flags:           ea.Flags,

+		NameLength:      uint8(len(ea.Name)),

+		ValueLength:     uint16(len(ea.Value)),

+	}

+

+	err := binary.Write(buf, binary.LittleEndian, &info)

+	if err != nil {

+		return err

+	}

+

+	_, err = buf.Write([]byte(ea.Name))

+	if err != nil {

+		return err

+	}

+

+	err = buf.WriteByte(0)

+	if err != nil {

+		return err

+	}

+

+	_, err = buf.Write(ea.Value)

+	if err != nil {

+		return err

+	}

+

+	_, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])

+	if err != nil {

+		return err

+	}

+

+	return nil

+}

+

+// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION

+// buffer for use with BackupWrite, ZwSetEaFile, etc.

+func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {

+	var buf bytes.Buffer

+	for i := range eas {

+		last := false

+		if i == len(eas)-1 {

+			last = true

+		}

+

+		err := writeEa(&buf, &eas[i], last)

+		if err != nil {

+			return nil, err

+		}

+	}

+	return buf.Bytes(), nil

+}

diff --git a/vendor/github.com/Microsoft/go-winio/file.go b/vendor/github.com/Microsoft/go-winio/file.go
index 613f31b..57ac369 100644
--- a/vendor/github.com/Microsoft/go-winio/file.go
+++ b/vendor/github.com/Microsoft/go-winio/file.go
@@ -23,6 +23,13 @@
 func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
 func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
 func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }
+func (b *atomicBool) swap(new bool) bool {
+	var newInt int32
+	if new {
+		newInt = 1
+	}
+	return atomic.SwapInt32((*int32)(b), newInt) == 1
+}
 
 const (
 	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
@@ -71,7 +78,8 @@
 type win32File struct {
 	handle        syscall.Handle
 	wg            sync.WaitGroup
-	closing       bool
+	wgLock        sync.RWMutex
+	closing       atomicBool
 	readDeadline  deadlineHandler
 	writeDeadline deadlineHandler
 }
@@ -107,14 +115,18 @@
 
 // closeHandle closes the resources associated with a Win32 handle
 func (f *win32File) closeHandle() {
-	if !f.closing {
+	f.wgLock.Lock()
+	// Atomically set that we are closing, releasing the resources only once.
+	if !f.closing.swap(true) {
+		f.wgLock.Unlock()
 		// cancel all IO and wait for it to complete
-		f.closing = true
 		cancelIoEx(f.handle, nil)
 		f.wg.Wait()
 		// at this point, no new IO can start
 		syscall.Close(f.handle)
 		f.handle = 0
+	} else {
+		f.wgLock.Unlock()
 	}
 }
 
@@ -127,10 +139,13 @@
 // prepareIo prepares for a new IO operation.
 // The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
 func (f *win32File) prepareIo() (*ioOperation, error) {
-	f.wg.Add(1)
-	if f.closing {
+	f.wgLock.RLock()
+	if f.closing.isSet() {
+		f.wgLock.RUnlock()
 		return nil, ErrFileClosed
 	}
+	f.wg.Add(1)
+	f.wgLock.RUnlock()
 	c := &ioOperation{}
 	c.ch = make(chan ioResult)
 	return c, nil
@@ -159,7 +174,7 @@
 		return int(bytes), err
 	}
 
-	if f.closing {
+	if f.closing.isSet() {
 		cancelIoEx(f.handle, &c.o)
 	}
 
@@ -175,7 +190,7 @@
 	case r = <-c.ch:
 		err = r.err
 		if err == syscall.ERROR_OPERATION_ABORTED {
-			if f.closing {
+			if f.closing.isSet() {
 				err = ErrFileClosed
 			}
 		}
diff --git a/vendor/github.com/Microsoft/go-winio/pipe.go b/vendor/github.com/Microsoft/go-winio/pipe.go
index da706cc..44340b8 100644
--- a/vendor/github.com/Microsoft/go-winio/pipe.go
+++ b/vendor/github.com/Microsoft/go-winio/pipe.go
@@ -265,9 +265,9 @@
 			if err == nil {
 				// Wait for the client to connect.
 				ch := make(chan error)
-				go func() {
+				go func(p *win32File) {
 					ch <- connectPipe(p)
-				}()
+				}(p)
 				select {
 				case err = <-ch:
 					if err != nil {
diff --git a/vendor/github.com/Microsoft/go-winio/vhd/vhd.go b/vendor/github.com/Microsoft/go-winio/vhd/vhd.go
new file mode 100644
index 0000000..32f0701
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/vhd/vhd.go
@@ -0,0 +1,82 @@
+// +build windows

+

+package vhd

+

+import "syscall"

+

+//go:generate go run mksyscall_windows.go -output zvhd.go vhd.go

+

+//sys createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.CreateVirtualDisk

+

+type virtualStorageType struct {

+	DeviceID uint32

+	VendorID [16]byte

+}

+

+const virtualDiskAccessNONE uint32 = 0

+const virtualDiskAccessATTACHRO uint32 = 65536

+const virtualDiskAccessATTACHRW uint32 = 131072

+const virtualDiskAccessDETACH uint32 = 262144

+const virtualDiskAccessGETINFO uint32 = 524288

+const virtualDiskAccessCREATE uint32 = 1048576

+const virtualDiskAccessMETAOPS uint32 = 2097152

+const virtualDiskAccessREAD uint32 = 851968

+const virtualDiskAccessALL uint32 = 4128768

+const virtualDiskAccessWRITABLE uint32 = 3276800

+

+const createVirtualDiskFlagNone uint32 = 0

+const createVirtualDiskFlagFullPhysicalAllocation uint32 = 1

+const createVirtualDiskFlagPreventWritesToSourceDisk uint32 = 2

+const createVirtualDiskFlagDoNotCopyMetadataFromParent uint32 = 4

+

+type version2 struct {

+	UniqueID                 [16]byte // GUID

+	MaximumSize              uint64

+	BlockSizeInBytes         uint32

+	SectorSizeInBytes        uint32

+	ParentPath               *uint16 // string

+	SourcePath               *uint16 // string

+	OpenFlags                uint32

+	ParentVirtualStorageType virtualStorageType

+	SourceVirtualStorageType virtualStorageType

+	ResiliencyGUID           [16]byte // GUID

+}

+

+type createVirtualDiskParameters struct {

+	Version  uint32 // Must always be set to 2

+	Version2 version2

+}

+

+// CreateVhdx will create a simple vhdx file at the given path using default values.

+func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {

+	var defaultType virtualStorageType

+

+	parameters := createVirtualDiskParameters{

+		Version: 2,

+		Version2: version2{

+			MaximumSize:      uint64(maxSizeInGb) * 1024 * 1024 * 1024,

+			BlockSizeInBytes: blockSizeInMb * 1024 * 1024,

+		},

+	}

+

+	var handle syscall.Handle

+

+	if err := createVirtualDisk(

+		&defaultType,

+		path,

+		virtualDiskAccessNONE,

+		nil,

+		createVirtualDiskFlagNone,

+		0,

+		&parameters,

+		nil,

+		&handle); err != nil {

+		return err

+	}

+

+	if err := syscall.CloseHandle(handle); err != nil {

+		return err

+	}

+

+	return nil

+}

diff --git a/vendor/github.com/Microsoft/go-winio/vhd/zvhd.go b/vendor/github.com/Microsoft/go-winio/vhd/zvhd.go
new file mode 100644
index 0000000..c450955
--- /dev/null
+++ b/vendor/github.com/Microsoft/go-winio/vhd/zvhd.go
@@ -0,0 +1,64 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package vhd
+
+import (
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+	errnoERROR_IO_PENDING = 997
+)
+
+var (
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+	switch e {
+	case 0:
+		return nil
+	case errnoERROR_IO_PENDING:
+		return errERROR_IO_PENDING
+	}
+	// TODO: add more here, after collecting data on the common
+	// error values see on Windows. (perhaps when running
+	// all.bat?)
+	return e
+}
+
+var (
+	modVirtDisk = windows.NewLazySystemDLL("VirtDisk.dll")
+
+	procCreateVirtualDisk = modVirtDisk.NewProc("CreateVirtualDisk")
+)
+
+func createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
+	var _p0 *uint16
+	_p0, err = syscall.UTF16PtrFromString(path)
+	if err != nil {
+		return
+	}
+	return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, flags, providerSpecificFlags, parameters, o, handle)
+}
+
+func _createVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
+	r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(flags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(handle)))
+	if r1 != 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/activatelayer.go b/vendor/github.com/Microsoft/hcsshim/activatelayer.go
index efc4d80..6d824d7 100644
--- a/vendor/github.com/Microsoft/hcsshim/activatelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/activatelayer.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // ActivateLayer will find the layer with the given id and mount it's filesystem.
 // For a read/write layer, the mounted filesystem will appear as a volume on the
diff --git a/vendor/github.com/Microsoft/hcsshim/container.go b/vendor/github.com/Microsoft/hcsshim/container.go
index 8bc7d6d..3354f70 100644
--- a/vendor/github.com/Microsoft/hcsshim/container.go
+++ b/vendor/github.com/Microsoft/hcsshim/container.go
@@ -8,7 +8,7 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -16,9 +16,10 @@
 )
 
 const (
-	pendingUpdatesQuery = `{ "PropertyTypes" : ["PendingUpdates"]}`
-	statisticsQuery     = `{ "PropertyTypes" : ["Statistics"]}`
-	processListQuery    = `{ "PropertyTypes" : ["ProcessList"]}`
+	pendingUpdatesQuery    = `{ "PropertyTypes" : ["PendingUpdates"]}`
+	statisticsQuery        = `{ "PropertyTypes" : ["Statistics"]}`
+	processListQuery       = `{ "PropertyTypes" : ["ProcessList"]}`
+	mappedVirtualDiskQuery = `{ "PropertyTypes" : ["MappedVirtualDisk"]}`
 )
 
 type container struct {
@@ -30,20 +31,21 @@
 
 // ContainerProperties holds the properties for a container and the processes running in that container
 type ContainerProperties struct {
-	ID                string `json:"Id"`
-	Name              string
-	SystemType        string
-	Owner             string
-	SiloGUID          string            `json:"SiloGuid,omitempty"`
-	RuntimeID         string            `json:"RuntimeId,omitempty"`
-	IsRuntimeTemplate bool              `json:",omitempty"`
-	RuntimeImagePath  string            `json:",omitempty"`
-	Stopped           bool              `json:",omitempty"`
-	ExitType          string            `json:",omitempty"`
-	AreUpdatesPending bool              `json:",omitempty"`
-	ObRoot            string            `json:",omitempty"`
-	Statistics        Statistics        `json:",omitempty"`
-	ProcessList       []ProcessListItem `json:",omitempty"`
+	ID                           string `json:"Id"`
+	Name                         string
+	SystemType                   string
+	Owner                        string
+	SiloGUID                     string                              `json:"SiloGuid,omitempty"`
+	RuntimeID                    string                              `json:"RuntimeId,omitempty"`
+	IsRuntimeTemplate            bool                                `json:",omitempty"`
+	RuntimeImagePath             string                              `json:",omitempty"`
+	Stopped                      bool                                `json:",omitempty"`
+	ExitType                     string                              `json:",omitempty"`
+	AreUpdatesPending            bool                                `json:",omitempty"`
+	ObRoot                       string                              `json:",omitempty"`
+	Statistics                   Statistics                          `json:",omitempty"`
+	ProcessList                  []ProcessListItem                   `json:",omitempty"`
+	MappedVirtualDiskControllers map[int]MappedVirtualDiskController `json:",omitempty"`
 }
 
 // MemoryStats holds the memory statistics for a container
@@ -103,6 +105,11 @@
 	UserTime100ns                uint64    `json:",omitempty"`
 }
 
+// MappedVirtualDiskController is the structure of an item returned by a MappedVirtualDiskList call on a container
+type MappedVirtualDiskController struct {
+	MappedVirtualDisks map[int]MappedVirtualDisk `json:",omitempty"`
+}
+
 // Type of Request Support in ModifySystem
 type RequestType string
 
@@ -194,12 +201,18 @@
 
 	if createError == nil || IsPending(createError) {
 		if err := container.registerCallback(); err != nil {
+			// Terminate the container if it still exists. We're okay to ignore a failure here.
+			container.Terminate()
 			return nil, makeContainerError(container, operation, "", err)
 		}
 	}
 
 	err = processAsyncHcsResult(createError, resultp, container.callbackNumber, hcsNotificationSystemCreateCompleted, &defaultTimeout)
 	if err != nil {
+		if err == ErrTimeout {
+			// Terminate the container if it still exists. We're okay to ignore a failure here.
+			container.Terminate()
+		}
 		return nil, makeContainerError(container, operation, configuration, err)
 	}
 
@@ -487,6 +500,55 @@
 	return properties.ProcessList, nil
 }
 
+// MappedVirtualDisks returns a map of the controllers and the disks mapped
+// to a container.
+//
+// Example of JSON returned by the query.
+//{
+//   "Id":"1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3_svm",
+//   "SystemType":"Container",
+//   "RuntimeOsType":"Linux",
+//   "RuntimeId":"00000000-0000-0000-0000-000000000000",
+//   "State":"Running",
+//   "MappedVirtualDiskControllers":{
+//      "0":{
+//         "MappedVirtualDisks":{
+//            "2":{
+//               "HostPath":"C:\\lcow\\lcow\\scratch\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3.vhdx",
+//               "ContainerPath":"/mnt/gcs/LinuxServiceVM/scratch",
+//               "Lun":2,
+//               "CreateInUtilityVM":true
+//            },
+//            "3":{
+//               "HostPath":"C:\\lcow\\lcow\\1126e8d7d279c707a666972a15976371d365eaf622c02cea2c442b84f6f550a3\\sandbox.vhdx",
+//               "Lun":3,
+//               "CreateInUtilityVM":true,
+//               "AttachOnly":true
+//            }
+//         }
+//      }
+//   }
+//}
+func (container *container) MappedVirtualDisks() (map[int]MappedVirtualDiskController, error) {
+	container.handleLock.RLock()
+	defer container.handleLock.RUnlock()
+	operation := "MappedVirtualDiskList"
+	title := "HCSShim::Container::" + operation
+	logrus.Debugf(title+" id=%s", container.id)
+
+	if container.handle == 0 {
+		return nil, makeContainerError(container, operation, "", ErrAlreadyClosed)
+	}
+
+	properties, err := container.properties(mappedVirtualDiskQuery)
+	if err != nil {
+		return nil, makeContainerError(container, operation, "", err)
+	}
+
+	logrus.Debugf(title+" succeeded id=%s", container.id)
+	return properties.MappedVirtualDiskControllers, nil
+}
+
 // Pause pauses the execution of the container. This feature is not enabled in TP5.
 func (container *container) Pause() error {
 	container.handleLock.RLock()
diff --git a/vendor/github.com/Microsoft/hcsshim/createlayer.go b/vendor/github.com/Microsoft/hcsshim/createlayer.go
index 9ecffb1..035d9c3 100644
--- a/vendor/github.com/Microsoft/hcsshim/createlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/createlayer.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // CreateLayer creates a new, empty, read-only layer on the filesystem based on
 // the parent layer provided.
diff --git a/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go b/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
index b69c3da..7a6a885 100644
--- a/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/createsandboxlayer.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // CreateSandboxLayer creates and populates new read-write layer for use by a container.
 // This requires both the id of the direct parent layer, as well as the full list
diff --git a/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go b/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
index c02bcb3..fd78503 100644
--- a/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/deactivatelayer.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
 func DeactivateLayer(info DriverInfo, id string) error {
diff --git a/vendor/github.com/Microsoft/hcsshim/destroylayer.go b/vendor/github.com/Microsoft/hcsshim/destroylayer.go
index 91ed269..b1e3b89 100644
--- a/vendor/github.com/Microsoft/hcsshim/destroylayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/destroylayer.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // DestroyLayer will remove the on-disk files representing the layer with the given
 // id, including that layer's containing folder, if any.
diff --git a/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go b/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
index e168921..6946c6a 100644
--- a/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
+++ b/vendor/github.com/Microsoft/hcsshim/expandsandboxsize.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // ExpandSandboxSize expands the size of a layer to at least size bytes.
 func ExpandSandboxSize(info DriverInfo, layerId string, size uint64) error {
diff --git a/vendor/github.com/Microsoft/hcsshim/exportlayer.go b/vendor/github.com/Microsoft/hcsshim/exportlayer.go
index 3c9b24e..d7025f2 100644
--- a/vendor/github.com/Microsoft/hcsshim/exportlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/exportlayer.go
@@ -7,7 +7,7 @@
 	"syscall"
 
 	"github.com/Microsoft/go-winio"
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // ExportLayer will create a folder at exportFolderPath and fill that folder with
diff --git a/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go b/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
index 41b5758..89f8079 100644
--- a/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
+++ b/vendor/github.com/Microsoft/hcsshim/getlayermountpath.go
@@ -3,7 +3,7 @@
 import (
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // GetLayerMountPath will look for a mounted layer with the given id and return
diff --git a/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go b/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
index 01ab4da..05d3d95 100644
--- a/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
+++ b/vendor/github.com/Microsoft/hcsshim/getsharedbaseimages.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // GetSharedBaseImages will enumerate the images stored in the common central
 // image store and return descriptive info about those images for the purpose
diff --git a/vendor/github.com/Microsoft/hcsshim/hcsshim.go b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
index 3cb3a29..236ba1f 100644
--- a/vendor/github.com/Microsoft/hcsshim/hcsshim.go
+++ b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
@@ -8,7 +8,7 @@
 	"syscall"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 //go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
new file mode 100644
index 0000000..92afc0c
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
@@ -0,0 +1,318 @@
+package hcsshim

+

+import (

+	"encoding/json"

+	"fmt"

+	"net"

+

+	"github.com/sirupsen/logrus"

+)

+

+// HNSEndpoint represents a network endpoint in HNS

+type HNSEndpoint struct {

+	Id                 string            `json:"ID,omitempty"`

+	Name               string            `json:",omitempty"`

+	VirtualNetwork     string            `json:",omitempty"`

+	VirtualNetworkName string            `json:",omitempty"`

+	Policies           []json.RawMessage `json:",omitempty"`

+	MacAddress         string            `json:",omitempty"`

+	IPAddress          net.IP            `json:",omitempty"`

+	DNSSuffix          string            `json:",omitempty"`

+	DNSServerList      string            `json:",omitempty"`

+	GatewayAddress     string            `json:",omitempty"`

+	EnableInternalDNS  bool              `json:",omitempty"`

+	DisableICC         bool              `json:",omitempty"`

+	PrefixLength       uint8             `json:",omitempty"`

+	IsRemoteEndpoint   bool              `json:",omitempty"`

+}

+

+//SystemType represents the type of the system on which actions are done

+type SystemType string

+

+// SystemType const

+const (

+	ContainerType      SystemType = "Container"

+	VirtualMachineType SystemType = "VirtualMachine"

+	HostType           SystemType = "Host"

+)

+

+// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system

+// Supported resource types are Network and Request Types are Add/Remove

+type EndpointAttachDetachRequest struct {

+	ContainerID    string     `json:"ContainerId,omitempty"`

+	SystemType     SystemType `json:"SystemType"`

+	CompartmentID  uint16     `json:"CompartmentId,omitempty"`

+	VirtualNICName string     `json:"VirtualNicName,omitempty"`

+}

+

+// EndpointResquestResponse is object to get the endpoint request response

+type EndpointResquestResponse struct {

+	Success bool

+	Error   string

+}

+

+// HNSEndpointRequest makes a HNS call to modify/query a network endpoint

+func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {

+	endpoint := &HNSEndpoint{}

+	err := hnsCall(method, "/endpoints/"+path, request, &endpoint)

+	if err != nil {

+		return nil, err

+	}

+

+	return endpoint, nil

+}

+

+// HNSListEndpointRequest makes a HNS call to query the list of available endpoints

+func HNSListEndpointRequest() ([]HNSEndpoint, error) {

+	var endpoint []HNSEndpoint

+	err := hnsCall("GET", "/endpoints/", "", &endpoint)

+	if err != nil {

+		return nil, err

+	}

+

+	return endpoint, nil

+}

+

+// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container

+func HotAttachEndpoint(containerID string, endpointID string) error {

+	return modifyNetworkEndpoint(containerID, endpointID, Add)

+}

+

+// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container

+func HotDetachEndpoint(containerID string, endpointID string) error {

+	return modifyNetworkEndpoint(containerID, endpointID, Remove)

+}

+

+// ModifyContainer corresponding to the container id, by sending a request

+func modifyContainer(id string, request *ResourceModificationRequestResponse) error {

+	container, err := OpenContainer(id)

+	if err != nil {

+		if IsNotExist(err) {

+			return ErrComputeSystemDoesNotExist

+		}

+		return getInnerError(err)

+	}

+	defer container.Close()

+	err = container.Modify(request)

+	if err != nil {

+		if IsNotSupported(err) {

+			return ErrPlatformNotSupported

+		}

+		return getInnerError(err)

+	}

+

+	return nil

+}

+

+func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {

+	requestMessage := &ResourceModificationRequestResponse{

+		Resource: Network,

+		Request:  request,

+		Data:     endpointID,

+	}

+	err := modifyContainer(containerID, requestMessage)

+

+	if err != nil {

+		return err

+	}

+

+	return nil

+}

+

+// GetHNSEndpointByID get the Endpoint by ID

+func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {

+	return HNSEndpointRequest("GET", endpointID, "")

+}

+

+// GetHNSEndpointByName gets the endpoint filtered by Name

+func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {

+	hnsResponse, err := HNSListEndpointRequest()

+	if err != nil {

+		return nil, err

+	}

+	for _, hnsEndpoint := range hnsResponse {

+		if hnsEndpoint.Name == endpointName {

+			return &hnsEndpoint, nil

+		}

+	}

+	return nil, fmt.Errorf("Endpoint %v not found", endpointName)

+}

+

+// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods

+func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {

+	operation := "Create"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+

+	jsonString, err := json.Marshal(endpoint)

+	if err != nil {

+		return nil, err

+	}

+	return HNSEndpointRequest("POST", "", string(jsonString))

+}

+

+// Delete Endpoint by sending EndpointRequest to HNS

+func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {

+	operation := "Delete"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+

+	return HNSEndpointRequest("DELETE", endpoint.Id, "")

+}

+

+// Update Endpoint

+func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {

+	operation := "Update"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+	jsonString, err := json.Marshal(endpoint)

+	if err != nil {

+		return nil, err

+	}

+	err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)

+

+	return endpoint, err

+}

+

+// ContainerHotAttach attaches an endpoint to a running container

+func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {

+	operation := "ContainerHotAttach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)

+

+	return modifyNetworkEndpoint(containerID, endpoint.Id, Add)

+}

+

+// ContainerHotDetach detaches an endpoint from a running container

+func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {

+	operation := "ContainerHotDetach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)

+

+	return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)

+}

+

+// ApplyACLPolicy applies Acl Policy on the Endpoint

+func (endpoint *HNSEndpoint) ApplyACLPolicy(policy *ACLPolicy) error {

+	operation := "ApplyACLPolicy"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+

+	jsonString, err := json.Marshal(policy)

+	if err != nil {

+		return err

+	}

+	endpoint.Policies[0] = jsonString

+	_, err = endpoint.Update()

+	return err

+}

+

+// ContainerAttach attaches an endpoint to container

+func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {

+	operation := "ContainerAttach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+

+	requestMessage := &EndpointAttachDetachRequest{

+		ContainerID:   containerID,

+		CompartmentID: compartmentID,

+		SystemType:    ContainerType,

+	}

+	response := &EndpointResquestResponse{}

+	jsonString, err := json.Marshal(requestMessage)

+	if err != nil {

+		return err

+	}

+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)

+}

+

+// ContainerDetach detaches an endpoint from container

+func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {

+	operation := "ContainerDetach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+

+	requestMessage := &EndpointAttachDetachRequest{

+		ContainerID: containerID,

+		SystemType:  ContainerType,

+	}

+	response := &EndpointResquestResponse{}

+

+	jsonString, err := json.Marshal(requestMessage)

+	if err != nil {

+		return err

+	}

+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)

+}

+

+// HostAttach attaches a nic on the host

+func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {

+	operation := "HostAttach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+	requestMessage := &EndpointAttachDetachRequest{

+		CompartmentID: compartmentID,

+		SystemType:    HostType,

+	}

+	response := &EndpointResquestResponse{}

+

+	jsonString, err := json.Marshal(requestMessage)

+	if err != nil {

+		return err

+	}

+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)

+

+}

+

+// HostDetach detaches a nic on the host

+func (endpoint *HNSEndpoint) HostDetach() error {

+	operation := "HostDetach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+	requestMessage := &EndpointAttachDetachRequest{

+		SystemType: HostType,

+	}

+	response := &EndpointResquestResponse{}

+

+	jsonString, err := json.Marshal(requestMessage)

+	if err != nil {

+		return err

+	}

+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)

+}

+

+// VirtualMachineNICAttach attaches a endpoint to a virtual machine

+func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {

+	operation := "VirtualMachineNicAttach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+	requestMessage := &EndpointAttachDetachRequest{

+		VirtualNICName: virtualMachineNICName,

+		SystemType:     VirtualMachineType,

+	}

+	response := &EndpointResquestResponse{}

+

+	jsonString, err := json.Marshal(requestMessage)

+	if err != nil {

+		return err

+	}

+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)

+}

+

+// VirtualMachineNICDetach detaches a endpoint  from a virtual machine

+func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {

+	operation := "VirtualMachineNicDetach"

+	title := "HCSShim::HNSEndpoint::" + operation

+	logrus.Debugf(title+" id=%s", endpoint.Id)

+

+	requestMessage := &EndpointAttachDetachRequest{

+		SystemType: VirtualMachineType,

+	}

+	response := &EndpointResquestResponse{}

+

+	jsonString, err := json.Marshal(requestMessage)

+	if err != nil {

+		return err

+	}

+	return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)

+}

diff --git a/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go b/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
index 97ec2e8..2c1b979 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnsfuncs.go
@@ -3,99 +3,10 @@
 import (
 	"encoding/json"
 	"fmt"
-	"net"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
-type NatPolicy struct {
-	Type         string
-	Protocol     string
-	InternalPort uint16
-	ExternalPort uint16
-}
-
-type QosPolicy struct {
-	Type                            string
-	MaximumOutgoingBandwidthInBytes uint64
-}
-
-type VlanPolicy struct {
-	Type string
-	VLAN uint
-}
-
-type VsidPolicy struct {
-	Type string
-	VSID uint
-}
-
-type PaPolicy struct {
-	Type string
-	PA   string
-}
-
-// Subnet is assoicated with a network and represents a list
-// of subnets available to the network
-type Subnet struct {
-	AddressPrefix  string            `json:",omitempty"`
-	GatewayAddress string            `json:",omitempty"`
-	Policies       []json.RawMessage `json:",omitempty"`
-}
-
-// MacPool is assoicated with a network and represents a list
-// of macaddresses available to the network
-type MacPool struct {
-	StartMacAddress string `json:",omitempty"`
-	EndMacAddress   string `json:",omitempty"`
-}
-
-// HNSNetwork represents a network in HNS
-type HNSNetwork struct {
-	Id                   string            `json:"ID,omitempty"`
-	Name                 string            `json:",omitempty"`
-	Type                 string            `json:",omitempty"`
-	NetworkAdapterName   string            `json:",omitempty"`
-	SourceMac            string            `json:",omitempty"`
-	Policies             []json.RawMessage `json:",omitempty"`
-	MacPools             []MacPool         `json:",omitempty"`
-	Subnets              []Subnet          `json:",omitempty"`
-	DNSSuffix            string            `json:",omitempty"`
-	DNSServerList        string            `json:",omitempty"`
-	DNSServerCompartment uint32            `json:",omitempty"`
-	ManagementIP         string            `json:",omitempty"`
-}
-
-// HNSEndpoint represents a network endpoint in HNS
-type HNSEndpoint struct {
-	Id                 string            `json:"ID,omitempty"`
-	Name               string            `json:",omitempty"`
-	VirtualNetwork     string            `json:",omitempty"`
-	VirtualNetworkName string            `json:",omitempty"`
-	Policies           []json.RawMessage `json:",omitempty"`
-	MacAddress         string            `json:",omitempty"`
-	IPAddress          net.IP            `json:",omitempty"`
-	DNSSuffix          string            `json:",omitempty"`
-	DNSServerList      string            `json:",omitempty"`
-	GatewayAddress     string            `json:",omitempty"`
-	EnableInternalDNS  bool              `json:",omitempty"`
-	DisableICC         bool              `json:",omitempty"`
-	PrefixLength       uint8             `json:",omitempty"`
-	IsRemoteEndpoint   bool              `json:",omitempty"`
-}
-
-type hnsNetworkResponse struct {
-	Success bool
-	Error   string
-	Output  HNSNetwork
-}
-
-type hnsResponse struct {
-	Success bool
-	Error   string
-	Output  json.RawMessage
-}
-
 func hnsCall(method, path, request string, returnResponse interface{}) error {
 	var responseBuffer *uint16
 	logrus.Debugf("[%s]=>[%s] Request : %s", method, path, request)
@@ -127,145 +38,3 @@
 
 	return nil
 }
-
-// HNSNetworkRequest makes a call into HNS to update/query a single network
-func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
-	var network HNSNetwork
-	err := hnsCall(method, "/networks/"+path, request, &network)
-	if err != nil {
-		return nil, err
-	}
-
-	return &network, nil
-}
-
-// HNSListNetworkRequest makes a HNS call to query the list of available networks
-func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
-	var network []HNSNetwork
-	err := hnsCall(method, "/networks/"+path, request, &network)
-	if err != nil {
-		return nil, err
-	}
-
-	return network, nil
-}
-
-// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
-func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
-	endpoint := &HNSEndpoint{}
-	err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return endpoint, nil
-}
-
-// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
-func HNSListEndpointRequest() ([]HNSEndpoint, error) {
-	var endpoint []HNSEndpoint
-	err := hnsCall("GET", "/endpoints/", "", &endpoint)
-	if err != nil {
-		return nil, err
-	}
-
-	return endpoint, nil
-}
-
-// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
-func HotAttachEndpoint(containerID string, endpointID string) error {
-	return modifyNetworkEndpoint(containerID, endpointID, Add)
-}
-
-// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
-func HotDetachEndpoint(containerID string, endpointID string) error {
-	return modifyNetworkEndpoint(containerID, endpointID, Remove)
-}
-
-// ModifyContainer corresponding to the container id, by sending a request
-func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
-	container, err := OpenContainer(id)
-	if err != nil {
-		if IsNotExist(err) {
-			return ErrComputeSystemDoesNotExist
-		}
-		return getInnerError(err)
-	}
-	defer container.Close()
-	err = container.Modify(request)
-	if err != nil {
-		if IsNotSupported(err) {
-			return ErrPlatformNotSupported
-		}
-		return getInnerError(err)
-	}
-
-	return nil
-}
-
-func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
-	requestMessage := &ResourceModificationRequestResponse{
-		Resource: Network,
-		Request:  request,
-		Data:     endpointID,
-	}
-	err := modifyContainer(containerID, requestMessage)
-
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-// GetHNSNetworkByID
-func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
-	return HNSNetworkRequest("GET", networkID, "")
-}
-
-// GetHNSNetworkName filtered by Name
-func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
-	hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
-	if err != nil {
-		return nil, err
-	}
-	for _, hnsnetwork := range hsnnetworks {
-		if hnsnetwork.Name == networkName {
-			return &hnsnetwork, nil
-		}
-	}
-	return nil, fmt.Errorf("Network %v not found", networkName)
-}
-
-// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
-func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
-	jsonString, err := json.Marshal(endpoint)
-	if err != nil {
-		return nil, err
-	}
-	return HNSEndpointRequest("POST", "", string(jsonString))
-}
-
-// Create Endpoint by sending EndpointRequest to HNS
-func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
-	return HNSEndpointRequest("DELETE", endpoint.Id, "")
-}
-
-// GetHNSEndpointByID
-func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
-	return HNSEndpointRequest("GET", endpointID, "")
-}
-
-// GetHNSNetworkName filtered by Name
-func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
-	hnsResponse, err := HNSListEndpointRequest()
-	if err != nil {
-		return nil, err
-	}
-	for _, hnsEndpoint := range hnsResponse {
-		if hnsEndpoint.Name == endpointName {
-			return &hnsEndpoint, nil
-		}
-	}
-	return nil, fmt.Errorf("Endpoint %v not found", endpointName)
-}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
new file mode 100644
index 0000000..3345bfa
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
@@ -0,0 +1,142 @@
+package hcsshim

+

+import (

+	"encoding/json"

+	"fmt"

+	"net"

+

+	"github.com/sirupsen/logrus"

+)

+

+// Subnet is assoicated with a network and represents a list

+// of subnets available to the network

+type Subnet struct {

+	AddressPrefix  string            `json:",omitempty"`

+	GatewayAddress string            `json:",omitempty"`

+	Policies       []json.RawMessage `json:",omitempty"`

+}

+

+// MacPool is assoicated with a network and represents a list

+// of macaddresses available to the network

+type MacPool struct {

+	StartMacAddress string `json:",omitempty"`

+	EndMacAddress   string `json:",omitempty"`

+}

+

+// HNSNetwork represents a network in HNS

+type HNSNetwork struct {

+	Id                   string            `json:"ID,omitempty"`

+	Name                 string            `json:",omitempty"`

+	Type                 string            `json:",omitempty"`

+	NetworkAdapterName   string            `json:",omitempty"`

+	SourceMac            string            `json:",omitempty"`

+	Policies             []json.RawMessage `json:",omitempty"`

+	MacPools             []MacPool         `json:",omitempty"`

+	Subnets              []Subnet          `json:",omitempty"`

+	DNSSuffix            string            `json:",omitempty"`

+	DNSServerList        string            `json:",omitempty"`

+	DNSServerCompartment uint32            `json:",omitempty"`

+	ManagementIP         string            `json:",omitempty"`

+	AutomaticDNS         bool              `json:",omitempty"`

+}

+

+type hnsNetworkResponse struct {

+	Success bool

+	Error   string

+	Output  HNSNetwork

+}

+

+type hnsResponse struct {

+	Success bool

+	Error   string

+	Output  json.RawMessage

+}

+

+// HNSNetworkRequest makes a call into HNS to update/query a single network

+func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {

+	var network HNSNetwork

+	err := hnsCall(method, "/networks/"+path, request, &network)

+	if err != nil {

+		return nil, err

+	}

+

+	return &network, nil

+}

+

+// HNSListNetworkRequest makes a HNS call to query the list of available networks

+func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {

+	var network []HNSNetwork

+	err := hnsCall(method, "/networks/"+path, request, &network)

+	if err != nil {

+		return nil, err

+	}

+

+	return network, nil

+}

+

+// GetHNSNetworkByID

+func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {

+	return HNSNetworkRequest("GET", networkID, "")

+}

+

+// GetHNSNetworkName filtered by Name

+func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {

+	hsnnetworks, err := HNSListNetworkRequest("GET", "", "")

+	if err != nil {

+		return nil, err

+	}

+	for _, hnsnetwork := range hsnnetworks {

+		if hnsnetwork.Name == networkName {

+			return &hnsnetwork, nil

+		}

+	}

+	return nil, fmt.Errorf("Network %v not found", networkName)

+}

+

+// Create Network by sending NetworkRequest to HNS.

+func (network *HNSNetwork) Create() (*HNSNetwork, error) {

+	operation := "Create"

+	title := "HCSShim::HNSNetwork::" + operation

+	logrus.Debugf(title+" id=%s", network.Id)

+

+	jsonString, err := json.Marshal(network)

+	if err != nil {

+		return nil, err

+	}

+	return HNSNetworkRequest("POST", "", string(jsonString))

+}

+

+// Delete Network by sending NetworkRequest to HNS

+func (network *HNSNetwork) Delete() (*HNSNetwork, error) {

+	operation := "Delete"

+	title := "HCSShim::HNSNetwork::" + operation

+	logrus.Debugf(title+" id=%s", network.Id)

+

+	return HNSNetworkRequest("DELETE", network.Id, "")

+}

+

+// Creates an endpoint on the Network.

+func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {

+	return &HNSEndpoint{

+		VirtualNetwork: network.Id,

+		IPAddress:      ipAddress,

+		MacAddress:     string(macAddress),

+	}

+}

+

+func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {

+	operation := "CreateEndpoint"

+	title := "HCSShim::HNSNetwork::" + operation

+	logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)

+

+	endpoint.VirtualNetwork = network.Id

+	return endpoint.Create()

+}

+

+func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {

+	operation := "CreateRemoteEndpoint"

+	title := "HCSShim::HNSNetwork::" + operation

+	logrus.Debugf(title+" id=%s", network.Id)

+	endpoint.IsRemoteEndpoint = true

+	return network.CreateEndpoint(endpoint)

+}

diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicy.go b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
new file mode 100644
index 0000000..ecfbf0e
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
@@ -0,0 +1,95 @@
+package hcsshim

+

+// Type of Request Support in ModifySystem

+type PolicyType string

+

+// RequestType const

+const (

+	Nat                  PolicyType = "NAT"

+	ACL                  PolicyType = "ACL"

+	PA                   PolicyType = "PA"

+	VLAN                 PolicyType = "VLAN"

+	VSID                 PolicyType = "VSID"

+	VNet                 PolicyType = "VNET"

+	L2Driver             PolicyType = "L2Driver"

+	Isolation            PolicyType = "Isolation"

+	QOS                  PolicyType = "QOS"

+	OutboundNat          PolicyType = "OutBoundNAT"

+	ExternalLoadBalancer PolicyType = "ELB"

+	Route                PolicyType = "ROUTE"

+)

+

+type NatPolicy struct {

+	Type         PolicyType `json:"Type"`

+	Protocol     string

+	InternalPort uint16

+	ExternalPort uint16

+}

+

+type QosPolicy struct {

+	Type                            PolicyType `json:"Type"`

+	MaximumOutgoingBandwidthInBytes uint64

+}

+

+type IsolationPolicy struct {

+	Type               PolicyType `json:"Type"`

+	VLAN               uint

+	VSID               uint

+	InDefaultIsolation bool

+}

+

+type VlanPolicy struct {

+	Type PolicyType `json:"Type"`

+	VLAN uint

+}

+

+type VsidPolicy struct {

+	Type PolicyType `json:"Type"`

+	VSID uint

+}

+

+type PaPolicy struct {

+	Type PolicyType `json:"Type"`

+	PA   string     `json:"PA"`

+}

+

+type OutboundNatPolicy struct {

+	Policy

+	VIP        string   `json:"VIP,omitempty"`

+	Exceptions []string `json:"ExceptionList,omitempty"`

+}

+

+type ActionType string

+type DirectionType string

+type RuleType string

+

+const (

+	Allow ActionType = "Allow"

+	Block ActionType = "Block"

+

+	In  DirectionType = "In"

+	Out DirectionType = "Out"

+

+	Host   RuleType = "Host"

+	Switch RuleType = "Switch"

+)

+

+type ACLPolicy struct {

+	Type          PolicyType `json:"Type"`

+	Protocol      uint16

+	InternalPort  uint16

+	Action        ActionType

+	Direction     DirectionType

+	LocalAddress  string

+	RemoteAddress string

+	LocalPort     uint16

+	RemotePort    uint16

+	RuleType      RuleType `json:"RuleType,omitempty"`

+

+	Priority    uint16

+	ServiceName string

+}

+

+type Policy struct {

+	Type PolicyType `json:"Type"`

+}

diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
new file mode 100644
index 0000000..bbd7e1e
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
@@ -0,0 +1,200 @@
+package hcsshim

+

+import (

+	"encoding/json"

+

+	"github.com/sirupsen/logrus"

+)

+

+// RoutePolicy is a structure defining schema for Route based Policy

+type RoutePolicy struct {

+	Policy

+	DestinationPrefix string `json:"DestinationPrefix,omitempty"`

+	NextHop           string `json:"NextHop,omitempty"`

+	EncapEnabled      bool   `json:"NeedEncap,omitempty"`

+}

+

+// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy

+type ELBPolicy struct {

+	LBPolicy

+	SourceVIP string   `json:"SourceVIP,omitempty"`

+	VIPs      []string `json:"VIPs,omitempty"`

+	ILB       bool     `json:"ILB,omitempty"`

+}

+

+// LBPolicy is a structure defining schema for LoadBalancing based Policy

+type LBPolicy struct {

+	Policy

+	Protocol     uint16 `json:"Protocol,omitempty"`

+	InternalPort uint16

+	ExternalPort uint16

+}

+

+// PolicyList is a structure defining schema for Policy list request

+type PolicyList struct {

+	ID                 string            `json:"ID,omitempty"`

+	EndpointReferences []string          `json:"References,omitempty"`

+	Policies           []json.RawMessage `json:"Policies,omitempty"`

+}

+

+// HNSPolicyListRequest makes a call into HNS to update/query a single network

+func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {

+	var policy PolicyList

+	err := hnsCall(method, "/policylists/"+path, request, &policy)

+	if err != nil {

+		return nil, err

+	}

+

+	return &policy, nil

+}

+

+// HNSListPolicyListRequest gets all the policy list

+func HNSListPolicyListRequest() ([]PolicyList, error) {

+	var plist []PolicyList

+	err := hnsCall("GET", "/policylists/", "", &plist)

+	if err != nil {

+		return nil, err

+	}

+

+	return plist, nil

+}

+

+// PolicyListRequest makes a HNS call to modify/query a network policy list

+func PolicyListRequest(method, path, request string) (*PolicyList, error) {

+	policylist := &PolicyList{}

+	err := hnsCall(method, "/policylists/"+path, request, &policylist)

+	if err != nil {

+		return nil, err

+	}

+

+	return policylist, nil

+}

+

+// GetPolicyListByID get the policy list by ID

+func GetPolicyListByID(policyListID string) (*PolicyList, error) {

+	return PolicyListRequest("GET", policyListID, "")

+}

+

+// Create PolicyList by sending PolicyListRequest to HNS.

+func (policylist *PolicyList) Create() (*PolicyList, error) {

+	operation := "Create"

+	title := "HCSShim::PolicyList::" + operation

+	logrus.Debugf(title+" id=%s", policylist.ID)

+	jsonString, err := json.Marshal(policylist)

+	if err != nil {

+		return nil, err

+	}

+	return PolicyListRequest("POST", "", string(jsonString))

+}

+

+// Delete deletes PolicyList

+func (policylist *PolicyList) Delete() (*PolicyList, error) {

+	operation := "Delete"

+	title := "HCSShim::PolicyList::" + operation

+	logrus.Debugf(title+" id=%s", policylist.ID)

+

+	return PolicyListRequest("DELETE", policylist.ID, "")

+}

+

+// AddEndpoint add an endpoint to a Policy List

+func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {

+	operation := "AddEndpoint"

+	title := "HCSShim::PolicyList::" + operation

+	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)

+

+	_, err := policylist.Delete()

+	if err != nil {

+		return nil, err

+	}

+

+	// Add Endpoint to the Existing List

+	policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)

+

+	return policylist.Create()

+}

+

+// RemoveEndpoint removes an endpoint from the Policy List

+func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {

+	operation := "RemoveEndpoint"

+	title := "HCSShim::PolicyList::" + operation

+	logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)

+

+	_, err := policylist.Delete()

+	if err != nil {

+		return nil, err

+	}

+

+	elementToRemove := "/endpoints/" + endpoint.Id

+

+	var references []string

+

+	for _, endpointReference := range policylist.EndpointReferences {

+		if endpointReference == elementToRemove {

+			continue

+		}

+		references = append(references, endpointReference)

+	}

+	policylist.EndpointReferences = references

+	return policylist.Create()

+}

+

+// AddLoadBalancer policy list for the specified endpoints

+func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {

+	operation := "AddLoadBalancer"

+	title := "HCSShim::PolicyList::" + operation

+	logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)

+

+	policylist := &PolicyList{}

+

+	elbPolicy := &ELBPolicy{

+		SourceVIP: sourceVIP,

+		ILB:       isILB,

+	}

+

+	if len(vip) > 0 {

+		elbPolicy.VIPs = []string{vip}

+	}

+	elbPolicy.Type = ExternalLoadBalancer

+	elbPolicy.Protocol = protocol

+	elbPolicy.InternalPort = internalPort

+	elbPolicy.ExternalPort = externalPort

+

+	for _, endpoint := range endpoints {

+		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)

+	}

+

+	jsonString, err := json.Marshal(elbPolicy)

+	if err != nil {

+		return nil, err

+	}

+	policylist.Policies = append(policylist.Policies, jsonString)

+	return policylist.Create()

+}

+

+// AddRoute adds route policy list for the specified endpoints

+func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {

+	operation := "AddRoute"

+	title := "HCSShim::PolicyList::" + operation

+	logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)

+

+	policylist := &PolicyList{}

+

+	rPolicy := &RoutePolicy{

+		DestinationPrefix: destinationPrefix,

+		NextHop:           nextHop,

+		EncapEnabled:      encapEnabled,

+	}

+	rPolicy.Type = Route

+

+	for _, endpoint := range endpoints {

+		policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)

+	}

+

+	jsonString, err := json.Marshal(rPolicy)

+	if err != nil {

+		return nil, err

+	}

+

+	policylist.Policies = append(policylist.Policies, jsonString)

+	return policylist.Create()

+}

diff --git a/vendor/github.com/Microsoft/hcsshim/importlayer.go b/vendor/github.com/Microsoft/hcsshim/importlayer.go
index 75dcd94..3aed143 100644
--- a/vendor/github.com/Microsoft/hcsshim/importlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/importlayer.go
@@ -7,7 +7,7 @@
 	"path/filepath"
 
 	"github.com/Microsoft/go-winio"
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // ImportLayer will take the contents of the folder at importFolderPath and import
diff --git a/vendor/github.com/Microsoft/hcsshim/interface.go b/vendor/github.com/Microsoft/hcsshim/interface.go
index 5238a64..e21f300 100644
--- a/vendor/github.com/Microsoft/hcsshim/interface.go
+++ b/vendor/github.com/Microsoft/hcsshim/interface.go
@@ -30,18 +30,27 @@
 }
 
 type MappedDir struct {
-	HostPath         string
-	ContainerPath    string
-	ReadOnly         bool
-	BandwidthMaximum uint64
-	IOPSMaximum      uint64
+	HostPath          string
+	ContainerPath     string
+	ReadOnly          bool
+	BandwidthMaximum  uint64
+	IOPSMaximum       uint64
+	CreateInUtilityVM bool
+}
+
+type MappedPipe struct {
+	HostPath          string
+	ContainerPipeName string
 }
 
 type HvRuntime struct {
-	ImagePath       string `json:",omitempty"`
-	SkipTemplate    bool   `json:",omitempty"`
-	LinuxInitrdFile string `json:",omitempty"` // File under ImagePath on host containing an initrd image for starting a Linux utility VM
-	LinuxKernelFile string `json:",omitempty"` // File under ImagePath on host containing a kernel for starting a Linux utility VM
+	ImagePath           string `json:",omitempty"`
+	SkipTemplate        bool   `json:",omitempty"`
+	LinuxInitrdFile     string `json:",omitempty"` // File under ImagePath on host containing an initrd image for starting a Linux utility VM
+	LinuxKernelFile     string `json:",omitempty"` // File under ImagePath on host containing a kernel for starting a Linux utility VM
+	LinuxBootParameters string `json:",omitempty"` // Additional boot parameters for starting a Linux Utility VM in initrd mode
+	BootSource          string `json:",omitempty"` // "Vhd" for Linux Utility VM booting from VHD
+	WritableBootSource  bool   `json:",omitempty"` // Linux Utility VM booting from VHD
 }
 
 type MappedVirtualDisk struct {
@@ -50,6 +59,7 @@
 	CreateInUtilityVM bool   `json:",omitempty"`
 	ReadOnly          bool   `json:",omitempty"`
 	Cache             string `json:",omitempty"` // "" (Unspecified); "Disabled"; "Enabled"; "Private"; "PrivateAllowSharing"
+	AttachOnly        bool   `json:",omitempty:`
 }
 
 // ContainerConfig is used as both the input of CreateContainer
@@ -64,14 +74,15 @@
 	Layers                      []Layer             // List of storage layers. Required for Windows Server and Hyper-V Containers. Format ID=GUID;Path=%root%\windowsfilter\layerID
 	Credentials                 string              `json:",omitempty"` // Credentials information
 	ProcessorCount              uint32              `json:",omitempty"` // Number of processors to assign to the container.
-	ProcessorWeight             uint64              `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default.
-	ProcessorMaximum            int64               `json:",omitempty"` // CPU maximum usage percent 1..100
+	ProcessorWeight             uint64              `json:",omitempty"` // CPU shares (relative weight to other containers with cpu shares). Range is from 1 to 10000. A value of 0 results in default shares.
+	ProcessorMaximum            int64               `json:",omitempty"` // Specifies the portion of processor cycles that this container can use as a percentage times 100. Range is from 1 to 10000. A value of 0 results in no limit.
 	StorageIOPSMaximum          uint64              `json:",omitempty"` // Maximum Storage IOPS
 	StorageBandwidthMaximum     uint64              `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second
 	StorageSandboxSize          uint64              `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller
 	MemoryMaximumInMB           int64               `json:",omitempty"` // Maximum memory available to the container in Megabytes
 	HostName                    string              `json:",omitempty"` // Hostname
 	MappedDirectories           []MappedDir         `json:",omitempty"` // List of mapped directories (volumes/mounts)
+	MappedPipes                 []MappedPipe        `json:",omitempty"` // List of mapped Windows named pipes
 	HvPartition                 bool                // True if it a Hyper-V Container
 	NetworkSharedContainerName  string              `json:",omitempty"` // Name (ID) of the container that we will share the network stack with.
 	EndpointList                []string            `json:",omitempty"` // List of networking endpoints to be attached to container
@@ -124,6 +135,9 @@
 	// ProcessList returns details for the processes in a container.
 	ProcessList() ([]ProcessListItem, error)
 
+	// MappedVirtualDisks returns virtual disks mapped to a utility VM, indexed by controller
+	MappedVirtualDisks() (map[int]MappedVirtualDiskController, error)
+
 	// CreateProcess launches a new process within the container.
 	CreateProcess(c *ProcessConfig) (Process, error)
 
diff --git a/vendor/github.com/Microsoft/hcsshim/layerexists.go b/vendor/github.com/Microsoft/hcsshim/layerexists.go
index 522d95c..fe46f40 100644
--- a/vendor/github.com/Microsoft/hcsshim/layerexists.go
+++ b/vendor/github.com/Microsoft/hcsshim/layerexists.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // LayerExists will return true if a layer with the given id exists and is known
 // to the system.
diff --git a/vendor/github.com/Microsoft/hcsshim/layerutils.go b/vendor/github.com/Microsoft/hcsshim/layerutils.go
index 47229d2..c0e5503 100644
--- a/vendor/github.com/Microsoft/hcsshim/layerutils.go
+++ b/vendor/github.com/Microsoft/hcsshim/layerutils.go
@@ -7,7 +7,7 @@
 	"path/filepath"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 /* To pass into syscall, we need a struct matching the following:
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy.go b/vendor/github.com/Microsoft/hcsshim/legacy.go
index 8576157..c7f6073 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy.go
@@ -307,6 +307,16 @@
 	return r.backupReader.Read(b)
 }
 
+func (r *legacyLayerReader) Seek(offset int64, whence int) (int64, error) {
+	if r.backupReader == nil {
+		if r.currentFile == nil {
+			return 0, errors.New("no current file")
+		}
+		return r.currentFile.Seek(offset, whence)
+	}
+	return 0, errors.New("seek not supported on this stream")
+}
+
 func (r *legacyLayerReader) Close() error {
 	r.proceed <- false
 	<-r.result
diff --git a/vendor/github.com/Microsoft/hcsshim/nametoguid.go b/vendor/github.com/Microsoft/hcsshim/nametoguid.go
index 1a522f9..b7c6d02 100644
--- a/vendor/github.com/Microsoft/hcsshim/nametoguid.go
+++ b/vendor/github.com/Microsoft/hcsshim/nametoguid.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // NameToGuid converts the given string into a GUID using the algorithm in the
 // Host Compute Service, ensuring GUIDs generated with the same string are common
diff --git a/vendor/github.com/Microsoft/hcsshim/preparelayer.go b/vendor/github.com/Microsoft/hcsshim/preparelayer.go
index 2791683..5c5b618 100644
--- a/vendor/github.com/Microsoft/hcsshim/preparelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/preparelayer.go
@@ -3,7 +3,7 @@
 import (
 	"sync"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var prepareLayerLock sync.Mutex
diff --git a/vendor/github.com/Microsoft/hcsshim/process.go b/vendor/github.com/Microsoft/hcsshim/process.go
index 4ef0ed3..faee2cf 100644
--- a/vendor/github.com/Microsoft/hcsshim/process.go
+++ b/vendor/github.com/Microsoft/hcsshim/process.go
@@ -7,7 +7,7 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // ContainerError is an error encountered in HCS
diff --git a/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go b/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
index d0ead0b..e8a3b50 100644
--- a/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/unpreparelayer.go
@@ -1,6 +1,6 @@
 package hcsshim
 
-import "github.com/Sirupsen/logrus"
+import "github.com/sirupsen/logrus"
 
 // UnprepareLayer disables the filesystem filter for the read-write layer with
 // the given id.
diff --git a/vendor/github.com/Microsoft/hcsshim/waithelper.go b/vendor/github.com/Microsoft/hcsshim/waithelper.go
index 828d148..b7be20e 100644
--- a/vendor/github.com/Microsoft/hcsshim/waithelper.go
+++ b/vendor/github.com/Microsoft/hcsshim/waithelper.go
@@ -3,7 +3,7 @@
 import (
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
diff --git a/vendor/github.com/Microsoft/opengcs/LICENSE b/vendor/github.com/Microsoft/opengcs/LICENSE
new file mode 100644
index 0000000..4b1ad51
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/LICENSE
@@ -0,0 +1,21 @@
+    MIT License

+

+    Copyright (c) Microsoft Corporation. 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/Microsoft/opengcs/README.md b/vendor/github.com/Microsoft/opengcs/README.md
new file mode 100644
index 0000000..e931fde
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/README.md
@@ -0,0 +1,14 @@
+

+# Open Guest Compute Service (opengcs) [![Build Status](https://travis-ci.org/Microsoft/opengcs.svg?branch=master)](https://travis-ci.org/Microsoft/opengcs)

+

+Open Guest Compute Service is a Linux open source project to further the development of a production quality implementation of Linux Hyper-V container on Windows (LCOW).  It's designed to run inside a custom Linux OS for supporting Linux container payload.

+

+# Getting Started

+

+  [How to build GCS binaries](./docs/gcsbuildinstructions.md/)

+

+  [How to build custom Linux OS images](./docs/customosbuildinstructions.md/)

+

+# Contributing

+

+This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

diff --git a/vendor/github.com/Microsoft/opengcs/client/config.go b/vendor/github.com/Microsoft/opengcs/client/config.go
new file mode 100644
index 0000000..5ece88b
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/client/config.go
@@ -0,0 +1,274 @@
+// +build windows
+
+package client
+
+import (
+	"encoding/json"
+	"fmt"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+
+	"github.com/Microsoft/hcsshim"
+	"github.com/sirupsen/logrus"
+)
+
+// Mode is the operational mode, both requested, and actual after verification
+type Mode uint
+
+const (
+	// Constants for the actual mode after validation
+
+	// ModeActualError means an error has occurred during validation
+	ModeActualError = iota
+	// ModeActualVhdx means that we are going to use VHDX boot after validation
+	ModeActualVhdx
+	// ModeActualKernelInitrd means that we are going to use kernel+initrd for boot after validation
+	ModeActualKernelInitrd
+
+	// Constants for the requested mode
+
+	// ModeRequestAuto means auto-select the boot mode for a utility VM
+	ModeRequestAuto = iota // VHDX will be priority over kernel+initrd
+	// ModeRequestVhdx means request VHDX boot if possible
+	ModeRequestVhdx
+	// ModeRequestKernelInitrd means request Kernel+initrd boot if possible
+	ModeRequestKernelInitrd
+
+	// defaultUvmTimeoutSeconds is the default time to wait for utility VM operations
+	defaultUvmTimeoutSeconds = 5 * 60
+
+	// DefaultVhdxSizeGB is the size of the default sandbox & scratch in GB
+	DefaultVhdxSizeGB = 20
+
+	// defaultVhdxBlockSizeMB is the block-size for the sandbox/scratch VHDx's this package can create.
+	defaultVhdxBlockSizeMB = 1
+)
+
+// Config is the structure used to configuring a utility VM. There are two ways
+// of starting. Either supply a VHD, or a Kernel+Initrd. For the latter, both
+// must be supplied, and both must be in the same directory.
+//
+// VHD is the priority.
+type Config struct {
+	Options                                        // Configuration options
+	Name               string                      // Name of the utility VM
+	RequestedMode      Mode                        // What mode is preferred when validating
+	ActualMode         Mode                        // What mode was obtained during validation
+	UvmTimeoutSeconds  int                         // How long to wait for the utility VM to respond in seconds
+	Uvm                hcsshim.Container           // The actual container
+	MappedVirtualDisks []hcsshim.MappedVirtualDisk // Data-disks to be attached
+}
+
+// Options is the structure used by a client to define configurable options for a utility VM.
+type Options struct {
+	KirdPath       string // Path to where kernel/initrd are found (defaults to %PROGRAMFILES%\Linux Containers)
+	KernelFile     string // Kernel for Utility VM (embedded in a UEFI bootloader) - does NOT include full path, just filename
+	InitrdFile     string // Initrd image for Utility VM - does NOT include full path, just filename
+	Vhdx           string // VHD for booting the utility VM - is a full path
+	TimeoutSeconds int    // Requested time for the utility VM to respond in seconds (may be over-ridden by environment)
+	BootParameters string // Additional boot parameters for initrd booting (not VHDx)
+}
+
+// ParseOptions parses a set of K-V pairs into options used by opengcs. Note
+// for consistency with the LCOW graphdriver in docker, we keep the same
+// convention of an `lcow.` prefix.
+func ParseOptions(options []string) (Options, error) {
+	rOpts := Options{TimeoutSeconds: 0}
+	for _, v := range options {
+		opt := strings.SplitN(v, "=", 2)
+		if len(opt) == 2 {
+			switch strings.ToLower(opt[0]) {
+			case "lcow.kirdpath":
+				rOpts.KirdPath = opt[1]
+			case "lcow.kernel":
+				rOpts.KernelFile = opt[1]
+			case "lcow.initrd":
+				rOpts.InitrdFile = opt[1]
+			case "lcow.vhdx":
+				rOpts.Vhdx = opt[1]
+			case "lcow.bootparameters":
+				rOpts.BootParameters = opt[1]
+			case "lcow.timeout":
+				var err error
+				if rOpts.TimeoutSeconds, err = strconv.Atoi(opt[1]); err != nil {
+					return rOpts, fmt.Errorf("lcow.timeout option could not be interpreted as an integer")
+				}
+				if rOpts.TimeoutSeconds < 0 {
+					return rOpts, fmt.Errorf("lcow.timeout option cannot be negative")
+				}
+			}
+		}
+	}
+
+	// Set default values if not supplied
+	if rOpts.KirdPath == "" {
+		rOpts.KirdPath = filepath.Join(os.Getenv("ProgramFiles"), "Linux Containers")
+	}
+	if rOpts.Vhdx == "" {
+		rOpts.Vhdx = filepath.Join(rOpts.KirdPath, `uvm.vhdx`)
+	}
+	if rOpts.KernelFile == "" {
+		rOpts.KernelFile = `bootx64.efi`
+	}
+	if rOpts.InitrdFile == "" {
+		rOpts.InitrdFile = `initrd.img`
+	}
+
+	return rOpts, nil
+}
+
+// GenerateDefault generates a default config from a set of options
+// If baseDir is not supplied, defaults to $env:ProgramFiles\Linux Containers
+func (config *Config) GenerateDefault(options []string) error {
+	// Parse the options that the user supplied.
+	var err error
+	config.Options, err = ParseOptions(options)
+	if err != nil {
+		return err
+	}
+
+	// Get the timeout from the environment
+	envTimeoutSeconds := 0
+	envTimeout := os.Getenv("OPENGCS_UVM_TIMEOUT_SECONDS")
+	if len(envTimeout) > 0 {
+		var err error
+		if envTimeoutSeconds, err = strconv.Atoi(envTimeout); err != nil {
+			return fmt.Errorf("OPENGCS_UVM_TIMEOUT_SECONDS could not be interpreted as an integer")
+		}
+		if envTimeoutSeconds < 0 {
+			return fmt.Errorf("OPENGCS_UVM_TIMEOUT_SECONDS cannot be negative")
+		}
+	}
+
+	// Priority to the requested timeout from the options.
+	if config.TimeoutSeconds != 0 {
+		config.UvmTimeoutSeconds = config.TimeoutSeconds
+		return nil
+	}
+
+	// Next priority, the environment
+	if envTimeoutSeconds != 0 {
+		config.UvmTimeoutSeconds = envTimeoutSeconds
+		return nil
+	}
+
+	// Last priority is the default timeout
+	config.UvmTimeoutSeconds = defaultUvmTimeoutSeconds
+
+	// Set the default requested mode
+	config.RequestedMode = ModeRequestAuto
+
+	return nil
+}
+
+// Validate validates a Config structure for starting a utility VM.
+func (config *Config) Validate() error {
+	config.ActualMode = ModeActualError
+
+	if config.RequestedMode == ModeRequestVhdx && config.Vhdx == "" {
+		return fmt.Errorf("VHDx mode must supply a VHDx")
+	}
+	if config.RequestedMode == ModeRequestKernelInitrd && (config.KernelFile == "" || config.InitrdFile == "") {
+		return fmt.Errorf("kernel+initrd mode must supply both kernel and initrd")
+	}
+
+	// Validate that if VHDX requested or auto, it exists.
+	if config.RequestedMode == ModeRequestAuto || config.RequestedMode == ModeRequestVhdx {
+		if _, err := os.Stat(config.Vhdx); os.IsNotExist(err) {
+			if config.RequestedMode == ModeRequestVhdx {
+				return fmt.Errorf("VHDx '%s' not found", config.Vhdx)
+			}
+		} else {
+			config.ActualMode = ModeActualVhdx
+
+			// Can't specify boot parameters with VHDx
+			if config.BootParameters != "" {
+				return fmt.Errorf("Boot parameters cannot be specified in VHDx mode")
+			}
+			return nil
+		}
+	}
+
+	// So must be kernel+initrd, or auto where we fallback as the VHDX doesn't exist
+	if config.InitrdFile == "" || config.KernelFile == "" {
+		if config.RequestedMode == ModeRequestKernelInitrd {
+			return fmt.Errorf("initrd and kernel options must be supplied")
+		}
+		return fmt.Errorf("opengcs: configuration is invalid")
+	}
+
+	if _, err := os.Stat(filepath.Join(config.KirdPath, config.KernelFile)); os.IsNotExist(err) {
+		return fmt.Errorf("kernel '%s' not found", filepath.Join(config.KirdPath, config.KernelFile))
+	}
+	if _, err := os.Stat(filepath.Join(config.KirdPath, config.InitrdFile)); os.IsNotExist(err) {
+		return fmt.Errorf("initrd '%s' not found", filepath.Join(config.KirdPath, config.InitrdFile))
+	}
+
+	config.ActualMode = ModeActualKernelInitrd
+
+	// Ensure all the MappedVirtualDisks exist on the host
+	for _, mvd := range config.MappedVirtualDisks {
+		if _, err := os.Stat(mvd.HostPath); err != nil {
+			return fmt.Errorf("mapped virtual disk '%s' not found", mvd.HostPath)
+		}
+		if mvd.ContainerPath == "" {
+			return fmt.Errorf("mapped virtual disk '%s' requested without a container path", mvd.HostPath)
+		}
+	}
+
+	return nil
+}
+
+// StartUtilityVM creates and starts a utility VM from a configuration.
+func (config *Config) StartUtilityVM() error {
+	logrus.Debugf("opengcs: StartUtilityVM: %+v", config)
+
+	if err := config.Validate(); err != nil {
+		return err
+	}
+
+	configuration := &hcsshim.ContainerConfig{
+		HvPartition:                 true,
+		Name:                        config.Name,
+		SystemType:                  "container",
+		ContainerType:               "linux",
+		TerminateOnLastHandleClosed: true,
+		MappedVirtualDisks:          config.MappedVirtualDisks,
+	}
+
+	if config.ActualMode == ModeActualVhdx {
+		configuration.HvRuntime = &hcsshim.HvRuntime{
+			ImagePath:          config.Vhdx,
+			BootSource:         "Vhd",
+			WritableBootSource: false,
+		}
+	} else {
+		configuration.HvRuntime = &hcsshim.HvRuntime{
+			ImagePath:           config.KirdPath,
+			LinuxInitrdFile:     config.InitrdFile,
+			LinuxKernelFile:     config.KernelFile,
+			LinuxBootParameters: config.BootParameters,
+		}
+	}
+
+	configurationS, _ := json.Marshal(configuration)
+	logrus.Debugf("opengcs: StartUtilityVM: calling HCS with '%s'", string(configurationS))
+	uvm, err := hcsshim.CreateContainer(config.Name, configuration)
+	if err != nil {
+		return err
+	}
+	logrus.Debugf("opengcs: StartUtilityVM: uvm created, starting...")
+	err = uvm.Start()
+	if err != nil {
+		logrus.Debugf("opengcs: StartUtilityVM: uvm failed to start: %s", err)
+		// Make sure we don't leave it laying around as it's been created in HCS
+		uvm.Terminate()
+		return err
+	}
+
+	config.Uvm = uvm
+	logrus.Debugf("opengcs StartUtilityVM: uvm %s is running", config.Name)
+	return nil
+}
diff --git a/vendor/github.com/Microsoft/opengcs/client/createext4vhdx.go b/vendor/github.com/Microsoft/opengcs/client/createext4vhdx.go
new file mode 100644
index 0000000..48daaeb
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/client/createext4vhdx.go
@@ -0,0 +1,167 @@
+// +build windows
+
+package client
+
+import (
+	"bytes"
+	"fmt"
+	"os"
+	"strings"
+	"time"
+
+	winio "github.com/Microsoft/go-winio/vhd"
+	//	"github.com/Microsoft/hcsshim"
+	"github.com/sirupsen/logrus"
+)
+
+// dismount is a simple utility function wrapping a conditional HotRemove. It would
+// have been easier if you could cancel a deferred function, but this works just
+// as well.
+func (config *Config) dismount(file string) error {
+	logrus.Debugf("opengcs: CreateExt4Vhdx: hot-remove of %s", file)
+	err := config.HotRemoveVhd(file)
+	if err != nil {
+		logrus.Warnf("failed to hot-remove: %s", err)
+	}
+	return err
+}
+
+// CreateExt4Vhdx does what it says on the tin. It is the responsibility of the caller to synchronise
+// simultaneous attempts to create the cache file.
+func (config *Config) CreateExt4Vhdx(destFile string, sizeGB uint32, cacheFile string) error {
+	// Smallest we can accept is the default sandbox size as we can't size down, only expand.
+	if sizeGB < DefaultVhdxSizeGB {
+		sizeGB = DefaultVhdxSizeGB
+	}
+
+	logrus.Debugf("opengcs: CreateExt4Vhdx: %s size:%dGB cache:%s", destFile, sizeGB, cacheFile)
+
+	// Retrieve from cache if the default size and already on disk
+	if cacheFile != "" && sizeGB == DefaultVhdxSizeGB {
+		if _, err := os.Stat(cacheFile); err == nil {
+			if err := CopyFile(cacheFile, destFile, false); err != nil {
+				return fmt.Errorf("failed to copy cached file '%s' to '%s': %s", cacheFile, destFile, err)
+			}
+			logrus.Debugf("opengcs: CreateExt4Vhdx: %s fulfilled from cache", destFile)
+			return nil
+		}
+	}
+
+	// Must have a utility VM to operate on
+	if config.Uvm == nil {
+		return fmt.Errorf("no utility VM")
+	}
+
+	// Create the VHDX
+	if err := winio.CreateVhdx(destFile, sizeGB, defaultVhdxBlockSizeMB); err != nil {
+		return fmt.Errorf("failed to create VHDx %s: %s", destFile, err)
+	}
+
+	defer config.DebugGCS()
+
+	// Attach it to the utility VM, but don't mount it (as there's no filesystem on it)
+	if err := config.HotAddVhd(destFile, "", false, false); err != nil {
+		return fmt.Errorf("opengcs: CreateExt4Vhdx: failed to hot-add %s to utility VM: %s", cacheFile, err)
+	}
+
+	// Get the list of mapped virtual disks to find the controller and LUN IDs
+	logrus.Debugf("opengcs: CreateExt4Vhdx: %s querying mapped virtual disks", destFile)
+	mvdControllers, err := config.Uvm.MappedVirtualDisks()
+	if err != nil {
+		return fmt.Errorf("failed to get mapped virtual disks: %s", err)
+	}
+
+	// Find our mapped disk from the list of all currently added.
+	controller := -1
+	lun := -1
+	for controllerNumber, controllerElement := range mvdControllers {
+		for diskNumber, diskElement := range controllerElement.MappedVirtualDisks {
+			if diskElement.HostPath == destFile {
+				controller = controllerNumber
+				lun = diskNumber
+				break
+			}
+		}
+	}
+	if controller == -1 || lun == -1 {
+		config.dismount(destFile)
+		return fmt.Errorf("failed to find %s in mapped virtual disks after hot-adding", destFile)
+	}
+	logrus.Debugf("opengcs: CreateExt4Vhdx: %s at C=%d L=%d", destFile, controller, lun)
+
+	// Validate /sys/bus/scsi/devices/C:0:0:L exists as a directory
+	testdCommand := fmt.Sprintf(`test -d /sys/bus/scsi/devices/%d:0:0:%d`, controller, lun)
+	testdProc, err := config.RunProcess(testdCommand, nil, nil, nil)
+	if err != nil {
+		config.dismount(destFile)
+		return fmt.Errorf("failed to `%s` following hot-add %s to utility VM: %s", testdCommand, destFile, err)
+	}
+	defer testdProc.Close()
+	testdProc.WaitTimeout(time.Duration(int(time.Second) * config.UvmTimeoutSeconds))
+	testdExitCode, err := testdProc.ExitCode()
+	if err != nil {
+		config.dismount(destFile)
+		return fmt.Errorf("failed to get exit code from `%s` following hot-add %s to utility VM: %s", testdCommand, destFile, err)
+	}
+	if testdExitCode != 0 {
+		config.dismount(destFile)
+		return fmt.Errorf("`%s` return non-zero exit code (%d) following hot-add %s to utility VM", testdCommand, testdExitCode, destFile)
+	}
+
+	// Get the device from under the block subdirectory by doing a simple ls. This will come back as (eg) `sda`
+	lsCommand := fmt.Sprintf(`ls /sys/bus/scsi/devices/%d:0:0:%d/block`, controller, lun)
+	var lsOutput bytes.Buffer
+	lsProc, err := config.RunProcess(lsCommand, nil, &lsOutput, nil)
+	if err != nil {
+		config.dismount(destFile)
+		return fmt.Errorf("failed to `%s` following hot-add %s to utility VM: %s", lsCommand, destFile, err)
+	}
+	defer lsProc.Close()
+	lsProc.WaitTimeout(time.Duration(int(time.Second) * config.UvmTimeoutSeconds))
+	lsExitCode, err := lsProc.ExitCode()
+	if err != nil {
+		config.dismount(destFile)
+		return fmt.Errorf("failed to get exit code from `%s` following hot-add %s to utility VM: %s", lsCommand, destFile, err)
+	}
+	if lsExitCode != 0 {
+		config.dismount(destFile)
+		return fmt.Errorf("`%s` return non-zero exit code (%d) following hot-add %s to utility VM", lsCommand, lsExitCode, destFile)
+	}
+	device := fmt.Sprintf(`/dev/%s`, strings.TrimSpace(lsOutput.String()))
+	logrus.Debugf("opengcs: CreateExt4Vhdx: %s: device at %s", destFile, device)
+
+	// Format it ext4
+	mkfsCommand := fmt.Sprintf(`mkfs.ext4 -q -E lazy_itable_init=1 -O ^has_journal,sparse_super2,uninit_bg,^resize_inode %s`, device)
+	var mkfsStderr bytes.Buffer
+	mkfsProc, err := config.RunProcess(mkfsCommand, nil, nil, &mkfsStderr)
+	if err != nil {
+		config.dismount(destFile)
+		return fmt.Errorf("failed to RunProcess %q following hot-add %s to utility VM: %s", destFile, mkfsCommand, err)
+	}
+	defer mkfsProc.Close()
+	mkfsProc.WaitTimeout(time.Duration(int(time.Second) * config.UvmTimeoutSeconds))
+	mkfsExitCode, err := mkfsProc.ExitCode()
+	if err != nil {
+		config.dismount(destFile)
+		return fmt.Errorf("failed to get exit code from `%s` following hot-add %s to utility VM: %s", mkfsCommand, destFile, err)
+	}
+	if mkfsExitCode != 0 {
+		config.dismount(destFile)
+		return fmt.Errorf("`%s` return non-zero exit code (%d) following hot-add %s to utility VM: %s", mkfsCommand, mkfsExitCode, destFile, strings.TrimSpace(mkfsStderr.String()))
+	}
+
+	// Dismount before we copy it
+	if err := config.dismount(destFile); err != nil {
+		return fmt.Errorf("failed to hot-remove: %s", err)
+	}
+
+	// Populate the cache.
+	if cacheFile != "" && (sizeGB == DefaultVhdxSizeGB) {
+		if err := CopyFile(destFile, cacheFile, true); err != nil {
+			return fmt.Errorf("failed to seed cache '%s' from '%s': %s", destFile, cacheFile, err)
+		}
+	}
+
+	logrus.Debugf("opengcs: CreateExt4Vhdx: %s created (non-cache)", destFile)
+	return nil
+}
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/hotaddvhd.go b/vendor/github.com/Microsoft/opengcs/client/hotaddvhd.go
similarity index 80%
rename from vendor/github.com/jhowardmsft/opengcs/gogcs/client/hotaddvhd.go
rename to vendor/github.com/Microsoft/opengcs/client/hotaddvhd.go
index c054592..ef1e51f 100644
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/hotaddvhd.go
+++ b/vendor/github.com/Microsoft/opengcs/client/hotaddvhd.go
@@ -6,33 +6,36 @@
 	"fmt"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // HotAddVhd hot-adds a VHD to a utility VM. This is used in the global one-utility-VM-
 // service-VM per host scenario. In order to do a graphdriver `Diff`, we hot-add the
 // sandbox to /mnt/<id> so that we can run `exportSandbox` inside the utility VM to
 // get a tar-stream of the sandboxes contents back to the daemon.
-func (config *Config) HotAddVhd(hostPath string, containerPath string) error {
+func (config *Config) HotAddVhd(hostPath string, containerPath string, readOnly bool, mount bool) error {
 	logrus.Debugf("opengcs: HotAddVhd: %s: %s", hostPath, containerPath)
 
 	if config.Uvm == nil {
 		return fmt.Errorf("cannot hot-add VHD as no utility VM is in configuration")
 	}
 
+	defer config.DebugGCS()
+
 	modification := &hcsshim.ResourceModificationRequestResponse{
 		Resource: "MappedVirtualDisk",
 		Data: hcsshim.MappedVirtualDisk{
 			HostPath:          hostPath,
 			ContainerPath:     containerPath,
 			CreateInUtilityVM: true,
-			//ReadOnly:          true,
+			ReadOnly:          readOnly,
+			AttachOnly:        !mount,
 		},
 		Request: "Add",
 	}
-	logrus.Debugf("opengcs: HotAddVhd: %s to %s", hostPath, containerPath)
+
 	if err := config.Uvm.Modify(modification); err != nil {
-		return fmt.Errorf("opengcs: HotAddVhd: failed: %s", err)
+		return fmt.Errorf("failed to modify utility VM configuration for hot-add: %s", err)
 	}
 	logrus.Debugf("opengcs: HotAddVhd: %s added successfully", hostPath)
 	return nil
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/hotremovevhd.go b/vendor/github.com/Microsoft/opengcs/client/hotremovevhd.go
similarity index 84%
rename from vendor/github.com/jhowardmsft/opengcs/gogcs/client/hotremovevhd.go
rename to vendor/github.com/Microsoft/opengcs/client/hotremovevhd.go
index 1f3d21a..be63189 100644
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/hotremovevhd.go
+++ b/vendor/github.com/Microsoft/opengcs/client/hotremovevhd.go
@@ -6,7 +6,7 @@
 	"fmt"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // HotRemoveVhd hot-removes a VHD from a utility VM. This is used in the global one-utility-VM-
@@ -18,6 +18,8 @@
 		return fmt.Errorf("cannot hot-add VHD as no utility VM is in configuration")
 	}
 
+	defer config.DebugGCS()
+
 	modification := &hcsshim.ResourceModificationRequestResponse{
 		Resource: "MappedVirtualDisk",
 		Data: hcsshim.MappedVirtualDisk{
@@ -27,7 +29,7 @@
 		Request: "Remove",
 	}
 	if err := config.Uvm.Modify(modification); err != nil {
-		return fmt.Errorf("opengcs: HotRemoveVhd: %s failed: %s", hostPath, err)
+		return fmt.Errorf("failed modifying utility VM for hot-remove %s: %s", hostPath, err)
 	}
 	logrus.Debugf("opengcs: HotRemoveVhd: %s removed successfully", hostPath)
 	return nil
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/layervhddetails.go b/vendor/github.com/Microsoft/opengcs/client/layervhddetails.go
similarity index 100%
rename from vendor/github.com/jhowardmsft/opengcs/gogcs/client/layervhddetails.go
rename to vendor/github.com/Microsoft/opengcs/client/layervhddetails.go
diff --git a/vendor/github.com/Microsoft/opengcs/client/process.go b/vendor/github.com/Microsoft/opengcs/client/process.go
new file mode 100644
index 0000000..958fdb5
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/client/process.go
@@ -0,0 +1,157 @@
+// +build windows
+
+package client
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"strings"
+	"time"
+
+	"github.com/Microsoft/hcsshim"
+	"github.com/sirupsen/logrus"
+)
+
+// Process is the structure pertaining to a process running in a utility VM.
+type process struct {
+	Process hcsshim.Process
+	Stdin   io.WriteCloser
+	Stdout  io.ReadCloser
+	Stderr  io.ReadCloser
+}
+
+// createUtilsProcess is a convenient wrapper for hcsshim.createUtilsProcess to use when
+// communicating with a utility VM.
+func (config *Config) createUtilsProcess(commandLine string) (process, error) {
+	logrus.Debugf("opengcs: createUtilsProcess")
+
+	if config.Uvm == nil {
+		return process{}, fmt.Errorf("cannot create utils process as no utility VM is in configuration")
+	}
+
+	var (
+		err  error
+		proc process
+	)
+
+	env := make(map[string]string)
+	env["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:"
+	processConfig := &hcsshim.ProcessConfig{
+		EmulateConsole:    false,
+		CreateStdInPipe:   true,
+		CreateStdOutPipe:  true,
+		CreateStdErrPipe:  true,
+		CreateInUtilityVm: true,
+		WorkingDirectory:  "/bin",
+		Environment:       env,
+		CommandLine:       commandLine,
+	}
+	proc.Process, err = config.Uvm.CreateProcess(processConfig)
+	if err != nil {
+		return process{}, fmt.Errorf("failed to create process (%+v) in utility VM: %s", config, err)
+	}
+
+	if proc.Stdin, proc.Stdout, proc.Stderr, err = proc.Process.Stdio(); err != nil {
+		proc.Process.Kill() // Should this have a timeout?
+		proc.Process.Close()
+		return process{}, fmt.Errorf("failed to get stdio pipes for process %+v: %s", config, err)
+	}
+
+	logrus.Debugf("opengcs: createUtilsProcess success: pid %d", proc.Process.Pid())
+	return proc, nil
+}
+
+// RunProcess runs the given command line program in the utilityVM. It takes in
+// an input to the reader to feed into stdin and returns stdout to output.
+// IMPORTANT: It is the responsibility of the caller to call Close() on the returned process.
+func (config *Config) RunProcess(commandLine string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (hcsshim.Process, error) {
+	logrus.Debugf("opengcs: RunProcess: %s", commandLine)
+	process, err := config.createUtilsProcess(commandLine)
+	if err != nil {
+		return nil, err
+	}
+
+	// Send the data into the process's stdin
+	if stdin != nil {
+		if _, err = copyWithTimeout(process.Stdin,
+			stdin,
+			0,
+			config.UvmTimeoutSeconds,
+			fmt.Sprintf("send to stdin of %s", commandLine)); err != nil {
+			return nil, err
+		}
+
+		// Don't need stdin now we've sent everything. This signals GCS that we are finished sending data.
+		if err := process.Process.CloseStdin(); err != nil {
+			return nil, err
+		}
+	}
+
+	if stdout != nil {
+		// Copy the data over to the writer.
+		if _, err := copyWithTimeout(stdout,
+			process.Stdout,
+			0,
+			config.UvmTimeoutSeconds,
+			fmt.Sprintf("RunProcess: copy back from %s", commandLine)); err != nil {
+			return nil, err
+		}
+	}
+
+	if stderr != nil {
+		// Copy the data over to the writer.
+		if _, err := copyWithTimeout(stderr,
+			process.Stderr,
+			0,
+			config.UvmTimeoutSeconds,
+			fmt.Sprintf("RunProcess: copy back from %s", commandLine)); err != nil {
+			return nil, err
+		}
+	}
+
+	logrus.Debugf("opengcs: runProcess success: %s", commandLine)
+	return process.Process, nil
+}
+
+func debugCommand(s string) string {
+	return fmt.Sprintf(`echo -e 'DEBUG COMMAND: %s\\n--------------\\n';%s;echo -e '\\n\\n';`, s, s)
+}
+
+// DebugGCS extracts logs from the GCS. It's a useful hack for debugging,
+// but not necessarily optimal, but all that is available to us in RS3.
+func (config *Config) DebugGCS() {
+	if logrus.GetLevel() < logrus.DebugLevel || len(os.Getenv("OPENGCS_DEBUG_ENABLE")) == 0 {
+		return
+	}
+
+	var out bytes.Buffer
+	cmd := os.Getenv("OPENGCS_DEBUG_COMMAND")
+	if cmd == "" {
+		cmd = `sh -c "`
+		cmd += debugCommand("ls -l /tmp")
+		cmd += debugCommand("cat /tmp/gcs.log")
+		cmd += debugCommand("ls -l /tmp/gcs")
+		cmd += debugCommand("ls -l /tmp/gcs/*")
+		cmd += debugCommand("cat /tmp/gcs/*/config.json")
+		cmd += debugCommand("ls -lR /var/run/gcsrunc")
+		cmd += debugCommand("cat /var/run/gcsrunc/log.log")
+		cmd += debugCommand("ps -ef")
+		cmd += `"`
+	}
+	proc, err := config.RunProcess(cmd, nil, &out, nil)
+	defer func() {
+		if proc != nil {
+			proc.Kill()
+			proc.Close()
+		}
+	}()
+	if err != nil {
+		logrus.Debugln("benign failure getting gcs logs: ", err)
+	}
+	if proc != nil {
+		proc.WaitTimeout(time.Duration(int(time.Second) * 30))
+	}
+	logrus.Debugf("GCS Debugging:\n%s\n\nEnd GCS Debugging\n", strings.TrimSpace(out.String()))
+}
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/tartovhd.go b/vendor/github.com/Microsoft/opengcs/client/tartovhd.go
similarity index 72%
rename from vendor/github.com/jhowardmsft/opengcs/gogcs/client/tartovhd.go
rename to vendor/github.com/Microsoft/opengcs/client/tartovhd.go
index 3560245..29ee489 100644
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/tartovhd.go
+++ b/vendor/github.com/Microsoft/opengcs/client/tartovhd.go
@@ -6,7 +6,7 @@
 	"fmt"
 	"io"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // TarToVhd streams a tarstream contained in an io.Reader to a fixed vhd file
@@ -17,26 +17,28 @@
 		return 0, fmt.Errorf("cannot Tar2Vhd as no utility VM is in configuration")
 	}
 
+	defer config.DebugGCS()
+
 	process, err := config.createUtilsProcess("tar2vhd")
 	if err != nil {
-		return 0, fmt.Errorf("opengcs: TarToVhd: %s: failed to create utils process tar2vhd: %s", targetVHDFile, err)
+		return 0, fmt.Errorf("failed to start tar2vhd for %s: %s", targetVHDFile, err)
 	}
 	defer process.Process.Close()
 
 	// Send the tarstream into the `tar2vhd`s stdin
 	if _, err = copyWithTimeout(process.Stdin, reader, 0, config.UvmTimeoutSeconds, fmt.Sprintf("stdin of tar2vhd for generating %s", targetVHDFile)); err != nil {
-		return 0, fmt.Errorf("opengcs: TarToVhd: %s: failed to send to tar2vhd in uvm: %s", targetVHDFile, err)
+		return 0, fmt.Errorf("failed sending to tar2vhd for %s: %s", targetVHDFile, err)
 	}
 
 	// Don't need stdin now we've sent everything. This signals GCS that we are finished sending data.
 	if err := process.Process.CloseStdin(); err != nil {
-		return 0, fmt.Errorf("opengcs: TarToVhd: %s: failed closing stdin handle: %s", targetVHDFile, err)
+		return 0, fmt.Errorf("failed closing stdin handle for %s: %s", targetVHDFile, err)
 	}
 
 	// Write stdout contents of `tar2vhd` to the VHD file
 	payloadSize, err := writeFileFromReader(targetVHDFile, process.Stdout, config.UvmTimeoutSeconds, fmt.Sprintf("stdout of tar2vhd to %s", targetVHDFile))
 	if err != nil {
-		return 0, fmt.Errorf("opengcs: TarToVhd: %s: failed writing VHD file: %s", targetVHDFile, err)
+		return 0, fmt.Errorf("failed to write %s during tar2vhd: %s", targetVHDFile, err)
 	}
 
 	logrus.Debugf("opengcs: TarToVhd: %s created, %d bytes", targetVHDFile, payloadSize)
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/unsupported.go b/vendor/github.com/Microsoft/opengcs/client/unsupported.go
similarity index 100%
rename from vendor/github.com/jhowardmsft/opengcs/gogcs/client/unsupported.go
rename to vendor/github.com/Microsoft/opengcs/client/unsupported.go
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/utilities.go b/vendor/github.com/Microsoft/opengcs/client/utilities.go
similarity index 98%
rename from vendor/github.com/jhowardmsft/opengcs/gogcs/client/utilities.go
rename to vendor/github.com/Microsoft/opengcs/client/utilities.go
index 8976dc0..cd779f1 100644
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/utilities.go
+++ b/vendor/github.com/Microsoft/opengcs/client/utilities.go
@@ -10,7 +10,7 @@
 	"time"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/vhdtotar.go b/vendor/github.com/Microsoft/opengcs/client/vhdtotar.go
similarity index 97%
rename from vendor/github.com/jhowardmsft/opengcs/gogcs/client/vhdtotar.go
rename to vendor/github.com/Microsoft/opengcs/client/vhdtotar.go
index bdbd381..72e9a24 100644
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/vhdtotar.go
+++ b/vendor/github.com/Microsoft/opengcs/client/vhdtotar.go
@@ -7,7 +7,7 @@
 	"io"
 	"os"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // VhdToTar does what is says - it exports a VHD in a specified
@@ -20,6 +20,8 @@
 		return nil, fmt.Errorf("cannot VhdToTar as no utility VM is in configuration")
 	}
 
+	defer config.DebugGCS()
+
 	vhdHandle, err := os.Open(vhdFile)
 	if err != nil {
 		return nil, fmt.Errorf("opengcs: VhdToTar: failed to open %s: %s", vhdFile, err)
diff --git a/vendor/github.com/Microsoft/opengcs/service/gcsutils/README b/vendor/github.com/Microsoft/opengcs/service/gcsutils/README
new file mode 100644
index 0000000..85e5442
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/service/gcsutils/README
@@ -0,0 +1,4 @@
+1. This program only runs in Linux. So you just first copy the files over to a Linux machine. 
+2. Get Go and and then run make get-deps && make. This is set the $GOPATH for you and build the binaries.
+3. vhd_to_tar and tar_to_vhd are the standalone executables that read/write to stdin/out and do the tar <-> vhd conversion.
+   tar2vhd_server is the service VM server that takes client requests over hvsock.
diff --git a/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/defs.go b/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/defs.go
new file mode 100644
index 0000000..f1f2c04
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/defs.go
@@ -0,0 +1,109 @@
+package remotefs
+
+import (
+	"errors"
+	"os"
+	"time"
+)
+
+// RemotefsCmd is the name of the remotefs meta command
+const RemotefsCmd = "remotefs"
+
+// Name of the commands when called from the cli context (remotefs <CMD> ...)
+const (
+	StatCmd           = "stat"
+	LstatCmd          = "lstat"
+	ReadlinkCmd       = "readlink"
+	MkdirCmd          = "mkdir"
+	MkdirAllCmd       = "mkdirall"
+	RemoveCmd         = "remove"
+	RemoveAllCmd      = "removeall"
+	LinkCmd           = "link"
+	SymlinkCmd        = "symlink"
+	LchmodCmd         = "lchmod"
+	LchownCmd         = "lchown"
+	MknodCmd          = "mknod"
+	MkfifoCmd         = "mkfifo"
+	OpenFileCmd       = "openfile"
+	ReadFileCmd       = "readfile"
+	WriteFileCmd      = "writefile"
+	ReadDirCmd        = "readdir"
+	ResolvePathCmd    = "resolvepath"
+	ExtractArchiveCmd = "extractarchive"
+	ArchivePathCmd    = "archivepath"
+)
+
+// ErrInvalid is returned if the parameters are invalid
+var ErrInvalid = errors.New("invalid arguments")
+
+// ErrUnknown is returned for an unknown remotefs command
+var ErrUnknown = errors.New("unkown command")
+
+// ExportedError is the serialized version of the a Go error.
+// It also provides a trivial implementation of the error interface.
+type ExportedError struct {
+	ErrString string
+	ErrNum    int `json:",omitempty"`
+}
+
+// Error returns an error string
+func (ee *ExportedError) Error() string {
+	return ee.ErrString
+}
+
+// FileInfo is the stat struct returned by the remotefs system. It
+// fulfills the os.FileInfo interface.
+type FileInfo struct {
+	NameVar    string
+	SizeVar    int64
+	ModeVar    os.FileMode
+	ModTimeVar int64 // Serialization of time.Time breaks in travis, so use an int
+	IsDirVar   bool
+}
+
+var _ os.FileInfo = &FileInfo{}
+
+// Name returns the filename from a FileInfo structure
+func (f *FileInfo) Name() string { return f.NameVar }
+
+// Size returns the size from a FileInfo structure
+func (f *FileInfo) Size() int64 { return f.SizeVar }
+
+// Mode returns the mode from a FileInfo structure
+func (f *FileInfo) Mode() os.FileMode { return f.ModeVar }
+
+// ModTime returns the modification time from a FileInfo structure
+func (f *FileInfo) ModTime() time.Time { return time.Unix(0, f.ModTimeVar) }
+
+// IsDir returns the is-directory indicator from a FileInfo structure
+func (f *FileInfo) IsDir() bool { return f.IsDirVar }
+
+// Sys provides an interface to a FileInfo structure
+func (f *FileInfo) Sys() interface{} { return nil }
+
+// FileHeader is a header for remote *os.File operations for remotefs.OpenFile
+type FileHeader struct {
+	Cmd  uint32
+	Size uint64
+}
+
+const (
+	// Read request command.
+	Read uint32 = iota
+	// Write request command.
+	Write
+	// Seek request command.
+	Seek
+	// Close request command.
+	Close
+	// CmdOK is a response meaning request succeeded.
+	CmdOK
+	// CmdFailed is a response meaning request failed.
+	CmdFailed
+)
+
+// SeekHeader is header for the Seek operation for remotefs.OpenFile
+type SeekHeader struct {
+	Offset int64
+	Whence int32
+}
diff --git a/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/remotefs.go b/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/remotefs.go
new file mode 100644
index 0000000..2d4a9f2
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/remotefs.go
@@ -0,0 +1,546 @@
+// +build !windows
+
+package remotefs
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/json"
+	"io"
+	"os"
+	"path/filepath"
+	"strconv"
+
+	"github.com/docker/docker/pkg/archive"
+	"github.com/docker/docker/pkg/symlink"
+	"golang.org/x/sys/unix"
+)
+
+// Func is the function definition for a generic remote fs function
+// The input to the function is any serialized structs / data from in and the string slice
+// from args. The output of the function will be serialized and written to out.
+type Func func(stdin io.Reader, stdout io.Writer, args []string) error
+
+// Commands provide a string -> remotefs function mapping.
+// This is useful for commandline programs that will receive a string
+// as the function to execute.
+var Commands = map[string]Func{
+	StatCmd:           Stat,
+	LstatCmd:          Lstat,
+	ReadlinkCmd:       Readlink,
+	MkdirCmd:          Mkdir,
+	MkdirAllCmd:       MkdirAll,
+	RemoveCmd:         Remove,
+	RemoveAllCmd:      RemoveAll,
+	LinkCmd:           Link,
+	SymlinkCmd:        Symlink,
+	LchmodCmd:         Lchmod,
+	LchownCmd:         Lchown,
+	MknodCmd:          Mknod,
+	MkfifoCmd:         Mkfifo,
+	OpenFileCmd:       OpenFile,
+	ReadFileCmd:       ReadFile,
+	WriteFileCmd:      WriteFile,
+	ReadDirCmd:        ReadDir,
+	ResolvePathCmd:    ResolvePath,
+	ExtractArchiveCmd: ExtractArchive,
+	ArchivePathCmd:    ArchivePath,
+}
+
+// Stat functions like os.Stat.
+// Args:
+// - args[0] is the path
+// Out:
+// - out = FileInfo object
+func Stat(in io.Reader, out io.Writer, args []string) error {
+	return stat(in, out, args, os.Stat)
+}
+
+// Lstat functions like os.Lstat.
+// Args:
+// - args[0] is the path
+// Out:
+// - out = FileInfo object
+func Lstat(in io.Reader, out io.Writer, args []string) error {
+	return stat(in, out, args, os.Lstat)
+}
+
+func stat(in io.Reader, out io.Writer, args []string, statfunc func(string) (os.FileInfo, error)) error {
+	if len(args) < 1 {
+		return ErrInvalid
+	}
+
+	fi, err := statfunc(args[0])
+	if err != nil {
+		return err
+	}
+
+	info := FileInfo{
+		NameVar:    fi.Name(),
+		SizeVar:    fi.Size(),
+		ModeVar:    fi.Mode(),
+		ModTimeVar: fi.ModTime().UnixNano(),
+		IsDirVar:   fi.IsDir(),
+	}
+
+	buf, err := json.Marshal(info)
+	if err != nil {
+		return err
+	}
+
+	if _, err := out.Write(buf); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Readlink works like os.Readlink
+// In:
+//  - args[0] is path
+// Out:
+//  - Write link result to out
+func Readlink(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 1 {
+		return ErrInvalid
+	}
+
+	l, err := os.Readlink(args[0])
+	if err != nil {
+		return err
+	}
+
+	if _, err := out.Write([]byte(l)); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Mkdir works like os.Mkdir
+// Args:
+// - args[0] is the path
+// - args[1] is the permissions in octal (like 0755)
+func Mkdir(in io.Reader, out io.Writer, args []string) error {
+	return mkdir(in, out, args, os.Mkdir)
+}
+
+// MkdirAll works like os.MkdirAll.
+// Args:
+// - args[0] is the path
+// - args[1] is the permissions in octal (like 0755)
+func MkdirAll(in io.Reader, out io.Writer, args []string) error {
+	return mkdir(in, out, args, os.MkdirAll)
+}
+
+func mkdir(in io.Reader, out io.Writer, args []string, mkdirFunc func(string, os.FileMode) error) error {
+	if len(args) < 2 {
+		return ErrInvalid
+	}
+
+	perm, err := strconv.ParseUint(args[1], 8, 32)
+	if err != nil {
+		return err
+	}
+	return mkdirFunc(args[0], os.FileMode(perm))
+}
+
+// Remove works like os.Remove
+// Args:
+//	- args[0] is the path
+func Remove(in io.Reader, out io.Writer, args []string) error {
+	return remove(in, out, args, os.Remove)
+}
+
+// RemoveAll works like os.RemoveAll
+// Args:
+//  - args[0] is the path
+func RemoveAll(in io.Reader, out io.Writer, args []string) error {
+	return remove(in, out, args, os.RemoveAll)
+}
+
+func remove(in io.Reader, out io.Writer, args []string, removefunc func(string) error) error {
+	if len(args) < 1 {
+		return ErrInvalid
+	}
+	return removefunc(args[0])
+}
+
+// Link works like os.Link
+// Args:
+//  - args[0] = old path name (link source)
+//  - args[1] = new path name (link dest)
+func Link(in io.Reader, out io.Writer, args []string) error {
+	return link(in, out, args, os.Link)
+}
+
+// Symlink works like os.Symlink
+// Args:
+//  - args[0] = old path name (link source)
+//  - args[1] = new path name (link dest)
+func Symlink(in io.Reader, out io.Writer, args []string) error {
+	return link(in, out, args, os.Symlink)
+}
+
+func link(in io.Reader, out io.Writer, args []string, linkfunc func(string, string) error) error {
+	if len(args) < 2 {
+		return ErrInvalid
+	}
+	return linkfunc(args[0], args[1])
+}
+
+// Lchmod changes permission of the given file without following symlinks
+// Args:
+//  - args[0] = path
+//  - args[1] = permission mode in octal (like 0755)
+func Lchmod(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 2 {
+		return ErrInvalid
+	}
+
+	perm, err := strconv.ParseUint(args[1], 8, 32)
+	if err != nil {
+		return err
+	}
+
+	path := args[0]
+	if !filepath.IsAbs(path) {
+		path, err = filepath.Abs(path)
+		if err != nil {
+			return err
+		}
+	}
+	return unix.Fchmodat(0, path, uint32(perm), unix.AT_SYMLINK_NOFOLLOW)
+}
+
+// Lchown works like os.Lchown
+// Args:
+//  - args[0] = path
+//  - args[1] = uid in base 10
+//  - args[2] = gid in base 10
+func Lchown(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 3 {
+		return ErrInvalid
+	}
+
+	uid, err := strconv.ParseInt(args[1], 10, 64)
+	if err != nil {
+		return err
+	}
+
+	gid, err := strconv.ParseInt(args[2], 10, 64)
+	if err != nil {
+		return err
+	}
+	return os.Lchown(args[0], int(uid), int(gid))
+}
+
+// Mknod works like syscall.Mknod
+// Args:
+//  - args[0] = path
+//  - args[1] = permission mode in octal (like 0755)
+//  - args[2] = major device number in base 10
+//  - args[3] = minor device number in base 10
+func Mknod(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 4 {
+		return ErrInvalid
+	}
+
+	perm, err := strconv.ParseUint(args[1], 8, 32)
+	if err != nil {
+		return err
+	}
+
+	major, err := strconv.ParseInt(args[2], 10, 32)
+	if err != nil {
+		return err
+	}
+
+	minor, err := strconv.ParseInt(args[3], 10, 32)
+	if err != nil {
+		return err
+	}
+
+	dev := unix.Mkdev(uint32(major), uint32(minor))
+	return unix.Mknod(args[0], uint32(perm), int(dev))
+}
+
+// Mkfifo creates a FIFO special file with the given path name and permissions
+// Args:
+// 	- args[0] = path
+//  - args[1] = permission mode in octal (like 0755)
+func Mkfifo(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 2 {
+		return ErrInvalid
+	}
+
+	perm, err := strconv.ParseUint(args[1], 8, 32)
+	if err != nil {
+		return err
+	}
+	return unix.Mkfifo(args[0], uint32(perm))
+}
+
+// OpenFile works like os.OpenFile. To manage the file pointer state,
+// this function acts as a single file "file server" with Read/Write/Close
+// being serialized control codes from in.
+// Args:
+//  - args[0] = path
+//  - args[1] = flag in base 10
+//  - args[2] = permission mode in octal (like 0755)
+func OpenFile(in io.Reader, out io.Writer, args []string) (err error) {
+	defer func() {
+		if err != nil {
+			// error code will be serialized by the caller, so don't write it here
+			WriteFileHeader(out, &FileHeader{Cmd: CmdFailed}, nil)
+		}
+	}()
+
+	if len(args) < 3 {
+		return ErrInvalid
+	}
+
+	flag, err := strconv.ParseInt(args[1], 10, 32)
+	if err != nil {
+		return err
+	}
+
+	perm, err := strconv.ParseUint(args[2], 8, 32)
+	if err != nil {
+		return err
+	}
+
+	f, err := os.OpenFile(args[0], int(flag), os.FileMode(perm))
+	if err != nil {
+		return err
+	}
+
+	// Signal the client that OpenFile succeeded
+	if err := WriteFileHeader(out, &FileHeader{Cmd: CmdOK}, nil); err != nil {
+		return err
+	}
+
+	for {
+		hdr, err := ReadFileHeader(in)
+		if err != nil {
+			return err
+		}
+
+		var buf []byte
+		switch hdr.Cmd {
+		case Read:
+			buf = make([]byte, hdr.Size, hdr.Size)
+			n, err := f.Read(buf)
+			if err != nil {
+				return err
+			}
+			buf = buf[:n]
+		case Write:
+			if _, err := io.CopyN(f, in, int64(hdr.Size)); err != nil {
+				return err
+			}
+		case Seek:
+			seekHdr := &SeekHeader{}
+			if err := binary.Read(in, binary.BigEndian, seekHdr); err != nil {
+				return err
+			}
+			res, err := f.Seek(seekHdr.Offset, int(seekHdr.Whence))
+			if err != nil {
+				return err
+			}
+			buffer := &bytes.Buffer{}
+			if err := binary.Write(buffer, binary.BigEndian, res); err != nil {
+				return err
+			}
+			buf = buffer.Bytes()
+		case Close:
+			if err := f.Close(); err != nil {
+				return err
+			}
+		default:
+			return ErrUnknown
+		}
+
+		retHdr := &FileHeader{
+			Cmd:  CmdOK,
+			Size: uint64(len(buf)),
+		}
+		if err := WriteFileHeader(out, retHdr, buf); err != nil {
+			return err
+		}
+
+		if hdr.Cmd == Close {
+			break
+		}
+	}
+	return nil
+}
+
+// ReadFile works like ioutil.ReadFile but instead writes the file to a writer
+// Args:
+//  - args[0] = path
+// Out:
+//  - Write file contents to out
+func ReadFile(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 1 {
+		return ErrInvalid
+	}
+
+	f, err := os.Open(args[0])
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	if _, err := io.Copy(out, f); err != nil {
+		return nil
+	}
+	return nil
+}
+
+// WriteFile works like ioutil.WriteFile but instead reads the file from a reader
+// Args:
+//  - args[0] = path
+//  - args[1] = permission mode in octal (like 0755)
+//  - input data stream from in
+func WriteFile(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 2 {
+		return ErrInvalid
+	}
+
+	perm, err := strconv.ParseUint(args[1], 8, 32)
+	if err != nil {
+		return err
+	}
+
+	f, err := os.OpenFile(args[0], os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(perm))
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	if _, err := io.Copy(f, in); err != nil {
+		return err
+	}
+	return nil
+}
+
+// ReadDir works like *os.File.Readdir but instead writes the result to a writer
+// Args:
+//  - args[0] = path
+//  - args[1] = number of directory entries to return. If <= 0, return all entries in directory
+func ReadDir(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 2 {
+		return ErrInvalid
+	}
+
+	n, err := strconv.ParseInt(args[1], 10, 32)
+	if err != nil {
+		return err
+	}
+
+	f, err := os.Open(args[0])
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	infos, err := f.Readdir(int(n))
+	if err != nil {
+		return err
+	}
+
+	fileInfos := make([]FileInfo, len(infos))
+	for i := range infos {
+		fileInfos[i] = FileInfo{
+			NameVar:    infos[i].Name(),
+			SizeVar:    infos[i].Size(),
+			ModeVar:    infos[i].Mode(),
+			ModTimeVar: infos[i].ModTime().UnixNano(),
+			IsDirVar:   infos[i].IsDir(),
+		}
+	}
+
+	buf, err := json.Marshal(fileInfos)
+	if err != nil {
+		return err
+	}
+
+	if _, err := out.Write(buf); err != nil {
+		return err
+	}
+	return nil
+}
+
+// ResolvePath works like docker's symlink.FollowSymlinkInScope.
+// It takens in a `path` and a `root` and evaluates symlinks in `path`
+// as if they were scoped in `root`. `path` must be a child path of `root`.
+// In other words, `path` must have `root` as a prefix.
+// Example:
+// path=/foo/bar -> /baz
+// root=/foo,
+// Expected result = /foo/baz
+//
+// Args:
+// - args[0] is `path`
+// - args[1] is `root`
+// Out:
+// - Write resolved path to stdout
+func ResolvePath(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 2 {
+		return ErrInvalid
+	}
+	res, err := symlink.FollowSymlinkInScope(args[0], args[1])
+	if err != nil {
+		return err
+	}
+	if _, err = out.Write([]byte(res)); err != nil {
+		return err
+	}
+	return nil
+}
+
+// ExtractArchive extracts the archive read from in.
+// Args:
+// - in = size of json | json of archive.TarOptions | input tar stream
+// - args[0] = extract directory name
+func ExtractArchive(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 1 {
+		return ErrInvalid
+	}
+
+	opts, err := ReadTarOptions(in)
+	if err != nil {
+		return err
+	}
+
+	if err := archive.Untar(in, args[0], opts); err != nil {
+		return err
+	}
+	return nil
+}
+
+// ArchivePath archives the given directory and writes it to out.
+// Args:
+// - in = size of json | json of archive.TarOptions
+// - args[0] = source directory name
+// Out:
+// - out = tar file of the archive
+func ArchivePath(in io.Reader, out io.Writer, args []string) error {
+	if len(args) < 1 {
+		return ErrInvalid
+	}
+
+	opts, err := ReadTarOptions(in)
+	if err != nil {
+		return err
+	}
+
+	r, err := archive.TarWithOptions(args[0], opts)
+	if err != nil {
+		return err
+	}
+
+	if _, err := io.Copy(out, r); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/utils.go b/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/utils.go
new file mode 100644
index 0000000..a12827c
--- /dev/null
+++ b/vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/utils.go
@@ -0,0 +1,168 @@
+package remotefs
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/json"
+	"io"
+	"io/ioutil"
+	"os"
+	"syscall"
+
+	"github.com/docker/docker/pkg/archive"
+)
+
+// ReadError is an utility function that reads a serialized error from the given reader
+// and deserializes it.
+func ReadError(in io.Reader) (*ExportedError, error) {
+	b, err := ioutil.ReadAll(in)
+	if err != nil {
+		return nil, err
+	}
+
+	// No error
+	if len(b) == 0 {
+		return nil, nil
+	}
+
+	var exportedErr ExportedError
+	if err := json.Unmarshal(b, &exportedErr); err != nil {
+		return nil, err
+	}
+
+	return &exportedErr, nil
+}
+
+// ExportedToError will convert a ExportedError to an error. It will try to match
+// the error to any existing known error like os.ErrNotExist. Otherwise, it will just
+// return an implementation of the error interface.
+func ExportedToError(ee *ExportedError) error {
+	if ee.Error() == os.ErrNotExist.Error() {
+		return os.ErrNotExist
+	} else if ee.Error() == os.ErrExist.Error() {
+		return os.ErrExist
+	} else if ee.Error() == os.ErrPermission.Error() {
+		return os.ErrPermission
+	}
+	return ee
+}
+
+// WriteError is an utility function that serializes the error
+// and writes it to the output writer.
+func WriteError(err error, out io.Writer) error {
+	if err == nil {
+		return nil
+	}
+	err = fixOSError(err)
+
+	var errno int
+	switch typedError := err.(type) {
+	case *os.PathError:
+		if se, ok := typedError.Err.(syscall.Errno); ok {
+			errno = int(se)
+		}
+	case *os.LinkError:
+		if se, ok := typedError.Err.(syscall.Errno); ok {
+			errno = int(se)
+		}
+	case *os.SyscallError:
+		if se, ok := typedError.Err.(syscall.Errno); ok {
+			errno = int(se)
+		}
+	}
+
+	exportedError := &ExportedError{
+		ErrString: err.Error(),
+		ErrNum:    errno,
+	}
+
+	b, err1 := json.Marshal(exportedError)
+	if err1 != nil {
+		return err1
+	}
+
+	_, err1 = out.Write(b)
+	if err1 != nil {
+		return err1
+	}
+	return nil
+}
+
+// fixOSError converts possible platform dependent error into the portable errors in the
+// Go os package if possible.
+func fixOSError(err error) error {
+	// The os.IsExist, os.IsNotExist, and os.IsPermissions functions are platform
+	// dependent, so sending the raw error might break those functions on a different OS.
+	// Go defines portable errors for these.
+	if os.IsExist(err) {
+		return os.ErrExist
+	} else if os.IsNotExist(err) {
+		return os.ErrNotExist
+	} else if os.IsPermission(err) {
+		return os.ErrPermission
+	}
+	return err
+}
+
+// ReadTarOptions reads from the specified reader and deserializes an archive.TarOptions struct.
+func ReadTarOptions(r io.Reader) (*archive.TarOptions, error) {
+	var size uint64
+	if err := binary.Read(r, binary.BigEndian, &size); err != nil {
+		return nil, err
+	}
+
+	rawJSON := make([]byte, size)
+	if _, err := io.ReadFull(r, rawJSON); err != nil {
+		return nil, err
+	}
+
+	var opts archive.TarOptions
+	if err := json.Unmarshal(rawJSON, &opts); err != nil {
+		return nil, err
+	}
+	return &opts, nil
+}
+
+// WriteTarOptions serializes a archive.TarOptions struct and writes it to the writer.
+func WriteTarOptions(w io.Writer, opts *archive.TarOptions) error {
+	optsBuf, err := json.Marshal(opts)
+	if err != nil {
+		return err
+	}
+
+	optsSize := uint64(len(optsBuf))
+	optsSizeBuf := &bytes.Buffer{}
+	if err := binary.Write(optsSizeBuf, binary.BigEndian, optsSize); err != nil {
+		return err
+	}
+
+	if _, err := optsSizeBuf.WriteTo(w); err != nil {
+		return err
+	}
+
+	if _, err := w.Write(optsBuf); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// ReadFileHeader reads from r and returns a deserialized FileHeader
+func ReadFileHeader(r io.Reader) (*FileHeader, error) {
+	hdr := &FileHeader{}
+	if err := binary.Read(r, binary.BigEndian, hdr); err != nil {
+		return nil, err
+	}
+	return hdr, nil
+}
+
+// WriteFileHeader serializes a FileHeader and writes it to w, along with any extra data
+func WriteFileHeader(w io.Writer, hdr *FileHeader, extraData []byte) error {
+	if err := binary.Write(w, binary.BigEndian, hdr); err != nil {
+		return err
+	}
+	if _, err := w.Write(extraData); 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 2ad6dc5..0000000
--- a/vendor/github.com/Sirupsen/logrus/json_formatter.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package logrus
-
-import (
-	"encoding/json"
-	"fmt"
-)
-
-type JSONFormatter struct {
-	// TimestampFormat sets the format used for marshaling timestamps.
-	TimestampFormat string
-}
-
-func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
-	data := make(Fields, len(entry.Data)+3)
-	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
-		}
-	}
-	prefixFieldClashes(data)
-
-	timestampFormat := f.TimestampFormat
-	if timestampFormat == "" {
-		timestampFormat = DefaultTimestampFormat
-	}
-
-	data["time"] = entry.Time.Format(timestampFormat)
-	data["msg"] = entry.Message
-	data["level"] = entry.Level.String()
-
-	serialized, err := json.Marshal(data)
-	if err != nil {
-		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
-	}
-	return append(serialized, '\n'), nil
-}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_appengine.go b/vendor/github.com/Sirupsen/logrus/terminal_appengine.go
deleted file mode 100644
index 1960169..0000000
--- a/vendor/github.com/Sirupsen/logrus/terminal_appengine.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// +build appengine
-
-package logrus
-
-// IsTerminal returns true if stderr's file descriptor is a terminal.
-func IsTerminal() bool {
-	return true
-}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go b/vendor/github.com/Sirupsen/logrus/terminal_bsd.go
deleted file mode 100644
index 5f6be4d..0000000
--- a/vendor/github.com/Sirupsen/logrus/terminal_bsd.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// +build darwin freebsd openbsd netbsd dragonfly
-// +build !appengine
-
-package logrus
-
-import "syscall"
-
-const ioctlReadTermios = syscall.TIOCGETA
-
-type Termios syscall.Termios
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 329038f..0000000
--- a/vendor/github.com/Sirupsen/logrus/terminal_notwindows.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Based on ssh/terminal:
-// 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.
-
-// +build linux darwin freebsd openbsd netbsd dragonfly
-// +build !appengine
-
-package logrus
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-// IsTerminal returns true if stderr's file descriptor is a terminal.
-func IsTerminal() bool {
-	fd := syscall.Stderr
-	var termios Termios
-	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
-	return err == 0
-}
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go b/vendor/github.com/Sirupsen/logrus/terminal_solaris.go
deleted file mode 100644
index a3c6f6e..0000000
--- a/vendor/github.com/Sirupsen/logrus/terminal_solaris.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// +build solaris,!appengine
-
-package logrus
-
-import (
-	"os"
-
-	"golang.org/x/sys/unix"
-)
-
-// IsTerminal returns true if the given file descriptor is a terminal.
-func IsTerminal() bool {
-	_, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA)
-	return err == nil
-}
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 3727e8a..0000000
--- a/vendor/github.com/Sirupsen/logrus/terminal_windows.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Based on ssh/terminal:
-// 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.
-
-// +build windows,!appengine
-
-package logrus
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var kernel32 = syscall.NewLazyDLL("kernel32.dll")
-
-var (
-	procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
-)
-
-// IsTerminal returns true if stderr's file descriptor is a terminal.
-func IsTerminal() bool {
-	fd := syscall.Stderr
-	var st uint32
-	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
-	return r != 0 && e == 0
-}
diff --git a/vendor/github.com/Sirupsen/logrus/writer.go b/vendor/github.com/Sirupsen/logrus/writer.go
deleted file mode 100644
index f74d2aa..0000000
--- a/vendor/github.com/Sirupsen/logrus/writer.go
+++ /dev/null
@@ -1,53 +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 {
-	reader, writer := io.Pipe()
-
-	var printFunc func(args ...interface{})
-	switch level {
-	case DebugLevel:
-		printFunc = logger.Debug
-	case InfoLevel:
-		printFunc = logger.Info
-	case WarnLevel:
-		printFunc = logger.Warn
-	case ErrorLevel:
-		printFunc = logger.Error
-	case FatalLevel:
-		printFunc = logger.Fatal
-	case PanicLevel:
-		printFunc = logger.Panic
-	default:
-		printFunc = logger.Print
-	}
-
-	go logger.writerScanner(reader, printFunc)
-	runtime.SetFinalizer(writer, writerFinalizer)
-
-	return writer
-}
-
-func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
-	scanner := bufio.NewScanner(reader)
-	for scanner.Scan() {
-		printFunc(scanner.Text())
-	}
-	if err := scanner.Err(); err != nil {
-		logger.Errorf("Error while reading from Writer: %s", err)
-	}
-	reader.Close()
-}
-
-func writerFinalizer(writer *io.PipeWriter) {
-	writer.Close()
-}
diff --git a/vendor/github.com/containerd/containerd/api/grpc/types/api.pb.go b/vendor/github.com/containerd/containerd/api/grpc/types/api.pb.go
index e6ef556..8f14a18 100644
--- a/vendor/github.com/containerd/containerd/api/grpc/types/api.pb.go
+++ b/vendor/github.com/containerd/containerd/api/grpc/types/api.pb.go
@@ -1,6 +1,5 @@
-// Code generated by protoc-gen-go.
+// Code generated by protoc-gen-go. DO NOT EDIT.
 // source: api.proto
-// DO NOT EDIT!
 
 /*
 Package types is a generated protocol buffer package.
@@ -1052,6 +1051,8 @@
 	BlkioThrottleReadIopsDevice  []*ThrottleDevice `protobuf:"bytes,16,rep,name=blkioThrottleReadIopsDevice" json:"blkioThrottleReadIopsDevice,omitempty"`
 	BlkioThrottleWriteIopsDevice []*ThrottleDevice `protobuf:"bytes,17,rep,name=blkioThrottleWriteIopsDevice" json:"blkioThrottleWriteIopsDevice,omitempty"`
 	PidsLimit                    uint64            `protobuf:"varint,18,opt,name=pidsLimit" json:"pidsLimit,omitempty"`
+	CpuRealtimePeriod            uint64            `protobuf:"varint,19,opt,name=cpuRealtimePeriod" json:"cpuRealtimePeriod,omitempty"`
+	CpuRealtimeRuntime           int64             `protobuf:"varint,20,opt,name=cpuRealtimeRuntime" json:"cpuRealtimeRuntime,omitempty"`
 }
 
 func (m *UpdateResource) Reset()                    { *m = UpdateResource{} }
@@ -1185,6 +1186,20 @@
 	return 0
 }
 
+func (m *UpdateResource) GetCpuRealtimePeriod() uint64 {
+	if m != nil {
+		return m.CpuRealtimePeriod
+	}
+	return 0
+}
+
+func (m *UpdateResource) GetCpuRealtimeRuntime() int64 {
+	if m != nil {
+		return m.CpuRealtimeRuntime
+	}
+	return 0
+}
+
 type BlockIODevice struct {
 	Major int64 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"`
 	Minor int64 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"`
@@ -2415,170 +2430,172 @@
 func init() { proto.RegisterFile("api.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 2632 bytes of a gzipped FileDescriptorProto
+	// 2666 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x19, 0x4d, 0x6f, 0x24, 0x47,
 	0x75, 0x67, 0xa6, 0xed, 0xf1, 0xbc, 0xf9, 0xb0, 0xa7, 0xd6, 0xeb, 0xed, 0x9d, 0x24, 0xbb, 0x4e,
 	0x2b, 0x10, 0x03, 0x91, 0xb3, 0x78, 0x13, 0x58, 0x11, 0x09, 0x69, 0xd7, 0x1b, 0x82, 0xc9, 0x3a,
-	0x99, 0xb4, 0x6d, 0x56, 0x48, 0x48, 0xa3, 0x76, 0x77, 0xed, 0x4c, 0xe1, 0x9e, 0xae, 0x4e, 0x75,
-	0xb5, 0x3d, 0xbe, 0xe4, 0xc0, 0x01, 0x0e, 0x48, 0x70, 0x45, 0xe2, 0xc8, 0x8d, 0x3b, 0x07, 0xf8,
-	0x03, 0x48, 0xfc, 0x10, 0x6e, 0xdc, 0x39, 0xa2, 0xfa, 0xe8, 0xea, 0xea, 0xf9, 0xf0, 0x6e, 0x90,
-	0x10, 0x17, 0x2e, 0xad, 0x7a, 0xaf, 0xde, 0x57, 0xbd, 0x7a, 0xef, 0xd5, 0xab, 0x6a, 0x68, 0x05,
-	0x29, 0xd9, 0x4f, 0x19, 0xe5, 0x14, 0xad, 0xf1, 0xeb, 0x14, 0x67, 0x83, 0x07, 0x63, 0x4a, 0xc7,
-	0x31, 0x7e, 0x5f, 0x22, 0xcf, 0xf3, 0x97, 0xef, 0x73, 0x32, 0xc5, 0x19, 0x0f, 0xa6, 0xa9, 0xa2,
-	0xf3, 0xee, 0xc1, 0xdd, 0x4f, 0x30, 0x3f, 0xc1, 0xec, 0x12, 0xb3, 0x9f, 0x62, 0x96, 0x11, 0x9a,
-	0xf8, 0xf8, 0xcb, 0x1c, 0x67, 0xdc, 0x9b, 0x81, 0xbb, 0x38, 0x95, 0xa5, 0x34, 0xc9, 0x30, 0xda,
-	0x86, 0xb5, 0x69, 0xf0, 0x0b, 0xca, 0xdc, 0xda, 0x6e, 0x6d, 0xaf, 0xeb, 0x2b, 0x40, 0x62, 0x49,
-	0x42, 0x99, 0x5b, 0xd7, 0x58, 0x01, 0x08, 0x6c, 0x1a, 0xf0, 0x70, 0xe2, 0x36, 0x14, 0x56, 0x02,
-	0x68, 0x00, 0x1b, 0x0c, 0x5f, 0x12, 0x21, 0xd5, 0x75, 0x76, 0x6b, 0x7b, 0x2d, 0xdf, 0xc0, 0xde,
-	0xaf, 0x6a, 0xb0, 0x7d, 0x96, 0x46, 0x01, 0xc7, 0x43, 0x46, 0x43, 0x9c, 0x65, 0xda, 0x24, 0xd4,
-	0x83, 0x3a, 0x89, 0xa4, 0xce, 0x96, 0x5f, 0x27, 0x11, 0xda, 0x82, 0x46, 0x4a, 0x22, 0xa9, 0xae,
-	0xe5, 0x8b, 0x21, 0xba, 0x0f, 0x10, 0xc6, 0x34, 0xc3, 0x27, 0x3c, 0x22, 0x89, 0xd4, 0xb8, 0xe1,
-	0x5b, 0x18, 0x61, 0xcc, 0x15, 0x89, 0xf8, 0x44, 0xea, 0xec, 0xfa, 0x0a, 0x40, 0x3b, 0xb0, 0x3e,
-	0xc1, 0x64, 0x3c, 0xe1, 0xee, 0x9a, 0x44, 0x6b, 0xc8, 0xbb, 0x0b, 0x77, 0xe6, 0xec, 0x50, 0xeb,
-	0xf7, 0xfe, 0x5e, 0x87, 0x9d, 0x43, 0x86, 0x03, 0x8e, 0x0f, 0x69, 0xc2, 0x03, 0x92, 0x60, 0xb6,
-	0xca, 0xc6, 0xfb, 0x00, 0xe7, 0x79, 0x12, 0xc5, 0x78, 0x18, 0xf0, 0x89, 0x36, 0xd5, 0xc2, 0x48,
-	0x8b, 0x27, 0x38, 0xbc, 0x48, 0x29, 0x49, 0xb8, 0xb4, 0xb8, 0xe5, 0x5b, 0x18, 0x61, 0x71, 0x26,
-	0x17, 0xa3, 0xbc, 0xa4, 0x00, 0x61, 0x71, 0xc6, 0x23, 0x9a, 0x2b, 0x8b, 0x5b, 0xbe, 0x86, 0x34,
-	0x1e, 0x33, 0xe6, 0xae, 0x1b, 0x3c, 0x66, 0x4c, 0xe0, 0xe3, 0xe0, 0x1c, 0xc7, 0x99, 0xdb, 0xdc,
-	0x6d, 0x08, 0xbc, 0x82, 0xd0, 0x2e, 0xb4, 0x13, 0x3a, 0x24, 0x97, 0x94, 0xfb, 0x94, 0x72, 0x77,
-	0x43, 0x3a, 0xcc, 0x46, 0x21, 0x17, 0x9a, 0x2c, 0x4f, 0x44, 0xdc, 0xb8, 0x2d, 0x29, 0xb2, 0x00,
-	0x05, 0xaf, 0x1e, 0x3e, 0x61, 0xe3, 0xcc, 0x05, 0x29, 0xd8, 0x46, 0xa1, 0x77, 0xa0, 0x5b, 0xae,
-	0xe4, 0x19, 0x61, 0x6e, 0x5b, 0x4a, 0xa8, 0x22, 0xbd, 0x23, 0xb8, 0xbb, 0xe0, 0x4b, 0x1d, 0x67,
-	0xfb, 0xd0, 0x0a, 0x0b, 0xa4, 0xf4, 0x69, 0xfb, 0x60, 0x6b, 0x5f, 0x86, 0xf6, 0x7e, 0x49, 0x5c,
-	0x92, 0x78, 0x47, 0xd0, 0x3d, 0x21, 0xe3, 0x24, 0x88, 0x5f, 0x3f, 0x62, 0x84, 0xc7, 0x24, 0x8b,
-	0x8e, 0x4f, 0x0d, 0x79, 0x5b, 0xd0, 0x2b, 0x44, 0xe9, 0x4d, 0xff, 0x73, 0x03, 0xfa, 0x4f, 0xa2,
-	0xe8, 0x15, 0x31, 0x39, 0x80, 0x0d, 0x8e, 0xd9, 0x94, 0x08, 0x89, 0x75, 0xe9, 0x4e, 0x03, 0xa3,
-	0x07, 0xe0, 0xe4, 0x19, 0x66, 0x52, 0x53, 0xfb, 0xa0, 0xad, 0x57, 0x72, 0x96, 0x61, 0xe6, 0xcb,
-	0x09, 0x84, 0xc0, 0x09, 0x84, 0x2f, 0x1d, 0xe9, 0x4b, 0x39, 0x16, 0x26, 0xe3, 0xe4, 0xd2, 0x5d,
-	0x93, 0x28, 0x31, 0x14, 0x98, 0xf0, 0x2a, 0xd2, 0x3b, 0x2c, 0x86, 0xc5, 0xb2, 0x9a, 0xe5, 0xb2,
-	0x4c, 0xd8, 0x6c, 0x2c, 0x0f, 0x9b, 0xd6, 0x8a, 0xb0, 0x81, 0x4a, 0xd8, 0x78, 0xd0, 0x09, 0x83,
-	0x34, 0x38, 0x27, 0x31, 0xe1, 0x04, 0x67, 0x6e, 0x5b, 0x1a, 0x51, 0xc1, 0xa1, 0x3d, 0xd8, 0x0c,
-	0xd2, 0x34, 0x60, 0x53, 0xca, 0x86, 0x8c, 0xbe, 0x24, 0x31, 0x76, 0x3b, 0x52, 0xc8, 0x3c, 0x5a,
-	0x48, 0xcb, 0x70, 0x4c, 0x92, 0x7c, 0xf6, 0x5c, 0x44, 0x9f, 0xdb, 0x95, 0x64, 0x15, 0x9c, 0x90,
-	0x96, 0xd0, 0xcf, 0xf0, 0xd5, 0x90, 0x91, 0x4b, 0x12, 0xe3, 0x31, 0xce, 0xdc, 0x9e, 0xf4, 0xe2,
-	0x3c, 0x1a, 0xbd, 0x0b, 0x4d, 0x16, 0x93, 0x29, 0xe1, 0x99, 0xbb, 0xb9, 0xdb, 0xd8, 0x6b, 0x1f,
-	0x74, 0xb5, 0x3f, 0x7d, 0x89, 0xf5, 0x8b, 0x59, 0xef, 0x19, 0xac, 0x2b, 0x94, 0x70, 0xaf, 0x20,
-	0xd1, 0xbb, 0x25, 0xc7, 0x02, 0x97, 0xd1, 0x97, 0x5c, 0xee, 0x95, 0xe3, 0xcb, 0xb1, 0xc0, 0x4d,
-	0x02, 0x16, 0xc9, 0x7d, 0x72, 0x7c, 0x39, 0xf6, 0x7c, 0x70, 0xc4, 0x46, 0x09, 0x57, 0xe7, 0x7a,
-	0xc3, 0xbb, 0xbe, 0x18, 0x0a, 0xcc, 0x58, 0xc7, 0x54, 0xd7, 0x17, 0x43, 0xf4, 0x4d, 0xe8, 0x05,
-	0x51, 0x44, 0x38, 0xa1, 0x49, 0x10, 0x7f, 0x42, 0xa2, 0xcc, 0x6d, 0xec, 0x36, 0xf6, 0xba, 0xfe,
-	0x1c, 0xd6, 0x3b, 0x00, 0x64, 0x07, 0x94, 0x0e, 0xfa, 0x37, 0xa1, 0x95, 0x5d, 0x67, 0x1c, 0x4f,
-	0x87, 0x46, 0x4f, 0x89, 0xf0, 0x7e, 0x59, 0x33, 0xe9, 0x62, 0xb2, 0x68, 0x55, 0x2c, 0x7e, 0xb7,
-	0x52, 0x5b, 0xea, 0x32, 0xea, 0xfa, 0x45, 0xfe, 0x94, 0xdc, 0x76, 0xb9, 0x59, 0x48, 0xd9, 0xc6,
-	0xb2, 0x94, 0x1d, 0x80, 0xbb, 0x68, 0x83, 0x4e, 0x93, 0x10, 0xee, 0x3e, 0xc3, 0x31, 0x7e, 0x1d,
-	0xfb, 0x10, 0x38, 0x49, 0x30, 0xc5, 0x3a, 0x1d, 0xe5, 0xf8, 0xf5, 0x0d, 0x58, 0x54, 0xa2, 0x0d,
-	0x38, 0x86, 0x3b, 0xcf, 0x49, 0xc6, 0x5f, 0xad, 0x7e, 0x41, 0x55, 0x7d, 0x99, 0xaa, 0xdf, 0xd7,
-	0x00, 0x4a, 0x59, 0xc6, 0xe6, 0x9a, 0x65, 0x33, 0x02, 0x07, 0xcf, 0x08, 0xd7, 0xf9, 0x2e, 0xc7,
-	0x22, 0x2a, 0x78, 0x98, 0xea, 0x23, 0x48, 0x0c, 0x45, 0xbd, 0xcc, 0x13, 0x32, 0x3b, 0xa1, 0xe1,
-	0x05, 0xe6, 0x99, 0xac, 0xe7, 0x1b, 0xbe, 0x8d, 0x92, 0x49, 0x3b, 0xc1, 0x71, 0x2c, 0x8b, 0xfa,
-	0x86, 0xaf, 0x00, 0x51, 0x81, 0xf1, 0x34, 0xe5, 0xd7, 0x9f, 0x9d, 0xb8, 0xeb, 0x32, 0xff, 0x0a,
-	0xd0, 0x3b, 0x86, 0x9d, 0xf9, 0x95, 0xea, 0x18, 0x7a, 0x04, 0xed, 0x72, 0x15, 0x99, 0x5b, 0x93,
-	0x09, 0xb2, 0x64, 0xeb, 0x6d, 0x2a, 0xef, 0x3e, 0x74, 0x4e, 0x78, 0xc0, 0xf1, 0x0a, 0x7f, 0x79,
-	0x7b, 0xd0, 0x33, 0x55, 0x57, 0x12, 0xaa, 0xba, 0x11, 0xf0, 0x3c, 0xd3, 0x54, 0x1a, 0xf2, 0xfe,
-	0xd2, 0x80, 0xa6, 0x0e, 0xeb, 0xa2, 0x36, 0xd5, 0xca, 0xda, 0xf4, 0x3f, 0x29, 0x91, 0x95, 0xac,
-	0x6a, 0xce, 0x65, 0xd5, 0xff, 0xcb, 0x65, 0x59, 0x2e, 0xff, 0x56, 0x83, 0x96, 0xd9, 0xe6, 0xaf,
-	0xdd, 0xce, 0xbc, 0x07, 0xad, 0x54, 0x6d, 0x3c, 0x56, 0x55, 0xaf, 0x7d, 0xd0, 0xd3, 0x8a, 0x8a,
-	0x3a, 0x57, 0x12, 0x58, 0xf1, 0xe3, 0xd8, 0xf1, 0x63, 0xb5, 0x2b, 0x6b, 0x95, 0x76, 0x05, 0x81,
-	0x93, 0x8a, 0x72, 0xba, 0x2e, 0xcb, 0xa9, 0x1c, 0xdb, 0x0d, 0x4a, 0xb3, 0xd2, 0xa0, 0x78, 0x1f,
-	0x42, 0xf3, 0x38, 0x08, 0x27, 0x24, 0x91, 0x19, 0x1a, 0xa6, 0x3a, 0x4c, 0xbb, 0xbe, 0x1c, 0x0b,
-	0x25, 0x53, 0x3c, 0xa5, 0xec, 0x5a, 0xd7, 0x7e, 0x0d, 0x79, 0x17, 0xd0, 0xd5, 0x69, 0xa0, 0x93,
-	0xe9, 0x21, 0x80, 0x69, 0x31, 0x8a, 0x5c, 0x5a, 0x6c, 0x43, 0x2c, 0x1a, 0xb4, 0x07, 0xcd, 0xa9,
-	0xd2, 0xac, 0xab, 0x6e, 0xe1, 0x03, 0x6d, 0x8f, 0x5f, 0x4c, 0x7b, 0xbf, 0xae, 0xc1, 0x8e, 0xea,
-	0x31, 0x5f, 0xd9, 0x49, 0x2e, 0xef, 0x5d, 0x94, 0xfb, 0x1a, 0x15, 0xf7, 0x3d, 0x82, 0x16, 0xc3,
-	0x19, 0xcd, 0x59, 0x88, 0x95, 0x67, 0xdb, 0x07, 0x77, 0x8a, 0x4c, 0x92, 0xba, 0x7c, 0x3d, 0xeb,
-	0x97, 0x74, 0xde, 0x6f, 0x9a, 0xd0, 0xab, 0xce, 0x8a, 0x8a, 0x75, 0x1e, 0x5f, 0x10, 0xfa, 0x42,
-	0x35, 0xc7, 0x35, 0xe9, 0x26, 0x1b, 0x25, 0xb2, 0x2a, 0x4c, 0xf3, 0x93, 0x49, 0xc0, 0x70, 0xa6,
-	0xdd, 0x58, 0x22, 0xf4, 0xec, 0x10, 0x33, 0x42, 0x8b, 0xc3, 0xb4, 0x44, 0x88, 0x32, 0x10, 0xa6,
-	0xf9, 0x17, 0x39, 0xe5, 0x81, 0x34, 0xd2, 0xf1, 0x0d, 0x2c, 0xbb, 0xe2, 0x34, 0xcf, 0x30, 0x3f,
-	0x14, 0xbb, 0xb6, 0xa6, 0xbb, 0x62, 0x83, 0x29, 0xe7, 0x8f, 0xf1, 0x34, 0xd3, 0x69, 0x6e, 0x61,
-	0x84, 0xe5, 0x6a, 0x37, 0x9f, 0x8b, 0xa0, 0x96, 0x81, 0xe1, 0xf8, 0x36, 0x4a, 0x48, 0x50, 0xe0,
-	0xc9, 0x55, 0x90, 0xca, 0xb4, 0x77, 0x7c, 0x0b, 0x83, 0xde, 0x83, 0xbe, 0x82, 0x7c, 0x9c, 0x61,
-	0x76, 0x19, 0x88, 0x63, 0x5b, 0x96, 0x01, 0xc7, 0x5f, 0x9c, 0x10, 0xd4, 0x17, 0x98, 0x25, 0x38,
-	0x3e, 0xb6, 0xb4, 0x82, 0xa2, 0x5e, 0x98, 0x40, 0x07, 0xb0, 0xad, 0x90, 0xa7, 0x87, 0x43, 0x9b,
-	0xa1, 0x2d, 0x19, 0x96, 0xce, 0x89, 0x4c, 0x97, 0x8e, 0x7f, 0x8e, 0x83, 0x97, 0x7a, 0x3f, 0x3a,
-	0x92, 0x7c, 0x1e, 0x8d, 0x9e, 0x40, 0xdf, 0xda, 0xa2, 0x67, 0xf8, 0x92, 0x84, 0xd8, 0xed, 0xca,
-	0xa8, 0xbd, 0xad, 0xa3, 0xc0, 0x9e, 0xf2, 0x17, 0xa9, 0xd1, 0x19, 0x0c, 0x24, 0xf2, 0x74, 0xc2,
-	0x28, 0xe7, 0x31, 0xf6, 0x71, 0x10, 0x3d, 0x4d, 0x33, 0x2d, 0xab, 0x27, 0x65, 0x15, 0x11, 0x55,
-	0xd0, 0x68, 0x69, 0x37, 0x30, 0xa2, 0x17, 0xf0, 0x46, 0x65, 0xf6, 0x05, 0x23, 0x1c, 0x97, 0x72,
-	0x37, 0x6f, 0x92, 0x7b, 0x13, 0xe7, 0x82, 0x60, 0xa1, 0xf6, 0x88, 0x1a, 0xc1, 0x5b, 0xaf, 0x2f,
-	0xb8, 0xca, 0x89, 0x7e, 0x06, 0x6f, 0x2e, 0xea, 0xb5, 0x24, 0xf7, 0x6f, 0x92, 0x7c, 0x23, 0xab,
-	0x48, 0x0e, 0x51, 0xbf, 0xd4, 0xce, 0x23, 0x95, 0x1c, 0x06, 0xe1, 0x7d, 0x04, 0xdd, 0xa7, 0x31,
-	0x0d, 0x2f, 0x8e, 0x3e, 0xd7, 0xe4, 0x95, 0x2b, 0x77, 0x63, 0xe9, 0x95, 0xbb, 0xa1, 0xaf, 0xdc,
-	0xde, 0x57, 0xd0, 0xa9, 0x6c, 0xe7, 0xf7, 0x64, 0x1e, 0x17, 0xa2, 0xf4, 0x45, 0x6a, 0x5b, 0x1b,
-	0x5d, 0x51, 0xe3, 0xdb, 0x84, 0xa2, 0xbe, 0x5c, 0xa9, 0x50, 0x53, 0xcd, 0xad, 0x86, 0x44, 0xee,
-	0xc4, 0x65, 0x18, 0xaa, 0x7b, 0x93, 0x85, 0xf1, 0x7e, 0x0e, 0xbd, 0xaa, 0x2b, 0xfe, 0x63, 0x0b,
-	0x10, 0x38, 0x2c, 0xe0, 0xb8, 0xe8, 0xce, 0xc5, 0xd8, 0xbb, 0x07, 0x77, 0x17, 0x2a, 0xa6, 0x6e,
-	0xfd, 0xae, 0xa1, 0xfb, 0xf1, 0x25, 0x4e, 0xb8, 0xb9, 0x9d, 0x3d, 0x86, 0x96, 0x79, 0xf2, 0xd0,
-	0xa5, 0x78, 0xb0, 0xaf, 0x1e, 0x45, 0xf6, 0x8b, 0x47, 0x91, 0xfd, 0xd3, 0x82, 0xc2, 0x2f, 0x89,
-	0xc5, 0x1a, 0x33, 0x4e, 0x19, 0x8e, 0x3e, 0x4f, 0xe2, 0xeb, 0xe2, 0x25, 0xa1, 0xc4, 0xe8, 0xea,
-	0xec, 0x98, 0xe6, 0xe8, 0x77, 0x35, 0x58, 0x93, 0xba, 0x97, 0xde, 0x32, 0x14, 0x75, 0xdd, 0xd4,
-	0xf2, 0x6a, 0xe5, 0xee, 0x9a, 0xca, 0xad, 0x6b, 0xbc, 0x53, 0xd6, 0xf8, 0xca, 0x0a, 0xd6, 0xbf,
-	0xc6, 0x0a, 0xbc, 0xdf, 0xd6, 0xa1, 0xf3, 0x19, 0xe6, 0x57, 0x94, 0x5d, 0x88, 0xf3, 0x2c, 0x5b,
-	0xda, 0xba, 0xde, 0x83, 0x0d, 0x36, 0x1b, 0x9d, 0x5f, 0x73, 0x53, 0xbf, 0x9b, 0x6c, 0xf6, 0x54,
-	0x80, 0xe8, 0x2d, 0x00, 0x36, 0x1b, 0x0d, 0x03, 0xd5, 0xae, 0xea, 0xf2, 0xcd, 0x66, 0x1a, 0x81,
-	0xde, 0x80, 0x96, 0x3f, 0x1b, 0x61, 0xc6, 0x28, 0xcb, 0x8a, 0xfa, 0xed, 0xcf, 0x3e, 0x96, 0xb0,
-	0xe0, 0xf5, 0x67, 0xa3, 0x88, 0xd1, 0x34, 0xc5, 0x91, 0xac, 0xdf, 0x8e, 0xdf, 0xf2, 0x67, 0xcf,
-	0x14, 0x42, 0x68, 0x3d, 0x2d, 0xb4, 0xae, 0x2b, 0xad, 0xa7, 0xa5, 0xd6, 0xd3, 0xd9, 0x28, 0xd5,
-	0x5a, 0x55, 0xe1, 0x6e, 0x9d, 0xda, 0x5a, 0x4f, 0x8d, 0x56, 0x55, 0xb5, 0x37, 0x4e, 0x2d, 0xad,
-	0xa7, 0xa5, 0xd6, 0x56, 0xc1, 0xab, 0xb5, 0x7a, 0x7f, 0xaa, 0xc1, 0xc6, 0x61, 0x9a, 0x9f, 0x65,
-	0xc1, 0x18, 0xa3, 0x07, 0xd0, 0xe6, 0x94, 0x07, 0xf1, 0x28, 0x17, 0xa0, 0x3e, 0xdb, 0x40, 0xa2,
-	0x14, 0xc1, 0xdb, 0xd0, 0x49, 0x31, 0x0b, 0xd3, 0x5c, 0x53, 0xd4, 0x77, 0x1b, 0xe2, 0x0c, 0x51,
-	0x38, 0x45, 0xb2, 0x0f, 0xb7, 0xe5, 0xdc, 0x88, 0x24, 0x23, 0x55, 0xb4, 0xa7, 0x34, 0xc2, 0xda,
-	0x55, 0x7d, 0x39, 0x75, 0x94, 0x7c, 0x6a, 0x26, 0xd0, 0xb7, 0xa1, 0x6f, 0xe8, 0x45, 0x33, 0x2b,
-	0xa9, 0x95, 0xeb, 0x36, 0x35, 0xf5, 0x99, 0x46, 0x7b, 0x5f, 0x99, 0x1c, 0x22, 0xc9, 0xf8, 0x59,
-	0xc0, 0x03, 0xd1, 0xe8, 0xa4, 0xf2, 0xe4, 0xcc, 0xb4, 0xb5, 0x05, 0x88, 0xbe, 0x03, 0x7d, 0xae,
-	0xf3, 0x2d, 0x1a, 0x15, 0x34, 0x6a, 0x37, 0xb7, 0xcc, 0xc4, 0x50, 0x13, 0x7f, 0x03, 0x7a, 0x25,
-	0xb1, 0x6c, 0x9b, 0x94, 0xbd, 0x5d, 0x83, 0x15, 0xd1, 0xe4, 0xfd, 0x41, 0x39, 0x4b, 0x45, 0xce,
-	0x7b, 0xf2, 0x20, 0xb7, 0x5c, 0xd5, 0x3e, 0xd8, 0x2c, 0x1a, 0x20, 0xed, 0x0c, 0x79, 0x78, 0x2b,
-	0xb7, 0xfc, 0x10, 0x36, 0xb9, 0x31, 0x7d, 0x14, 0x05, 0x3c, 0xd0, 0xa9, 0x37, 0x57, 0x27, 0xf5,
-	0xc2, 0xfc, 0x1e, 0xaf, 0x2e, 0xf4, 0x6d, 0xe8, 0xa8, 0xce, 0x5c, 0x2b, 0x54, 0xf6, 0xb5, 0x15,
-	0x4e, 0xaa, 0xf0, 0x3e, 0x82, 0xd6, 0x90, 0x44, 0x99, 0xb2, 0xce, 0x85, 0x66, 0x98, 0x33, 0x86,
-	0x93, 0xa2, 0x45, 0x29, 0x40, 0x51, 0x1e, 0x65, 0x57, 0xab, 0x9d, 0xa1, 0x00, 0x8f, 0x02, 0xa8,
-	0x93, 0x55, 0x6a, 0xdb, 0x86, 0x35, 0x3b, 0x04, 0x14, 0x20, 0xe2, 0x6c, 0x1a, 0xcc, 0xcc, 0xd6,
-	0xcb, 0x38, 0x9b, 0x06, 0x33, 0xb5, 0x40, 0x17, 0x9a, 0x2f, 0x03, 0x12, 0x87, 0xfa, 0xc1, 0xce,
-	0xf1, 0x0b, 0xb0, 0x54, 0xe8, 0xd8, 0x0a, 0xff, 0x58, 0x87, 0xb6, 0xd2, 0xa8, 0x0c, 0xde, 0x86,
-	0xb5, 0x30, 0x08, 0x27, 0x46, 0xa5, 0x04, 0xd0, 0xbb, 0x85, 0x21, 0xd5, 0x8b, 0x7a, 0x69, 0x6a,
-	0x61, 0xdb, 0x43, 0x80, 0xec, 0x2a, 0x48, 0x2d, 0xef, 0x2c, 0xa5, 0x6e, 0x09, 0x22, 0x65, 0xf0,
-	0x07, 0xd0, 0x51, 0xf1, 0xa9, 0x79, 0x9c, 0x55, 0x3c, 0x6d, 0x45, 0xa6, 0xb8, 0x1e, 0x89, 0x4b,
-	0x51, 0xc0, 0x55, 0x13, 0xde, 0x3e, 0x78, 0xab, 0x42, 0x2e, 0x57, 0xb2, 0x2f, 0xbf, 0x1f, 0x27,
-	0x9c, 0x5d, 0xfb, 0x8a, 0x76, 0xf0, 0x18, 0xa0, 0x44, 0x8a, 0x7a, 0x76, 0x81, 0xaf, 0x8b, 0xcb,
-	0xdf, 0x05, 0xbe, 0x16, 0x6b, 0xbf, 0x0c, 0xe2, 0xbc, 0x70, 0xaa, 0x02, 0x7e, 0x50, 0x7f, 0x5c,
-	0xf3, 0x42, 0xd8, 0x7c, 0x2a, 0x0e, 0x4c, 0x8b, 0xbd, 0x72, 0xe8, 0x39, 0x4b, 0x0f, 0x3d, 0xa7,
-	0x78, 0x67, 0xee, 0x41, 0x9d, 0xa6, 0xba, 0x11, 0xae, 0xd3, 0xb4, 0x54, 0xe4, 0x58, 0x8a, 0xbc,
-	0x7f, 0x38, 0x00, 0xa5, 0x16, 0x74, 0x02, 0x03, 0x42, 0x47, 0xa2, 0x8f, 0x23, 0x21, 0x56, 0x05,
-	0x69, 0xc4, 0x70, 0x98, 0xb3, 0x8c, 0x5c, 0x62, 0xdd, 0xea, 0xef, 0x98, 0x63, 0xaa, 0x62, 0x9c,
-	0x7f, 0x97, 0xd0, 0x13, 0xc5, 0x28, 0x2b, 0x97, 0x5f, 0xb0, 0xa1, 0x9f, 0xc0, 0x9d, 0x52, 0x68,
-	0x64, 0xc9, 0xab, 0xdf, 0x28, 0xef, 0xb6, 0x91, 0x17, 0x95, 0xb2, 0x7e, 0x04, 0xb7, 0x09, 0x1d,
-	0x7d, 0x99, 0xe3, 0xbc, 0x22, 0xa9, 0x71, 0xa3, 0xa4, 0x3e, 0xa1, 0x5f, 0x48, 0x8e, 0x52, 0xce,
-	0x17, 0x70, 0xcf, 0x5a, 0xa8, 0x48, 0x7b, 0x4b, 0x9a, 0x73, 0xa3, 0xb4, 0x1d, 0x63, 0x97, 0x28,
-	0x0c, 0xa5, 0xc8, 0x4f, 0x61, 0x87, 0xd0, 0xd1, 0x55, 0x40, 0xf8, 0xbc, 0xbc, 0xb5, 0x57, 0xad,
-	0xf3, 0x45, 0x40, 0x78, 0x55, 0x98, 0x5a, 0xe7, 0x14, 0xb3, 0x71, 0x65, 0x9d, 0xeb, 0xaf, 0x5a,
-	0xe7, 0xb1, 0xe4, 0x28, 0xe5, 0x3c, 0x85, 0x3e, 0xa1, 0xf3, 0xf6, 0x34, 0x6f, 0x94, 0xb2, 0x49,
-	0x68, 0xd5, 0x96, 0x43, 0xe8, 0x67, 0x38, 0xe4, 0x94, 0xd9, 0xb1, 0xb0, 0x71, 0xa3, 0x8c, 0x2d,
-	0xcd, 0x60, 0x84, 0x78, 0x5f, 0x42, 0xe7, 0xc7, 0xf9, 0x18, 0xf3, 0xf8, 0xdc, 0xe4, 0xfc, 0x7f,
-	0xbb, 0xcc, 0xfc, 0xab, 0x0e, 0xed, 0xc3, 0x31, 0xa3, 0x79, 0x5a, 0xa9, 0xda, 0x2a, 0x87, 0x17,
-	0xaa, 0xb6, 0xa4, 0x91, 0x55, 0x5b, 0x51, 0x7f, 0x08, 0x1d, 0x75, 0xaf, 0xd1, 0x0c, 0xaa, 0x0a,
-	0xa1, 0xc5, 0xa4, 0x2f, 0xee, 0x51, 0x8a, 0xed, 0x40, 0xdf, 0x11, 0x35, 0x57, 0xb5, 0x1a, 0x95,
-	0x6e, 0xf2, 0xe1, 0xbc, 0xcc, 0xba, 0x23, 0xe8, 0x4e, 0x94, 0x6f, 0x34, 0x97, 0x0a, 0xc0, 0x77,
-	0x0a, 0xe3, 0xca, 0x35, 0xec, 0xdb, 0x3e, 0x54, 0xae, 0xee, 0x4c, 0x6c, 0xb7, 0xbe, 0x0f, 0x20,
-	0x9a, 0xe6, 0x51, 0x51, 0xa8, 0xec, 0x5f, 0x04, 0xe6, 0x84, 0x50, 0x8d, 0xb5, 0x1c, 0x0e, 0x4e,
-	0xa1, 0xbf, 0x20, 0x73, 0x49, 0x99, 0xfa, 0x96, 0x5d, 0xa6, 0xca, 0x8b, 0x93, 0xcd, 0x6a, 0xd7,
-	0xae, 0xbf, 0xd6, 0xd4, 0xa3, 0x41, 0xf9, 0x8a, 0xfb, 0x18, 0xba, 0x89, 0x6a, 0xbe, 0xcc, 0x06,
-	0xd8, 0x37, 0x30, 0xbb, 0x31, 0xf3, 0x3b, 0x89, 0xdd, 0xa6, 0x7d, 0x08, 0x9d, 0x50, 0x7a, 0x60,
-	0xe9, 0x46, 0x58, 0xce, 0xf1, 0xdb, 0xa1, 0xb5, 0xdb, 0x95, 0x46, 0xd1, 0xf9, 0x3a, 0x8d, 0xa2,
-	0x7e, 0xf7, 0x5b, 0xf5, 0x4b, 0xe3, 0xe0, 0x9f, 0xeb, 0xd0, 0x78, 0x32, 0x3c, 0x42, 0x67, 0xb0,
-	0x35, 0xff, 0x47, 0x10, 0xdd, 0xd7, 0x66, 0xad, 0xf8, 0x8b, 0x38, 0x78, 0xb0, 0x72, 0x5e, 0xb7,
-	0xec, 0xb7, 0x90, 0x0f, 0x9b, 0x73, 0xff, 0x7f, 0x50, 0x71, 0xd4, 0x2c, 0xff, 0xc7, 0x36, 0xb8,
-	0xbf, 0x6a, 0xda, 0x96, 0x39, 0x77, 0x47, 0x30, 0x32, 0x97, 0xbf, 0xb6, 0x18, 0x99, 0xab, 0xae,
-	0x16, 0xb7, 0xd0, 0xf7, 0x61, 0x5d, 0xfd, 0x11, 0x42, 0xc5, 0xc5, 0xa5, 0xf2, 0xaf, 0x69, 0x70,
-	0x67, 0x0e, 0x6b, 0x18, 0x9f, 0x43, 0xb7, 0xf2, 0x1b, 0x11, 0xbd, 0x51, 0xd1, 0x55, 0xfd, 0xa1,
-	0x34, 0x78, 0x73, 0xf9, 0xa4, 0x91, 0x76, 0x08, 0x50, 0xfe, 0x34, 0x40, 0xae, 0xa6, 0x5e, 0xf8,
-	0x31, 0x35, 0xb8, 0xb7, 0x64, 0xc6, 0x08, 0x39, 0x83, 0xad, 0xf9, 0x07, 0x7c, 0x34, 0xe7, 0xd5,
-	0xf9, 0xe7, 0x73, 0xb3, 0x95, 0x2b, 0x5f, 0xfe, 0xa5, 0xd8, 0xf9, 0x67, 0x79, 0x23, 0x76, 0xc5,
-	0x4f, 0x01, 0x23, 0x76, 0xe5, 0x7b, 0xfe, 0x2d, 0xf4, 0x39, 0xf4, 0xaa, 0xef, 0xdc, 0xa8, 0x70,
-	0xd2, 0xd2, 0x87, 0xfe, 0xc1, 0x5b, 0x2b, 0x66, 0x8d, 0xc0, 0x0f, 0x60, 0x4d, 0x3d, 0x60, 0x17,
-	0xe9, 0x68, 0xbf, 0x7b, 0x0f, 0xb6, 0xab, 0x48, 0xc3, 0xf5, 0x10, 0xd6, 0xd5, 0xed, 0xd2, 0x04,
-	0x40, 0xe5, 0xb2, 0x39, 0xe8, 0xd8, 0x58, 0xef, 0xd6, 0xc3, 0x5a, 0xa1, 0x27, 0xab, 0xe8, 0xc9,
-	0x96, 0xe9, 0xb1, 0x36, 0xe7, 0x7c, 0x5d, 0xa6, 0xeb, 0xa3, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff,
-	0x4c, 0xa9, 0xa8, 0x4d, 0xd0, 0x1f, 0x00, 0x00,
+	0x99, 0x94, 0x6d, 0x56, 0x48, 0x48, 0xa3, 0x76, 0x77, 0xed, 0x4c, 0xe1, 0x9e, 0xae, 0x4e, 0x75,
+	0xb5, 0x3d, 0xbe, 0xe4, 0xc0, 0x01, 0x6e, 0x70, 0x45, 0xe2, 0xc8, 0x8d, 0x3b, 0x07, 0xf8, 0x03,
+	0x48, 0xfc, 0x10, 0x24, 0x0e, 0xdc, 0x39, 0xa2, 0xfa, 0xe8, 0xee, 0xea, 0xf9, 0xf0, 0x6e, 0x90,
+	0x10, 0x17, 0x2e, 0xad, 0x7a, 0xaf, 0xde, 0x57, 0xbd, 0x7a, 0xef, 0xd5, 0xab, 0x2e, 0x68, 0xf9,
+	0x09, 0xdd, 0x4f, 0x38, 0x13, 0x0c, 0xad, 0x89, 0xeb, 0x84, 0xa4, 0x83, 0x07, 0x63, 0xc6, 0xc6,
+	0x11, 0x79, 0x5f, 0x21, 0xcf, 0xb3, 0x97, 0xef, 0x0b, 0x3a, 0x25, 0xa9, 0xf0, 0xa7, 0x89, 0xa6,
+	0xf3, 0xee, 0xc1, 0xdd, 0x4f, 0x88, 0x38, 0x21, 0xfc, 0x92, 0xf0, 0x9f, 0x12, 0x9e, 0x52, 0x16,
+	0x63, 0xf2, 0x65, 0x46, 0x52, 0xe1, 0xcd, 0xc0, 0x5d, 0x9c, 0x4a, 0x13, 0x16, 0xa7, 0x04, 0x6d,
+	0xc3, 0xda, 0xd4, 0xff, 0x05, 0xe3, 0x6e, 0x6d, 0xb7, 0xb6, 0xd7, 0xc5, 0x1a, 0x50, 0x58, 0x1a,
+	0x33, 0xee, 0xd6, 0x0d, 0x56, 0x02, 0x12, 0x9b, 0xf8, 0x22, 0x98, 0xb8, 0x0d, 0x8d, 0x55, 0x00,
+	0x1a, 0xc0, 0x06, 0x27, 0x97, 0x54, 0x4a, 0x75, 0x9d, 0xdd, 0xda, 0x5e, 0x0b, 0x17, 0xb0, 0xf7,
+	0xab, 0x1a, 0x6c, 0x9f, 0x25, 0xa1, 0x2f, 0xc8, 0x90, 0xb3, 0x80, 0xa4, 0xa9, 0x31, 0x09, 0xf5,
+	0xa0, 0x4e, 0x43, 0xa5, 0xb3, 0x85, 0xeb, 0x34, 0x44, 0x5b, 0xd0, 0x48, 0x68, 0xa8, 0xd4, 0xb5,
+	0xb0, 0x1c, 0xa2, 0xfb, 0x00, 0x41, 0xc4, 0x52, 0x72, 0x22, 0x42, 0x1a, 0x2b, 0x8d, 0x1b, 0xd8,
+	0xc2, 0x48, 0x63, 0xae, 0x68, 0x28, 0x26, 0x4a, 0x67, 0x17, 0x6b, 0x00, 0xed, 0xc0, 0xfa, 0x84,
+	0xd0, 0xf1, 0x44, 0xb8, 0x6b, 0x0a, 0x6d, 0x20, 0xef, 0x2e, 0xdc, 0x99, 0xb3, 0x43, 0xaf, 0xdf,
+	0xfb, 0x5b, 0x1d, 0x76, 0x0e, 0x39, 0xf1, 0x05, 0x39, 0x64, 0xb1, 0xf0, 0x69, 0x4c, 0xf8, 0x2a,
+	0x1b, 0xef, 0x03, 0x9c, 0x67, 0x71, 0x18, 0x91, 0xa1, 0x2f, 0x26, 0xc6, 0x54, 0x0b, 0xa3, 0x2c,
+	0x9e, 0x90, 0xe0, 0x22, 0x61, 0x34, 0x16, 0xca, 0xe2, 0x16, 0xb6, 0x30, 0xd2, 0xe2, 0x54, 0x2d,
+	0x46, 0x7b, 0x49, 0x03, 0xd2, 0xe2, 0x54, 0x84, 0x2c, 0xd3, 0x16, 0xb7, 0xb0, 0x81, 0x0c, 0x9e,
+	0x70, 0xee, 0xae, 0x17, 0x78, 0xc2, 0xb9, 0xc4, 0x47, 0xfe, 0x39, 0x89, 0x52, 0xb7, 0xb9, 0xdb,
+	0x90, 0x78, 0x0d, 0xa1, 0x5d, 0x68, 0xc7, 0x6c, 0x48, 0x2f, 0x99, 0xc0, 0x8c, 0x09, 0x77, 0x43,
+	0x39, 0xcc, 0x46, 0x21, 0x17, 0x9a, 0x3c, 0x8b, 0x65, 0xdc, 0xb8, 0x2d, 0x25, 0x32, 0x07, 0x25,
+	0xaf, 0x19, 0x3e, 0xe1, 0xe3, 0xd4, 0x05, 0x25, 0xd8, 0x46, 0xa1, 0x77, 0xa0, 0x5b, 0xae, 0xe4,
+	0x19, 0xe5, 0x6e, 0x5b, 0x49, 0xa8, 0x22, 0xbd, 0x23, 0xb8, 0xbb, 0xe0, 0x4b, 0x13, 0x67, 0xfb,
+	0xd0, 0x0a, 0x72, 0xa4, 0xf2, 0x69, 0xfb, 0x60, 0x6b, 0x5f, 0x85, 0xf6, 0x7e, 0x49, 0x5c, 0x92,
+	0x78, 0x47, 0xd0, 0x3d, 0xa1, 0xe3, 0xd8, 0x8f, 0x5e, 0x3f, 0x62, 0xa4, 0xc7, 0x14, 0x8b, 0x89,
+	0x4f, 0x03, 0x79, 0x5b, 0xd0, 0xcb, 0x45, 0x99, 0x4d, 0xff, 0x53, 0x03, 0xfa, 0x4f, 0xc2, 0xf0,
+	0x15, 0x31, 0x39, 0x80, 0x0d, 0x41, 0xf8, 0x94, 0x4a, 0x89, 0x75, 0xe5, 0xce, 0x02, 0x46, 0x0f,
+	0xc0, 0xc9, 0x52, 0xc2, 0x95, 0xa6, 0xf6, 0x41, 0xdb, 0xac, 0xe4, 0x2c, 0x25, 0x1c, 0xab, 0x09,
+	0x84, 0xc0, 0xf1, 0xa5, 0x2f, 0x1d, 0xe5, 0x4b, 0x35, 0x96, 0x26, 0x93, 0xf8, 0xd2, 0x5d, 0x53,
+	0x28, 0x39, 0x94, 0x98, 0xe0, 0x2a, 0x34, 0x3b, 0x2c, 0x87, 0xf9, 0xb2, 0x9a, 0xe5, 0xb2, 0x8a,
+	0xb0, 0xd9, 0x58, 0x1e, 0x36, 0xad, 0x15, 0x61, 0x03, 0x95, 0xb0, 0xf1, 0xa0, 0x13, 0xf8, 0x89,
+	0x7f, 0x4e, 0x23, 0x2a, 0x28, 0x49, 0xdd, 0xb6, 0x32, 0xa2, 0x82, 0x43, 0x7b, 0xb0, 0xe9, 0x27,
+	0x89, 0xcf, 0xa7, 0x8c, 0x0f, 0x39, 0x7b, 0x49, 0x23, 0xe2, 0x76, 0x94, 0x90, 0x79, 0xb4, 0x94,
+	0x96, 0x92, 0x88, 0xc6, 0xd9, 0xec, 0xb9, 0x8c, 0x3e, 0xb7, 0xab, 0xc8, 0x2a, 0x38, 0x29, 0x2d,
+	0x66, 0x9f, 0x91, 0xab, 0x21, 0xa7, 0x97, 0x34, 0x22, 0x63, 0x92, 0xba, 0x3d, 0xe5, 0xc5, 0x79,
+	0x34, 0x7a, 0x17, 0x9a, 0x3c, 0xa2, 0x53, 0x2a, 0x52, 0x77, 0x73, 0xb7, 0xb1, 0xd7, 0x3e, 0xe8,
+	0x1a, 0x7f, 0x62, 0x85, 0xc5, 0xf9, 0xac, 0xf7, 0x0c, 0xd6, 0x35, 0x4a, 0xba, 0x57, 0x92, 0x98,
+	0xdd, 0x52, 0x63, 0x89, 0x4b, 0xd9, 0x4b, 0xa1, 0xf6, 0xca, 0xc1, 0x6a, 0x2c, 0x71, 0x13, 0x9f,
+	0x87, 0x6a, 0x9f, 0x1c, 0xac, 0xc6, 0x1e, 0x06, 0x47, 0x6e, 0x94, 0x74, 0x75, 0x66, 0x36, 0xbc,
+	0x8b, 0xe5, 0x50, 0x62, 0xc6, 0x26, 0xa6, 0xba, 0x58, 0x0e, 0xd1, 0x37, 0xa1, 0xe7, 0x87, 0x21,
+	0x15, 0x94, 0xc5, 0x7e, 0xf4, 0x09, 0x0d, 0x53, 0xb7, 0xb1, 0xdb, 0xd8, 0xeb, 0xe2, 0x39, 0xac,
+	0x77, 0x00, 0xc8, 0x0e, 0x28, 0x13, 0xf4, 0x6f, 0x42, 0x2b, 0xbd, 0x4e, 0x05, 0x99, 0x0e, 0x0b,
+	0x3d, 0x25, 0xc2, 0xfb, 0x65, 0xad, 0x48, 0x97, 0x22, 0x8b, 0x56, 0xc5, 0xe2, 0x77, 0x2b, 0xb5,
+	0xa5, 0xae, 0xa2, 0xae, 0x9f, 0xe7, 0x4f, 0xc9, 0x6d, 0x97, 0x9b, 0x85, 0x94, 0x6d, 0x2c, 0x4b,
+	0xd9, 0x01, 0xb8, 0x8b, 0x36, 0x98, 0x34, 0x09, 0xe0, 0xee, 0x33, 0x12, 0x91, 0xd7, 0xb1, 0x0f,
+	0x81, 0x13, 0xfb, 0x53, 0x62, 0xd2, 0x51, 0x8d, 0x5f, 0xdf, 0x80, 0x45, 0x25, 0xc6, 0x80, 0x63,
+	0xb8, 0xf3, 0x9c, 0xa6, 0xe2, 0xd5, 0xea, 0x17, 0x54, 0xd5, 0x97, 0xa9, 0xfa, 0x5d, 0x0d, 0xa0,
+	0x94, 0x55, 0xd8, 0x5c, 0xb3, 0x6c, 0x46, 0xe0, 0x90, 0x19, 0x15, 0x26, 0xdf, 0xd5, 0x58, 0x46,
+	0x85, 0x08, 0x12, 0x73, 0x04, 0xc9, 0xa1, 0xac, 0x97, 0x59, 0x4c, 0x67, 0x27, 0x2c, 0xb8, 0x20,
+	0x22, 0x55, 0xf5, 0x7c, 0x03, 0xdb, 0x28, 0x95, 0xb4, 0x13, 0x12, 0x45, 0xaa, 0xa8, 0x6f, 0x60,
+	0x0d, 0xc8, 0x0a, 0x4c, 0xa6, 0x89, 0xb8, 0xfe, 0xec, 0xc4, 0x5d, 0x57, 0xf9, 0x97, 0x83, 0xde,
+	0x31, 0xec, 0xcc, 0xaf, 0xd4, 0xc4, 0xd0, 0x23, 0x68, 0x97, 0xab, 0x48, 0xdd, 0x9a, 0x4a, 0x90,
+	0x25, 0x5b, 0x6f, 0x53, 0x79, 0xf7, 0xa1, 0x73, 0x22, 0x7c, 0x41, 0x56, 0xf8, 0xcb, 0xdb, 0x83,
+	0x5e, 0x51, 0x75, 0x15, 0xa1, 0xae, 0x1b, 0xbe, 0xc8, 0x52, 0x43, 0x65, 0x20, 0xef, 0xcf, 0x0d,
+	0x68, 0x9a, 0xb0, 0xce, 0x6b, 0x53, 0xad, 0xac, 0x4d, 0xff, 0x93, 0x12, 0x59, 0xc9, 0xaa, 0xe6,
+	0x5c, 0x56, 0xfd, 0xbf, 0x5c, 0x96, 0xe5, 0xf2, 0xaf, 0x35, 0x68, 0x15, 0xdb, 0xfc, 0xb5, 0xdb,
+	0x99, 0xf7, 0xa0, 0x95, 0xe8, 0x8d, 0x27, 0xba, 0xea, 0xb5, 0x0f, 0x7a, 0x46, 0x51, 0x5e, 0xe7,
+	0x4a, 0x02, 0x2b, 0x7e, 0x1c, 0x3b, 0x7e, 0xac, 0x76, 0x65, 0xad, 0xd2, 0xae, 0x20, 0x70, 0x12,
+	0x59, 0x4e, 0xd7, 0x55, 0x39, 0x55, 0x63, 0xbb, 0x41, 0x69, 0x56, 0x1a, 0x14, 0xef, 0x43, 0x68,
+	0x1e, 0xfb, 0xc1, 0x84, 0xc6, 0x2a, 0x43, 0x83, 0xc4, 0x84, 0x69, 0x17, 0xab, 0xb1, 0x54, 0x32,
+	0x25, 0x53, 0xc6, 0xaf, 0x4d, 0xed, 0x37, 0x90, 0x77, 0x01, 0x5d, 0x93, 0x06, 0x26, 0x99, 0x1e,
+	0x02, 0x14, 0x2d, 0x46, 0x9e, 0x4b, 0x8b, 0x6d, 0x88, 0x45, 0x83, 0xf6, 0xa0, 0x39, 0xd5, 0x9a,
+	0x4d, 0xd5, 0xcd, 0x7d, 0x60, 0xec, 0xc1, 0xf9, 0xb4, 0xf7, 0xeb, 0x1a, 0xec, 0xe8, 0x1e, 0xf3,
+	0x95, 0x9d, 0xe4, 0xf2, 0xde, 0x45, 0xbb, 0xaf, 0x51, 0x71, 0xdf, 0x23, 0x68, 0x71, 0x92, 0xb2,
+	0x8c, 0x07, 0x44, 0x7b, 0xb6, 0x7d, 0x70, 0x27, 0xcf, 0x24, 0xa5, 0x0b, 0x9b, 0x59, 0x5c, 0xd2,
+	0x79, 0xff, 0x68, 0x42, 0xaf, 0x3a, 0x2b, 0x2b, 0xd6, 0x79, 0x74, 0x41, 0xd9, 0x0b, 0xdd, 0x1c,
+	0xd7, 0x94, 0x9b, 0x6c, 0x94, 0xcc, 0xaa, 0x20, 0xc9, 0x4e, 0x26, 0x3e, 0x27, 0xa9, 0x71, 0x63,
+	0x89, 0x30, 0xb3, 0x43, 0xc2, 0x29, 0xcb, 0x0f, 0xd3, 0x12, 0x21, 0xcb, 0x40, 0x90, 0x64, 0x5f,
+	0x64, 0x4c, 0xf8, 0xca, 0x48, 0x07, 0x17, 0xb0, 0xea, 0x8a, 0x93, 0x2c, 0x25, 0xe2, 0x50, 0xee,
+	0xda, 0x9a, 0xe9, 0x8a, 0x0b, 0x4c, 0x39, 0x7f, 0x4c, 0xa6, 0xa9, 0x49, 0x73, 0x0b, 0x23, 0x2d,
+	0xd7, 0xbb, 0xf9, 0x5c, 0x06, 0xb5, 0x0a, 0x0c, 0x07, 0xdb, 0x28, 0x29, 0x41, 0x83, 0x27, 0x57,
+	0x7e, 0xa2, 0xd2, 0xde, 0xc1, 0x16, 0x06, 0xbd, 0x07, 0x7d, 0x0d, 0x61, 0x92, 0x12, 0x7e, 0xe9,
+	0xcb, 0x63, 0x5b, 0x95, 0x01, 0x07, 0x2f, 0x4e, 0x48, 0xea, 0x0b, 0xc2, 0x63, 0x12, 0x1d, 0x5b,
+	0x5a, 0x41, 0x53, 0x2f, 0x4c, 0xa0, 0x03, 0xd8, 0xd6, 0xc8, 0xd3, 0xc3, 0xa1, 0xcd, 0xd0, 0x56,
+	0x0c, 0x4b, 0xe7, 0x64, 0xa6, 0x2b, 0xc7, 0x3f, 0x27, 0xfe, 0x4b, 0xb3, 0x1f, 0x1d, 0x45, 0x3e,
+	0x8f, 0x46, 0x4f, 0xa0, 0x6f, 0x6d, 0xd1, 0x33, 0x72, 0x49, 0x03, 0xe2, 0x76, 0x55, 0xd4, 0xde,
+	0x36, 0x51, 0x60, 0x4f, 0xe1, 0x45, 0x6a, 0x74, 0x06, 0x03, 0x85, 0x3c, 0x9d, 0x70, 0x26, 0x44,
+	0x44, 0x30, 0xf1, 0xc3, 0xa7, 0x49, 0x6a, 0x64, 0xf5, 0x94, 0xac, 0x3c, 0xa2, 0x72, 0x1a, 0x23,
+	0xed, 0x06, 0x46, 0xf4, 0x02, 0xde, 0xa8, 0xcc, 0xbe, 0xe0, 0x54, 0x90, 0x52, 0xee, 0xe6, 0x4d,
+	0x72, 0x6f, 0xe2, 0x5c, 0x10, 0x2c, 0xd5, 0x1e, 0xb1, 0x42, 0xf0, 0xd6, 0xeb, 0x0b, 0xae, 0x72,
+	0xa2, 0x9f, 0xc1, 0x9b, 0x8b, 0x7a, 0x2d, 0xc9, 0xfd, 0x9b, 0x24, 0xdf, 0xc8, 0x2a, 0x93, 0x43,
+	0xd6, 0x2f, 0xbd, 0xf3, 0x48, 0x27, 0x47, 0x81, 0x90, 0x01, 0x15, 0x24, 0x19, 0x26, 0x7e, 0x24,
+	0x4b, 0x99, 0x49, 0xa1, 0xdb, 0x3a, 0xa0, 0x16, 0x26, 0xd0, 0x3e, 0x20, 0x0b, 0x89, 0x4d, 0x39,
+	0xdc, 0xde, 0xad, 0xed, 0x35, 0xf0, 0x92, 0x19, 0xef, 0x23, 0xe8, 0x3e, 0x8d, 0x58, 0x70, 0x71,
+	0xf4, 0xb9, 0x31, 0xa6, 0x72, 0xa1, 0x6f, 0x2c, 0xbd, 0xd0, 0x37, 0xcc, 0x85, 0xde, 0xfb, 0x0a,
+	0x3a, 0x95, 0x60, 0xf9, 0x9e, 0xaa, 0x12, 0xb9, 0x28, 0x73, 0x4d, 0xdb, 0x36, 0x2e, 0xa9, 0xa8,
+	0xc1, 0x36, 0xa1, 0xac, 0x5e, 0x57, 0x3a, 0x90, 0x75, 0xeb, 0x6c, 0x20, 0x99, 0x99, 0x51, 0x19,
+	0xe4, 0xfa, 0x56, 0x66, 0x61, 0xbc, 0x9f, 0x43, 0xaf, 0xea, 0xe8, 0xff, 0xd8, 0x02, 0x04, 0x0e,
+	0xf7, 0x05, 0xc9, 0x7b, 0x7f, 0x39, 0xf6, 0xee, 0xc1, 0xdd, 0x85, 0x7a, 0x6c, 0x1a, 0xcb, 0x6b,
+	0xe8, 0x7e, 0x7c, 0x49, 0x62, 0x51, 0xdc, 0xfd, 0x1e, 0x43, 0xab, 0xf8, 0xa1, 0x62, 0x0a, 0xfd,
+	0x60, 0x5f, 0xff, 0x72, 0xd9, 0xcf, 0x7f, 0xb9, 0xec, 0x9f, 0xe6, 0x14, 0xb8, 0x24, 0x96, 0x6b,
+	0x4c, 0x05, 0xe3, 0x24, 0xfc, 0x3c, 0x8e, 0xae, 0xf3, 0xff, 0x14, 0x25, 0xc6, 0xd4, 0x7e, 0xa7,
+	0x68, 0xbd, 0x7e, 0x5b, 0x83, 0x35, 0xa5, 0x7b, 0xe9, 0x1d, 0x46, 0x53, 0xd7, 0x8b, 0x93, 0xa2,
+	0x7a, 0x2e, 0x74, 0x8b, 0x73, 0xc1, 0x9c, 0x20, 0x4e, 0x79, 0x82, 0x54, 0x56, 0xb0, 0xfe, 0x35,
+	0x56, 0xe0, 0xfd, 0xa6, 0x0e, 0x9d, 0xcf, 0x88, 0xb8, 0x62, 0xfc, 0x42, 0x9e, 0x96, 0xe9, 0xd2,
+	0xc6, 0xf8, 0x1e, 0x6c, 0xf0, 0xd9, 0xe8, 0xfc, 0x5a, 0x14, 0xa7, 0x43, 0x93, 0xcf, 0x9e, 0x4a,
+	0x10, 0xbd, 0x05, 0xc0, 0x67, 0xa3, 0xa1, 0xaf, 0x9b, 0x61, 0x73, 0x38, 0xf0, 0x99, 0x41, 0xa0,
+	0x37, 0xa0, 0x85, 0x67, 0x23, 0xc2, 0x39, 0xe3, 0x69, 0x7e, 0x3a, 0xe0, 0xd9, 0xc7, 0x0a, 0x96,
+	0xbc, 0x78, 0x36, 0x0a, 0x39, 0x4b, 0x12, 0x12, 0xaa, 0xd3, 0xc1, 0xc1, 0x2d, 0x3c, 0x7b, 0xa6,
+	0x11, 0x52, 0xeb, 0x69, 0xae, 0x75, 0x5d, 0x6b, 0x3d, 0x2d, 0xb5, 0x9e, 0xce, 0x46, 0x89, 0xd1,
+	0xaa, 0x8f, 0x85, 0xd6, 0xa9, 0xad, 0xf5, 0xb4, 0xd0, 0xaa, 0xcf, 0x84, 0x8d, 0x53, 0x4b, 0xeb,
+	0x69, 0xa9, 0xb5, 0x95, 0xf3, 0x1a, 0xad, 0xde, 0x1f, 0x6b, 0xb0, 0x71, 0x98, 0x64, 0x67, 0xa9,
+	0x3f, 0x26, 0xe8, 0x01, 0xb4, 0x05, 0x13, 0x7e, 0x34, 0xca, 0x24, 0x68, 0x4e, 0x4e, 0x50, 0x28,
+	0x4d, 0xf0, 0x36, 0x74, 0x12, 0xc2, 0x83, 0x24, 0x33, 0x14, 0xf5, 0xdd, 0x86, 0x3c, 0xa1, 0x34,
+	0x4e, 0x93, 0xec, 0xc3, 0x6d, 0x35, 0x37, 0xa2, 0xf1, 0x48, 0x1f, 0x09, 0x53, 0x16, 0x12, 0xe3,
+	0xaa, 0xbe, 0x9a, 0x3a, 0x8a, 0x3f, 0x2d, 0x26, 0xd0, 0xb7, 0xa1, 0x5f, 0xd0, 0xcb, 0x56, 0x59,
+	0x51, 0x6b, 0xd7, 0x6d, 0x1a, 0xea, 0x33, 0x83, 0xf6, 0xbe, 0x2a, 0x72, 0x88, 0xc6, 0xe3, 0x67,
+	0xbe, 0xf0, 0x65, 0x1b, 0x95, 0xa8, 0x62, 0x92, 0x1a, 0x6b, 0x73, 0x10, 0x7d, 0x07, 0xfa, 0xc2,
+	0xe4, 0x5b, 0x38, 0xca, 0x69, 0xf4, 0x6e, 0x6e, 0x15, 0x13, 0x43, 0x43, 0xfc, 0x0d, 0xe8, 0x95,
+	0xc4, 0xaa, 0x0a, 0x69, 0x7b, 0xbb, 0x05, 0x56, 0x46, 0x93, 0xf7, 0x7b, 0xed, 0x2c, 0x1d, 0x39,
+	0xef, 0xa9, 0x36, 0xc1, 0x72, 0x55, 0xfb, 0x60, 0x33, 0x6f, 0xaf, 0x8c, 0x33, 0x54, 0x6b, 0xa0,
+	0xdd, 0xf2, 0x43, 0xd8, 0x14, 0x85, 0xe9, 0xa3, 0xd0, 0x17, 0xbe, 0x49, 0xbd, 0xb9, 0x2a, 0x6c,
+	0x16, 0x86, 0x7b, 0xa2, 0xba, 0xd0, 0xb7, 0xa1, 0xa3, 0xfb, 0x7e, 0xa3, 0x50, 0xdb, 0xd7, 0xd6,
+	0x38, 0xa5, 0xc2, 0xfb, 0x08, 0x5a, 0x43, 0x1a, 0xa6, 0xda, 0x3a, 0x17, 0x9a, 0x41, 0xc6, 0x39,
+	0x89, 0xf3, 0x06, 0x28, 0x07, 0x65, 0x79, 0x54, 0x3d, 0xb3, 0x71, 0x86, 0x06, 0x3c, 0x06, 0xa0,
+	0xcf, 0x6d, 0xa5, 0x6d, 0x1b, 0xd6, 0xec, 0x10, 0xd0, 0x80, 0x8c, 0xb3, 0xa9, 0x3f, 0x2b, 0xb6,
+	0x5e, 0xc5, 0xd9, 0xd4, 0x9f, 0xe9, 0x05, 0xba, 0xd0, 0x7c, 0xe9, 0xd3, 0x28, 0x30, 0xbf, 0x03,
+	0x1d, 0x9c, 0x83, 0xa5, 0x42, 0xc7, 0x56, 0xf8, 0x87, 0x3a, 0xb4, 0xb5, 0x46, 0x6d, 0xf0, 0x36,
+	0xac, 0x05, 0x7e, 0x30, 0x29, 0x54, 0x2a, 0x00, 0xbd, 0x9b, 0x1b, 0x52, 0xfd, 0x0d, 0x50, 0x9a,
+	0x9a, 0xdb, 0xf6, 0x10, 0x20, 0xbd, 0xf2, 0x13, 0xcb, 0x3b, 0x4b, 0xa9, 0x5b, 0x92, 0x48, 0x1b,
+	0xfc, 0x01, 0x74, 0x74, 0x7c, 0x1a, 0x1e, 0x67, 0x15, 0x4f, 0x5b, 0x93, 0x69, 0xae, 0x47, 0xf2,
+	0xca, 0xe5, 0x0b, 0xdd, 0xe2, 0xb7, 0x0f, 0xde, 0xaa, 0x90, 0xab, 0x95, 0xec, 0xab, 0xef, 0xc7,
+	0xb1, 0xe0, 0xd7, 0x58, 0xd3, 0x0e, 0x1e, 0x03, 0x94, 0x48, 0x59, 0xcf, 0x2e, 0xc8, 0x75, 0x7e,
+	0xb5, 0xbc, 0x20, 0xd7, 0x72, 0xed, 0x97, 0x7e, 0x94, 0xe5, 0x4e, 0xd5, 0xc0, 0x0f, 0xea, 0x8f,
+	0x6b, 0x5e, 0x00, 0x9b, 0x4f, 0xe5, 0x71, 0x6c, 0xb1, 0x57, 0x0e, 0x3d, 0x67, 0xe9, 0xa1, 0xe7,
+	0xe4, 0x7f, 0xb1, 0x7b, 0x50, 0x67, 0x89, 0x69, 0xb3, 0xeb, 0x2c, 0x29, 0x15, 0x39, 0x96, 0x22,
+	0xef, 0xef, 0x0e, 0x40, 0xa9, 0x05, 0x9d, 0xc0, 0x80, 0xb2, 0x91, 0xec, 0x12, 0x69, 0x40, 0x74,
+	0x41, 0x1a, 0x71, 0x12, 0x64, 0x3c, 0xa5, 0x97, 0xc4, 0x5c, 0x24, 0x76, 0x8a, 0x63, 0xaa, 0x62,
+	0x1c, 0xbe, 0x4b, 0xd9, 0x89, 0x66, 0x54, 0x95, 0x0b, 0xe7, 0x6c, 0xe8, 0x27, 0x70, 0xa7, 0x14,
+	0x1a, 0x5a, 0xf2, 0xea, 0x37, 0xca, 0xbb, 0x5d, 0xc8, 0x0b, 0x4b, 0x59, 0x3f, 0x82, 0xdb, 0x94,
+	0x8d, 0xbe, 0xcc, 0x48, 0x56, 0x91, 0xd4, 0xb8, 0x51, 0x52, 0x9f, 0xb2, 0x2f, 0x14, 0x47, 0x29,
+	0xe7, 0x0b, 0xb8, 0x67, 0x2d, 0x54, 0xa6, 0xbd, 0x25, 0xcd, 0xb9, 0x51, 0xda, 0x4e, 0x61, 0x97,
+	0x2c, 0x0c, 0xa5, 0xc8, 0x4f, 0x61, 0x87, 0xb2, 0xd1, 0x95, 0x4f, 0xc5, 0xbc, 0xbc, 0xb5, 0x57,
+	0xad, 0xf3, 0x85, 0x4f, 0x45, 0x55, 0x98, 0x5e, 0xe7, 0x94, 0xf0, 0x71, 0x65, 0x9d, 0xeb, 0xaf,
+	0x5a, 0xe7, 0xb1, 0xe2, 0x28, 0xe5, 0x3c, 0x85, 0x3e, 0x65, 0xf3, 0xf6, 0x34, 0x6f, 0x94, 0xb2,
+	0x49, 0x59, 0xd5, 0x96, 0x43, 0xe8, 0xa7, 0x24, 0x10, 0x8c, 0xdb, 0xb1, 0xb0, 0x71, 0xa3, 0x8c,
+	0x2d, 0xc3, 0x50, 0x08, 0xf1, 0xbe, 0x84, 0xce, 0x8f, 0xb3, 0x31, 0x11, 0xd1, 0x79, 0x91, 0xf3,
+	0xff, 0xed, 0x32, 0xf3, 0xaf, 0x3a, 0xb4, 0x0f, 0xc7, 0x9c, 0x65, 0x49, 0xa5, 0x6a, 0xeb, 0x1c,
+	0x5e, 0xa8, 0xda, 0x8a, 0x46, 0x55, 0x6d, 0x4d, 0xfd, 0x21, 0x74, 0xf4, 0xad, 0xc9, 0x30, 0xe8,
+	0x2a, 0x84, 0x16, 0x93, 0x3e, 0xbf, 0xa5, 0x69, 0xb6, 0x03, 0x73, 0x03, 0x35, 0x5c, 0xd5, 0x6a,
+	0x54, 0xba, 0x09, 0xc3, 0x79, 0x99, 0x75, 0x47, 0xd0, 0x9d, 0x68, 0xdf, 0x18, 0x2e, 0x1d, 0x80,
+	0xef, 0xe4, 0xc6, 0x95, 0x6b, 0xd8, 0xb7, 0x7d, 0xa8, 0x5d, 0xdd, 0x99, 0xd8, 0x6e, 0x7d, 0x1f,
+	0x40, 0xb6, 0xe4, 0xa3, 0xbc, 0x50, 0xd9, 0x0f, 0x10, 0xc5, 0x09, 0xa1, 0xdb, 0x76, 0x35, 0x1c,
+	0x9c, 0x42, 0x7f, 0x41, 0xe6, 0x92, 0x32, 0xf5, 0x2d, 0xbb, 0x4c, 0x95, 0xd7, 0x32, 0x9b, 0xd5,
+	0xae, 0x5d, 0x7f, 0xa9, 0xe9, 0x5f, 0x12, 0xe5, 0x3f, 0xe2, 0xc7, 0xd0, 0x8d, 0x75, 0xf3, 0x55,
+	0x6c, 0x80, 0x7d, 0xbf, 0xb3, 0x1b, 0x33, 0xdc, 0x89, 0xed, 0x36, 0xed, 0x43, 0xe8, 0x04, 0xca,
+	0x03, 0x4b, 0x37, 0xc2, 0x72, 0x0e, 0x6e, 0x07, 0xd6, 0x6e, 0x57, 0x1a, 0x45, 0xe7, 0xeb, 0x34,
+	0x8a, 0xe6, 0xaf, 0xe2, 0xaa, 0x07, 0x93, 0x83, 0x7f, 0xae, 0x43, 0xe3, 0xc9, 0xf0, 0x08, 0x9d,
+	0xc1, 0xd6, 0xfc, 0x7b, 0x23, 0xba, 0x6f, 0xcc, 0x5a, 0xf1, 0x46, 0x39, 0x78, 0xb0, 0x72, 0xde,
+	0xb4, 0xec, 0xb7, 0x10, 0x86, 0xcd, 0xb9, 0xd7, 0x25, 0x94, 0x1f, 0x35, 0xcb, 0x5f, 0xf0, 0x06,
+	0xf7, 0x57, 0x4d, 0xdb, 0x32, 0xe7, 0xee, 0x08, 0x85, 0xcc, 0xe5, 0xff, 0x72, 0x0a, 0x99, 0xab,
+	0xae, 0x16, 0xb7, 0xd0, 0xf7, 0x61, 0x5d, 0xbf, 0x37, 0xa1, 0xfc, 0xe2, 0x52, 0x79, 0xc9, 0x1a,
+	0xdc, 0x99, 0xc3, 0x16, 0x8c, 0xcf, 0xa1, 0x5b, 0x79, 0xa4, 0x44, 0x6f, 0x54, 0x74, 0x55, 0x9f,
+	0xab, 0x06, 0x6f, 0x2e, 0x9f, 0x2c, 0xa4, 0x1d, 0x02, 0x94, 0x4f, 0x12, 0xc8, 0x35, 0xd4, 0x0b,
+	0xcf, 0x5e, 0x83, 0x7b, 0x4b, 0x66, 0x0a, 0x21, 0x67, 0xb0, 0x35, 0xff, 0x3c, 0x80, 0xe6, 0xbc,
+	0x3a, 0xff, 0x73, 0xbe, 0xd8, 0xca, 0x95, 0xef, 0x0a, 0x4a, 0xec, 0xfc, 0x4f, 0xff, 0x42, 0xec,
+	0x8a, 0x27, 0x87, 0x42, 0xec, 0xca, 0xd7, 0x82, 0x5b, 0xe8, 0x73, 0xe8, 0x55, 0xff, 0xa2, 0xa3,
+	0xdc, 0x49, 0x4b, 0x9f, 0x11, 0x06, 0x6f, 0xad, 0x98, 0x2d, 0x04, 0x7e, 0x00, 0x6b, 0xfa, 0xf7,
+	0x78, 0x9e, 0x8e, 0xf6, 0x5f, 0xf5, 0xc1, 0x76, 0x15, 0x59, 0x70, 0x3d, 0x84, 0x75, 0x7d, 0xbb,
+	0x2c, 0x02, 0xa0, 0x72, 0xd9, 0x1c, 0x74, 0x6c, 0xac, 0x77, 0xeb, 0x61, 0x2d, 0xd7, 0x93, 0x56,
+	0xf4, 0xa4, 0xcb, 0xf4, 0x58, 0x9b, 0x73, 0xbe, 0xae, 0xd2, 0xf5, 0xd1, 0xbf, 0x03, 0x00, 0x00,
+	0xff, 0xff, 0x8c, 0xbd, 0xc2, 0x0b, 0x2e, 0x20, 0x00, 0x00,
 }
diff --git a/vendor/github.com/containerd/containerd/api/grpc/types/api.proto b/vendor/github.com/containerd/containerd/api/grpc/types/api.proto
index 902f6c1..e9a6d10 100644
--- a/vendor/github.com/containerd/containerd/api/grpc/types/api.proto
+++ b/vendor/github.com/containerd/containerd/api/grpc/types/api.proto
@@ -211,6 +211,8 @@
 	repeated ThrottleDevice blkioThrottleReadIopsDevice = 16;
 	repeated ThrottleDevice blkioThrottleWriteIopsDevice = 17;
 	uint64 pidsLimit = 18;
+	uint64 cpuRealtimePeriod = 19;
+	int64 cpuRealtimeRuntime = 20;
 }
 
 message BlockIODevice {
diff --git a/vendor/github.com/containerd/containerd/runtime/container.go b/vendor/github.com/containerd/containerd/runtime/container.go
index 43351ca..9e1d24f 100644
--- a/vendor/github.com/containerd/containerd/runtime/container.go
+++ b/vendor/github.com/containerd/containerd/runtime/container.go
@@ -12,9 +12,9 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/containerd/containerd/specs"
 	ocs "github.com/opencontainers/runtime-spec/specs-go"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/sys/unix"
 )
@@ -434,7 +434,7 @@
 		c:           c,
 		stdio:       s,
 		spec:        spec,
-		processSpec: specs.ProcessSpec(spec.Process),
+		processSpec: specs.ProcessSpec(*spec.Process),
 	}
 	p, err := newProcess(config)
 	if err != nil {
@@ -544,7 +544,6 @@
 	case err := <-ch:
 		return err
 	}
-	return nil
 }
 
 func hostIDFromMap(id uint32, mp []ocs.LinuxIDMapping) int {
diff --git a/vendor/github.com/containerd/containerd/runtime/container_linux.go b/vendor/github.com/containerd/containerd/runtime/container_linux.go
index 9f3526a..265a38c 100644
--- a/vendor/github.com/containerd/containerd/runtime/container_linux.go
+++ b/vendor/github.com/containerd/containerd/runtime/container_linux.go
@@ -112,18 +112,20 @@
 func (c *container) UpdateResources(r *Resource) error {
 	sr := ocs.LinuxResources{
 		Memory: &ocs.LinuxMemory{
-			Limit:       u64Ptr(uint64(r.Memory)),
-			Reservation: u64Ptr(uint64(r.MemoryReservation)),
-			Swap:        u64Ptr(uint64(r.MemorySwap)),
-			Kernel:      u64Ptr(uint64(r.KernelMemory)),
-			KernelTCP:   u64Ptr(uint64(r.KernelTCPMemory)),
+			Limit:       i64Ptr(r.Memory),
+			Reservation: i64Ptr(r.MemoryReservation),
+			Swap:        i64Ptr(r.MemorySwap),
+			Kernel:      i64Ptr(r.KernelMemory),
+			KernelTCP:   i64Ptr(r.KernelTCPMemory),
 		},
 		CPU: &ocs.LinuxCPU{
-			Shares: u64Ptr(uint64(r.CPUShares)),
-			Quota:  i64Ptr(int64(r.CPUQuota)),
-			Period: u64Ptr(uint64(r.CPUPeriod)),
-			Cpus:   r.CpusetCpus,
-			Mems:   r.CpusetMems,
+			Shares:          u64Ptr(uint64(r.CPUShares)),
+			Quota:           i64Ptr(int64(r.CPUQuota)),
+			Period:          u64Ptr(uint64(r.CPUPeriod)),
+			Cpus:            r.CpusetCpus,
+			Mems:            r.CpusetMems,
+			RealtimePeriod:  u64Ptr(uint64(r.CPURealtimePeriod)),
+			RealtimeRuntime: i64Ptr(int64(r.CPURealtimdRuntime)),
 		},
 		BlockIO: &ocs.LinuxBlockIO{
 			Weight: &r.BlkioWeight,
diff --git a/vendor/github.com/containerd/containerd/runtime/process.go b/vendor/github.com/containerd/containerd/runtime/process.go
index 22d0192..903e831 100644
--- a/vendor/github.com/containerd/containerd/runtime/process.go
+++ b/vendor/github.com/containerd/containerd/runtime/process.go
@@ -14,9 +14,9 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/containerd/containerd/osutils"
 	"github.com/containerd/containerd/specs"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 )
 
@@ -233,7 +233,7 @@
 	p.stateLock.Lock()
 	p.state = Stopped
 	p.stateLock.Unlock()
-	err := ioutil.WriteFile(filepath.Join(p.root, ExitStatusFile), []byte(fmt.Sprintf("%u", status)), 0644)
+	err := ioutil.WriteFile(filepath.Join(p.root, ExitStatusFile), []byte(fmt.Sprintf("%d", status)), 0644)
 	return status, err
 }
 
@@ -262,10 +262,27 @@
 		}
 		if ppid == "1" {
 			logrus.Warnf("containerd: %s:%s shim died, killing associated process", p.container.id, p.id)
+			// Before sending SIGKILL to container, we need to make sure
+			// the container is not in Paused state. If the container is
+			// Paused, the container will not response to any signal
+			// we should Resume it after sending SIGKILL
+			var (
+				s    State
+				err1 error
+			)
+			if p.container != nil {
+				s, err1 = p.container.Status()
+			}
+
 			unix.Kill(p.pid, syscall.SIGKILL)
 			if err != nil && err != syscall.ESRCH {
 				return UnknownStatus, fmt.Errorf("containerd: unable to SIGKILL %s:%s (pid %v): %v", p.container.id, p.id, p.pid, err)
 			}
+			if p.container != nil {
+				if err1 == nil && s == Paused {
+					p.container.Resume()
+				}
+			}
 
 			// wait for the process to die
 			for {
@@ -283,14 +300,23 @@
 		return rst, rerr
 	}
 
-	// Possible that the shim was SIGKILLED
-	e := unix.Kill(p.cmd.Process.Pid, 0)
-	if e != syscall.ESRCH {
-		return rst, rerr
+	// The shim was SIGKILLED
+	// We should get the container state first
+	// to make sure the container is not in
+	// Pause state, if it's Paused, we should resume it
+	// and it will exit immediately because shim will send sigkill to
+	// container when died.
+	s, err1 := p.container.Status()
+	if err1 == nil && s == Paused {
+		p.container.Resume()
 	}
 
 	// Ensure we got the shim ProcessState
-	<-p.cmdDoneCh
+	select {
+	case <-p.cmdDoneCh:
+	case <-time.After(2 * time.Minute):
+		return rst, fmt.Errorf("could not get the shim ProcessState within two minutes")
+	}
 
 	shimStatus := p.cmd.ProcessState.Sys().(syscall.WaitStatus)
 	if shimStatus.Signaled() && shimStatus.Signal() == syscall.SIGKILL {
diff --git a/vendor/github.com/containerd/containerd/runtime/runtime.go b/vendor/github.com/containerd/containerd/runtime/runtime.go
index eaba452..f702487 100644
--- a/vendor/github.com/containerd/containerd/runtime/runtime.go
+++ b/vendor/github.com/containerd/containerd/runtime/runtime.go
@@ -84,18 +84,20 @@
 
 // Resource regroups the various container limits that can be updated
 type Resource struct {
-	CPUShares         int64
-	BlkioWeight       uint16
-	CPUPeriod         int64
-	CPUQuota          int64
-	CpusetCpus        string
-	CpusetMems        string
-	KernelMemory      int64
-	KernelTCPMemory   int64
-	Memory            int64
-	MemoryReservation int64
-	MemorySwap        int64
-	PidsLimit         int64
+	CPUShares          int64
+	BlkioWeight        uint16
+	CPUPeriod          int64
+	CPUQuota           int64
+	CpusetCpus         string
+	CpusetMems         string
+	KernelMemory       int64
+	KernelTCPMemory    int64
+	Memory             int64
+	MemoryReservation  int64
+	MemorySwap         int64
+	PidsLimit          int64
+	CPURealtimePeriod  uint64
+	CPURealtimdRuntime int64
 }
 
 // Possible container states
diff --git a/vendor/github.com/containerd/containerd/specs/spec_linux.go b/vendor/github.com/containerd/containerd/specs/spec_linux.go
index 0b31604..d415c1d 100644
--- a/vendor/github.com/containerd/containerd/specs/spec_linux.go
+++ b/vendor/github.com/containerd/containerd/specs/spec_linux.go
@@ -8,5 +8,5 @@
 	// Spec aliases the platform oci spec
 	Spec oci.Spec
 	// Rlimit aliases the platform resource limit
-	Rlimit oci.LinuxRlimit
+	Rlimit oci.POSIXRlimit
 )
diff --git a/vendor/github.com/containerd/containerd/vendor.conf b/vendor/github.com/containerd/containerd/vendor.conf
new file mode 100755
index 0000000..734f696
--- /dev/null
+++ b/vendor/github.com/containerd/containerd/vendor.conf
@@ -0,0 +1,33 @@
+github.com/sirupsen/logrus v1.0.1
+github.com/cloudfoundry/gosigar 3ed7c74352dae6dc00bdc8c74045375352e3ec05
+github.com/urfave/cli 8ba6f23b6e36d03666a14bd9421f5e3efcb59aca
+github.com/coreos/go-systemd 7b2428fec40033549c68f54e26e89e7ca9a9ce31
+github.com/cyberdelia/go-metrics-graphite 7e54b5c2aa6eaff4286c44129c3def899dff528c
+github.com/docker/docker f577caff19d486d8d01443507d891cb1b0891cdc
+github.com/docker/go-units 5d2041e26a699eaca682e2ea41c8f891e1060444
+github.com/godbus/dbus e2cf28118e66a6a63db46cf6088a35d2054d3bb0
+github.com/golang/glog 23def4e6c14b4da8ac2ed8007337bc5eb5007998
+github.com/golang/protobuf 8ee79997227bf9b34611aee7946ae64735e6fd93
+github.com/opencontainers/runc d40db12e72a40109dfcf28539f5ee0930d2f0277
+github.com/opencontainers/runtime-spec v1.0.0
+github.com/rcrowley/go-metrics eeba7bd0dd01ace6e690fa833b3f22aaec29af43
+github.com/satori/go.uuid f9ab0dce87d815821e221626b772e3475a0d2749
+github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852
+github.com/vishvananda/netlink adb0f53af689dd38f1443eba79489feaacf0b22e
+github.com/Azure/go-ansiterm 70b2c90b260171e829f1ebd7c17f600c11858dbe
+golang.org/x/net 991d3e32f76f19ee6d9caadb3a22eae8d23315f7 https://github.com/golang/net.git
+golang.org/x/sys 0e0164865330d5cf1c00247be08330bf96e2f87c https://github.com/golang/sys
+google.golang.org/grpc v1.0.4 https://github.com/grpc/grpc-go.git
+github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1
+github.com/tonistiigi/fifo b45391ebcd3d282404092c04a2b015b37df12383
+github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
+
+github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
+github.com/go-check/check a625211d932a2a643d0d17352095f03fb7774663 https://github.com/cpuguy83/check.git
+
+github.com/containerd/console a3863895279f5104533fd999c1babf80faffd98c
+github.com/containerd/go-runc 5fe4d8cb7fdc0fae5f5a7f4f1d65a565032401b2
+
+# dependencies of docker/pkg/listeners
+github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
+github.com/Microsoft/go-winio v0.3.2
diff --git a/vendor/github.com/stevvooe/continuity/LICENSE b/vendor/github.com/containerd/continuity/LICENSE
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/LICENSE
rename to vendor/github.com/containerd/continuity/LICENSE
diff --git a/vendor/github.com/containerd/continuity/README.md b/vendor/github.com/containerd/continuity/README.md
new file mode 100644
index 0000000..0e91ce0
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/README.md
@@ -0,0 +1,74 @@
+# continuity
+
+[![GoDoc](https://godoc.org/github.com/containerd/continuity?status.svg)](https://godoc.org/github.com/containerd/continuity)
+[![Build Status](https://travis-ci.org/containerd/continuity.svg?branch=master)](https://travis-ci.org/containerd/continuity)
+
+A transport-agnostic, filesystem metadata manifest system
+
+This project is a staging area for experiments in providing transport agnostic
+metadata storage.
+
+Please see https://github.com/opencontainers/specs/issues/11 for more details.
+
+## Manifest Format
+
+A continuity manifest encodes filesystem metadata in Protocol Buffers.
+Please refer to [proto/manifest.proto](proto/manifest.proto).
+
+## Usage
+
+Build:
+
+```console
+$ make
+```
+
+Create a manifest (of this repo itself):
+
+```console
+$ ./bin/continuity build . > /tmp/a.pb
+```
+
+Dump a manifest:
+
+```console
+$ ./bin/continuity ls /tmp/a.pb
+...
+-rw-rw-r--      270 B   /.gitignore
+-rw-rw-r--      88 B    /.mailmap
+-rw-rw-r--      187 B   /.travis.yml
+-rw-rw-r--      359 B   /AUTHORS
+-rw-rw-r--      11 kB   /LICENSE
+-rw-rw-r--      1.5 kB  /Makefile
+...
+-rw-rw-r--      986 B   /testutil_test.go
+drwxrwxr-x      0 B     /version
+-rw-rw-r--      478 B   /version/version.go
+```
+
+Verify a manifest:
+
+```console
+$ ./bin/continuity verify . /tmp/a.pb
+```
+
+Break the directory and restore using the manifest:
+```console
+$ chmod 777 Makefile
+$ ./bin/continuity verify . /tmp/a.pb
+2017/06/23 08:00:34 error verifying manifest: resource "/Makefile" has incorrect mode: -rwxrwxrwx != -rw-rw-r--
+$ ./bin/continuity apply . /tmp/a.pb
+$ stat -c %a Makefile
+664
+$ ./bin/continuity verify . /tmp/a.pb
+```
+
+
+## Contribution Guide
+### Building Proto Package
+
+If you change the proto file you will need to rebuild the generated Go with `go generate`.
+
+```console
+$ go generate ./proto
+```
diff --git a/vendor/github.com/containerd/continuity/devices/devices.go b/vendor/github.com/containerd/continuity/devices/devices.go
new file mode 100644
index 0000000..7086407
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices.go
@@ -0,0 +1,5 @@
+package devices
+
+import "fmt"
+
+var ErrNotSupported = fmt.Errorf("not supported")
diff --git a/vendor/github.com/containerd/continuity/devices/devices_darwin.go b/vendor/github.com/containerd/continuity/devices/devices_darwin.go
new file mode 100644
index 0000000..5041e66
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices_darwin.go
@@ -0,0 +1,15 @@
+package devices
+
+// from /usr/include/sys/types.h
+
+func getmajor(dev int32) uint64 {
+	return (uint64(dev) >> 24) & 0xff
+}
+
+func getminor(dev int32) uint64 {
+	return uint64(dev) & 0xffffff
+}
+
+func makedev(major int, minor int) int {
+	return ((major << 24) | minor)
+}
diff --git a/vendor/github.com/containerd/continuity/devices/devices_dummy.go b/vendor/github.com/containerd/continuity/devices/devices_dummy.go
new file mode 100644
index 0000000..9a48330
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices_dummy.go
@@ -0,0 +1,23 @@
+// +build solaris,!cgo
+
+//
+// Implementing the functions below requires cgo support.  Non-cgo stubs
+// versions are defined below to enable cross-compilation of source code
+// that depends on these functions, but the resultant cross-compiled
+// binaries cannot actually be used.  If the stub function(s) below are
+// actually invoked they will cause the calling process to exit.
+//
+
+package devices
+
+func getmajor(dev uint64) uint64 {
+	panic("getmajor() support requires cgo.")
+}
+
+func getminor(dev uint64) uint64 {
+	panic("getminor() support requires cgo.")
+}
+
+func makedev(major int, minor int) int {
+	panic("makedev() support requires cgo.")
+}
diff --git a/vendor/github.com/containerd/continuity/devices/devices_freebsd.go b/vendor/github.com/containerd/continuity/devices/devices_freebsd.go
new file mode 100644
index 0000000..a5c7b93
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices_freebsd.go
@@ -0,0 +1,15 @@
+package devices
+
+// from /usr/include/sys/types.h
+
+func getmajor(dev uint32) uint64 {
+	return (uint64(dev) >> 24) & 0xff
+}
+
+func getminor(dev uint32) uint64 {
+	return uint64(dev) & 0xffffff
+}
+
+func makedev(major int, minor int) int {
+	return ((major << 24) | minor)
+}
diff --git a/vendor/github.com/containerd/continuity/devices/devices_linux.go b/vendor/github.com/containerd/continuity/devices/devices_linux.go
new file mode 100644
index 0000000..454cf66
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices_linux.go
@@ -0,0 +1,15 @@
+package devices
+
+// from /usr/include/linux/kdev_t.h
+
+func getmajor(dev uint64) uint64 {
+	return dev >> 8
+}
+
+func getminor(dev uint64) uint64 {
+	return dev & 0xff
+}
+
+func makedev(major int, minor int) int {
+	return ((major << 8) | minor)
+}
diff --git a/vendor/github.com/containerd/continuity/devices/devices_solaris.go b/vendor/github.com/containerd/continuity/devices/devices_solaris.go
new file mode 100644
index 0000000..8819ac8
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices_solaris.go
@@ -0,0 +1,18 @@
+// +build cgo
+
+package devices
+
+//#include <sys/mkdev.h>
+import "C"
+
+func getmajor(dev uint64) uint64 {
+	return uint64(C.major(C.dev_t(dev)))
+}
+
+func getminor(dev uint64) uint64 {
+	return uint64(C.minor(C.dev_t(dev)))
+}
+
+func makedev(major int, minor int) int {
+	return int(C.makedev(C.major_t(major), C.minor_t(minor)))
+}
diff --git a/vendor/github.com/containerd/continuity/devices/devices_unix.go b/vendor/github.com/containerd/continuity/devices/devices_unix.go
new file mode 100644
index 0000000..85e9a68
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices_unix.go
@@ -0,0 +1,55 @@
+// +build linux darwin freebsd solaris
+
+package devices
+
+import (
+	"fmt"
+	"os"
+	"syscall"
+)
+
+func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
+	sys, ok := fi.Sys().(*syscall.Stat_t)
+	if !ok {
+		return 0, 0, fmt.Errorf("cannot extract device from os.FileInfo")
+	}
+
+	return getmajor(sys.Rdev), getminor(sys.Rdev), nil
+}
+
+// mknod provides a shortcut for syscall.Mknod
+func Mknod(p string, mode os.FileMode, maj, min int) error {
+	var (
+		m   = syscallMode(mode.Perm())
+		dev int
+	)
+
+	if mode&os.ModeDevice != 0 {
+		dev = makedev(maj, min)
+
+		if mode&os.ModeCharDevice != 0 {
+			m |= syscall.S_IFCHR
+		} else {
+			m |= syscall.S_IFBLK
+		}
+	} else if mode&os.ModeNamedPipe != 0 {
+		m |= syscall.S_IFIFO
+	}
+
+	return syscall.Mknod(p, m, dev)
+}
+
+// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
+func syscallMode(i os.FileMode) (o uint32) {
+	o |= uint32(i.Perm())
+	if i&os.ModeSetuid != 0 {
+		o |= syscall.S_ISUID
+	}
+	if i&os.ModeSetgid != 0 {
+		o |= syscall.S_ISGID
+	}
+	if i&os.ModeSticky != 0 {
+		o |= syscall.S_ISVTX
+	}
+	return
+}
diff --git a/vendor/github.com/containerd/continuity/devices/devices_windows.go b/vendor/github.com/containerd/continuity/devices/devices_windows.go
new file mode 100644
index 0000000..6099d1d
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/devices/devices_windows.go
@@ -0,0 +1,11 @@
+package devices
+
+import (
+	"os"
+
+	"github.com/pkg/errors"
+)
+
+func DeviceInfo(fi os.FileInfo) (uint64, uint64, error) {
+	return 0, 0, errors.Wrap(ErrNotSupported, "cannot get device info on windows")
+}
diff --git a/vendor/github.com/containerd/continuity/driver/driver.go b/vendor/github.com/containerd/continuity/driver/driver.go
new file mode 100644
index 0000000..aa1dd7d
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/driver/driver.go
@@ -0,0 +1,162 @@
+package driver
+
+import (
+	"fmt"
+	"io"
+	"os"
+)
+
+var ErrNotSupported = fmt.Errorf("not supported")
+
+// Driver provides all of the system-level functions in a common interface.
+// The context should call these with full paths and should never use the `os`
+// package or any other package to access resources on the filesystem. This
+// mechanism let's us carefully control access to the context and maintain
+// path and resource integrity. It also gives us an interface to reason about
+// direct resource access.
+//
+// Implementations don't need to do much other than meet the interface. For
+// example, it is not required to wrap os.FileInfo to return correct paths for
+// the call to Name().
+type Driver interface {
+	// Note that Open() returns a File interface instead of *os.File. This
+	// is because os.File is a struct, so if Open was to return *os.File,
+	// the only way to fulfill the interface would be to call os.Open()
+	Open(path string) (File, error)
+	OpenFile(path string, flag int, perm os.FileMode) (File, error)
+
+	Stat(path string) (os.FileInfo, error)
+	Lstat(path string) (os.FileInfo, error)
+	Readlink(p string) (string, error)
+	Mkdir(path string, mode os.FileMode) error
+	Remove(path string) error
+
+	Link(oldname, newname string) error
+	Lchmod(path string, mode os.FileMode) error
+	Lchown(path string, uid, gid int64) error
+	Symlink(oldname, newname string) error
+
+	MkdirAll(path string, perm os.FileMode) error
+	RemoveAll(path string) error
+
+	// TODO(aaronl): These methods might move outside the main Driver
+	// interface in the future as more platforms are added.
+	Mknod(path string, mode os.FileMode, major int, minor int) error
+	Mkfifo(path string, mode os.FileMode) error
+}
+
+// File is the interface for interacting with files returned by continuity's Open
+// This is needed since os.File is a struct, instead of an interface, so it can't
+// be used.
+type File interface {
+	io.ReadWriteCloser
+	io.Seeker
+	Readdir(n int) ([]os.FileInfo, error)
+}
+
+func NewSystemDriver() (Driver, error) {
+	// TODO(stevvooe): Consider having this take a "hint" path argument, which
+	// would be the context root. The hint could be used to resolve required
+	// filesystem support when assembling the driver to use.
+	return &driver{}, nil
+}
+
+// XAttrDriver should be implemented on operation systems and filesystems that
+// have xattr support for regular files and directories.
+type XAttrDriver interface {
+	// Getxattr returns all of the extended attributes for the file at path.
+	// Typically, this takes a syscall call to Listxattr and Getxattr.
+	Getxattr(path string) (map[string][]byte, error)
+
+	// Setxattr sets all of the extended attributes on file at path, following
+	// any symbolic links, if necessary. All attributes on the target are
+	// replaced by the values from attr. If the operation fails to set any
+	// attribute, those already applied will not be rolled back.
+	Setxattr(path string, attr map[string][]byte) error
+}
+
+// LXAttrDriver should be implemented by drivers on operating systems and
+// filesystems that support setting and getting extended attributes on
+// symbolic links. If this is not implemented, extended attributes will be
+// ignored on symbolic links.
+type LXAttrDriver interface {
+	// LGetxattr returns all of the extended attributes for the file at path
+	// and does not follow symlinks. Typically, this takes a syscall call to
+	// Llistxattr and Lgetxattr.
+	LGetxattr(path string) (map[string][]byte, error)
+
+	// LSetxattr sets all of the extended attributes on file at path, without
+	// following symbolic links. All attributes on the target are replaced by
+	// the values from attr. If the operation fails to set any attribute,
+	// those already applied will not be rolled back.
+	LSetxattr(path string, attr map[string][]byte) error
+}
+
+type DeviceInfoDriver interface {
+	DeviceInfo(fi os.FileInfo) (maj uint64, min uint64, err error)
+}
+
+// driver is a simple default implementation that sends calls out to the "os"
+// package. Extend the "driver" type in system-specific files to add support,
+// such as xattrs, which can add support at compile time.
+type driver struct{}
+
+var _ File = &os.File{}
+
+// LocalDriver is the exported Driver struct for convenience.
+var LocalDriver Driver = &driver{}
+
+func (d *driver) Open(p string) (File, error) {
+	return os.Open(p)
+}
+
+func (d *driver) OpenFile(path string, flag int, perm os.FileMode) (File, error) {
+	return os.OpenFile(path, flag, perm)
+}
+
+func (d *driver) Stat(p string) (os.FileInfo, error) {
+	return os.Stat(p)
+}
+
+func (d *driver) Lstat(p string) (os.FileInfo, error) {
+	return os.Lstat(p)
+}
+
+func (d *driver) Readlink(p string) (string, error) {
+	return os.Readlink(p)
+}
+
+func (d *driver) Mkdir(p string, mode os.FileMode) error {
+	return os.Mkdir(p, mode)
+}
+
+// Remove is used to unlink files and remove directories.
+// This is following the golang os package api which
+// combines the operations into a higher level Remove
+// function. If explicit unlinking or directory removal
+// to mirror system call is required, they should be
+// split up at that time.
+func (d *driver) Remove(path string) error {
+	return os.Remove(path)
+}
+
+func (d *driver) Link(oldname, newname string) error {
+	return os.Link(oldname, newname)
+}
+
+func (d *driver) Lchown(name string, uid, gid int64) error {
+	// TODO: error out if uid excesses int bit width?
+	return os.Lchown(name, int(uid), int(gid))
+}
+
+func (d *driver) Symlink(oldname, newname string) error {
+	return os.Symlink(oldname, newname)
+}
+
+func (d *driver) MkdirAll(path string, perm os.FileMode) error {
+	return os.MkdirAll(path, perm)
+}
+
+func (d *driver) RemoveAll(path string) error {
+	return os.RemoveAll(path)
+}
diff --git a/vendor/github.com/containerd/continuity/driver/driver_unix.go b/vendor/github.com/containerd/continuity/driver/driver_unix.go
new file mode 100644
index 0000000..d9ab165
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/driver/driver_unix.go
@@ -0,0 +1,122 @@
+// +build linux darwin freebsd solaris
+
+package driver
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"path/filepath"
+	"sort"
+
+	"github.com/containerd/continuity/devices"
+	"github.com/containerd/continuity/sysx"
+)
+
+func (d *driver) Mknod(path string, mode os.FileMode, major, minor int) error {
+	return devices.Mknod(path, mode, major, minor)
+}
+
+func (d *driver) Mkfifo(path string, mode os.FileMode) error {
+	if mode&os.ModeNamedPipe == 0 {
+		return errors.New("mode passed to Mkfifo does not have the named pipe bit set")
+	}
+	// mknod with a mode that has ModeNamedPipe set creates a fifo, not a
+	// device.
+	return devices.Mknod(path, mode, 0, 0)
+}
+
+// Lchmod changes the mode of an file not following symlinks.
+func (d *driver) Lchmod(path string, mode os.FileMode) (err error) {
+	if !filepath.IsAbs(path) {
+		path, err = filepath.Abs(path)
+		if err != nil {
+			return
+		}
+	}
+
+	return sysx.Fchmodat(0, path, uint32(mode), sysx.AtSymlinkNofollow)
+}
+
+// Getxattr returns all of the extended attributes for the file at path p.
+func (d *driver) Getxattr(p string) (map[string][]byte, error) {
+	xattrs, err := sysx.Listxattr(p)
+	if err != nil {
+		return nil, fmt.Errorf("listing %s xattrs: %v", p, err)
+	}
+
+	sort.Strings(xattrs)
+	m := make(map[string][]byte, len(xattrs))
+
+	for _, attr := range xattrs {
+		value, err := sysx.Getxattr(p, attr)
+		if err != nil {
+			return nil, fmt.Errorf("getting %q xattr on %s: %v", attr, p, err)
+		}
+
+		// NOTE(stevvooe): This append/copy tricky relies on unique
+		// xattrs. Break this out into an alloc/copy if xattrs are no
+		// longer unique.
+		m[attr] = append(m[attr], value...)
+	}
+
+	return m, nil
+}
+
+// Setxattr sets all of the extended attributes on file at path, following
+// any symbolic links, if necessary. All attributes on the target are
+// replaced by the values from attr. If the operation fails to set any
+// attribute, those already applied will not be rolled back.
+func (d *driver) Setxattr(path string, attrMap map[string][]byte) error {
+	for attr, value := range attrMap {
+		if err := sysx.Setxattr(path, attr, value, 0); err != nil {
+			return fmt.Errorf("error setting xattr %q on %s: %v", attr, path, err)
+		}
+	}
+
+	return nil
+}
+
+// LGetxattr returns all of the extended attributes for the file at path p
+// not following symbolic links.
+func (d *driver) LGetxattr(p string) (map[string][]byte, error) {
+	xattrs, err := sysx.LListxattr(p)
+	if err != nil {
+		return nil, fmt.Errorf("listing %s xattrs: %v", p, err)
+	}
+
+	sort.Strings(xattrs)
+	m := make(map[string][]byte, len(xattrs))
+
+	for _, attr := range xattrs {
+		value, err := sysx.LGetxattr(p, attr)
+		if err != nil {
+			return nil, fmt.Errorf("getting %q xattr on %s: %v", attr, p, err)
+		}
+
+		// NOTE(stevvooe): This append/copy tricky relies on unique
+		// xattrs. Break this out into an alloc/copy if xattrs are no
+		// longer unique.
+		m[attr] = append(m[attr], value...)
+	}
+
+	return m, nil
+}
+
+// LSetxattr sets all of the extended attributes on file at path, not
+// following any symbolic links. All attributes on the target are
+// replaced by the values from attr. If the operation fails to set any
+// attribute, those already applied will not be rolled back.
+func (d *driver) LSetxattr(path string, attrMap map[string][]byte) error {
+	for attr, value := range attrMap {
+		if err := sysx.LSetxattr(path, attr, value, 0); err != nil {
+			return fmt.Errorf("error setting xattr %q on %s: %v", attr, path, err)
+		}
+	}
+
+	return nil
+}
+
+func (d *driver) DeviceInfo(fi os.FileInfo) (maj uint64, min uint64, err error) {
+	return devices.DeviceInfo(fi)
+}
diff --git a/vendor/github.com/containerd/continuity/driver/driver_windows.go b/vendor/github.com/containerd/continuity/driver/driver_windows.go
new file mode 100644
index 0000000..e4cfa64
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/driver/driver_windows.go
@@ -0,0 +1,21 @@
+package driver
+
+import (
+	"os"
+
+	"github.com/pkg/errors"
+)
+
+func (d *driver) Mknod(path string, mode os.FileMode, major, minor int) error {
+	return errors.Wrap(ErrNotSupported, "cannot create device node on Windows")
+}
+
+func (d *driver) Mkfifo(path string, mode os.FileMode) error {
+	return errors.Wrap(ErrNotSupported, "cannot create fifo on Windows")
+}
+
+// Lchmod changes the mode of an file not following symlinks.
+func (d *driver) Lchmod(path string, mode os.FileMode) (err error) {
+	// TODO: Use Window's equivalent
+	return os.Chmod(path, mode)
+}
diff --git a/vendor/github.com/containerd/continuity/driver/utils.go b/vendor/github.com/containerd/continuity/driver/utils.go
new file mode 100644
index 0000000..9e0edd7
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/driver/utils.go
@@ -0,0 +1,74 @@
+package driver
+
+import (
+	"io"
+	"io/ioutil"
+	"os"
+	"sort"
+)
+
+// ReadFile works the same as ioutil.ReadFile with the Driver abstraction
+func ReadFile(r Driver, filename string) ([]byte, error) {
+	f, err := r.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	data, err := ioutil.ReadAll(f)
+	if err != nil {
+		return nil, err
+	}
+
+	return data, nil
+}
+
+// WriteFile works the same as ioutil.WriteFile with the Driver abstraction
+func WriteFile(r Driver, filename string, data []byte, perm os.FileMode) error {
+	f, err := r.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	n, err := f.Write(data)
+	if err != nil {
+		return err
+	} else if n != len(data) {
+		return io.ErrShortWrite
+	}
+
+	return nil
+}
+
+// ReadDir works the same as ioutil.ReadDir with the Driver abstraction
+func ReadDir(r Driver, dirname string) ([]os.FileInfo, error) {
+	f, err := r.Open(dirname)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+
+	dirs, err := f.Readdir(-1)
+	if err != nil {
+		return nil, err
+	}
+
+	sort.Sort(fileInfos(dirs))
+	return dirs, nil
+}
+
+// Simple implementation of the sort.Interface for os.FileInfo
+type fileInfos []os.FileInfo
+
+func (fis fileInfos) Len() int {
+	return len(fis)
+}
+
+func (fis fileInfos) Less(i, j int) bool {
+	return fis[i].Name() < fis[j].Name()
+}
+
+func (fis fileInfos) Swap(i, j int) {
+	fis[i], fis[j] = fis[j], fis[i]
+}
diff --git a/vendor/github.com/containerd/continuity/pathdriver/path_driver.go b/vendor/github.com/containerd/continuity/pathdriver/path_driver.go
new file mode 100644
index 0000000..b43d55f
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/pathdriver/path_driver.go
@@ -0,0 +1,85 @@
+package pathdriver
+
+import (
+	"path/filepath"
+)
+
+// PathDriver provides all of the path manipulation functions in a common
+// interface. The context should call these and never use the `filepath`
+// package or any other package to manipulate paths.
+type PathDriver interface {
+	Join(paths ...string) string
+	IsAbs(path string) bool
+	Rel(base, target string) (string, error)
+	Base(path string) string
+	Dir(path string) string
+	Clean(path string) string
+	Split(path string) (dir, file string)
+	Separator() byte
+	Abs(path string) (string, error)
+	Walk(string, filepath.WalkFunc) error
+	FromSlash(path string) string
+	ToSlash(path string) string
+	Match(pattern, name string) (matched bool, err error)
+}
+
+// pathDriver is a simple default implementation calls the filepath package.
+type pathDriver struct{}
+
+// LocalPathDriver is the exported pathDriver struct for convenience.
+var LocalPathDriver PathDriver = &pathDriver{}
+
+func (*pathDriver) Join(paths ...string) string {
+	return filepath.Join(paths...)
+}
+
+func (*pathDriver) IsAbs(path string) bool {
+	return filepath.IsAbs(path)
+}
+
+func (*pathDriver) Rel(base, target string) (string, error) {
+	return filepath.Rel(base, target)
+}
+
+func (*pathDriver) Base(path string) string {
+	return filepath.Base(path)
+}
+
+func (*pathDriver) Dir(path string) string {
+	return filepath.Dir(path)
+}
+
+func (*pathDriver) Clean(path string) string {
+	return filepath.Clean(path)
+}
+
+func (*pathDriver) Split(path string) (dir, file string) {
+	return filepath.Split(path)
+}
+
+func (*pathDriver) Separator() byte {
+	return filepath.Separator
+}
+
+func (*pathDriver) Abs(path string) (string, error) {
+	return filepath.Abs(path)
+}
+
+// Note that filepath.Walk calls os.Stat, so if the context wants to
+// to call Driver.Stat() for Walk, they need to create a new struct that
+// overrides this method.
+func (*pathDriver) Walk(root string, walkFn filepath.WalkFunc) error {
+	return filepath.Walk(root, walkFn)
+}
+
+func (*pathDriver) FromSlash(path string) string {
+	return filepath.FromSlash(path)
+}
+
+func (*pathDriver) ToSlash(path string) string {
+	return filepath.ToSlash(path)
+}
+
+func (*pathDriver) Match(pattern, name string) (bool, error) {
+	return filepath.Match(pattern, name)
+}
diff --git a/vendor/github.com/stevvooe/continuity/sysx/asm.s b/vendor/github.com/containerd/continuity/sysx/asm.s
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/asm.s
rename to vendor/github.com/containerd/continuity/sysx/asm.s
diff --git a/vendor/github.com/stevvooe/continuity/sysx/chmod_darwin.go b/vendor/github.com/containerd/continuity/sysx/chmod_darwin.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/chmod_darwin.go
rename to vendor/github.com/containerd/continuity/sysx/chmod_darwin.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/chmod_darwin_386.go b/vendor/github.com/containerd/continuity/sysx/chmod_darwin_386.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/chmod_darwin_386.go
rename to vendor/github.com/containerd/continuity/sysx/chmod_darwin_386.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/chmod_darwin_amd64.go b/vendor/github.com/containerd/continuity/sysx/chmod_darwin_amd64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/chmod_darwin_amd64.go
rename to vendor/github.com/containerd/continuity/sysx/chmod_darwin_amd64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/chmod_freebsd.go b/vendor/github.com/containerd/continuity/sysx/chmod_freebsd.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/chmod_freebsd.go
rename to vendor/github.com/containerd/continuity/sysx/chmod_freebsd.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/chmod_freebsd_amd64.go b/vendor/github.com/containerd/continuity/sysx/chmod_freebsd_amd64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/chmod_freebsd_amd64.go
rename to vendor/github.com/containerd/continuity/sysx/chmod_freebsd_amd64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/chmod_linux.go b/vendor/github.com/containerd/continuity/sysx/chmod_linux.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/chmod_linux.go
rename to vendor/github.com/containerd/continuity/sysx/chmod_linux.go
diff --git a/vendor/github.com/containerd/continuity/sysx/chmod_solaris.go b/vendor/github.com/containerd/continuity/sysx/chmod_solaris.go
new file mode 100644
index 0000000..3ba6e5e
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/sysx/chmod_solaris.go
@@ -0,0 +1,11 @@
+package sysx
+
+import "golang.org/x/sys/unix"
+
+const (
+	AtSymlinkNofollow = unix.AT_SYMLINK_NOFOLLOW
+)
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
+	return unix.Fchmodat(dirfd, path, mode, flags)
+}
diff --git a/vendor/github.com/stevvooe/continuity/sysx/copy_linux.go b/vendor/github.com/containerd/continuity/sysx/copy_linux.go
similarity index 78%
rename from vendor/github.com/stevvooe/continuity/sysx/copy_linux.go
rename to vendor/github.com/containerd/continuity/sysx/copy_linux.go
index d7ccbb2..4d85812 100644
--- a/vendor/github.com/stevvooe/continuity/sysx/copy_linux.go
+++ b/vendor/github.com/containerd/continuity/sysx/copy_linux.go
@@ -5,5 +5,7 @@
 //    $ GOOS=linux GOARCH=amd64 ./generate.sh copy
 //    $ GOOS=linux GOARCH=arm ./generate.sh copy
 //    $ GOOS=linux GOARCH=arm64 ./generate.sh copy
+//    $ GOOS=linux GOARCH=ppc64le ./generate.sh copy
+//    $ GOOS=linux GOARCH=s390x ./generate.sh copy
 
 //sys CopyFileRange(fdin uintptr, offin *int64, fdout uintptr, offout *int64, len int, flags int) (n int, err error)
diff --git a/vendor/github.com/stevvooe/continuity/sysx/copy_linux_386.go b/vendor/github.com/containerd/continuity/sysx/copy_linux_386.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/copy_linux_386.go
rename to vendor/github.com/containerd/continuity/sysx/copy_linux_386.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/copy_linux_amd64.go b/vendor/github.com/containerd/continuity/sysx/copy_linux_amd64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/copy_linux_amd64.go
rename to vendor/github.com/containerd/continuity/sysx/copy_linux_amd64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/copy_linux_arm.go b/vendor/github.com/containerd/continuity/sysx/copy_linux_arm.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/copy_linux_arm.go
rename to vendor/github.com/containerd/continuity/sysx/copy_linux_arm.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/copy_linux_arm64.go b/vendor/github.com/containerd/continuity/sysx/copy_linux_arm64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/copy_linux_arm64.go
rename to vendor/github.com/containerd/continuity/sysx/copy_linux_arm64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/copy_linux_amd64.go b/vendor/github.com/containerd/continuity/sysx/copy_linux_ppc64le.go
similarity index 100%
copy from vendor/github.com/stevvooe/continuity/sysx/copy_linux_amd64.go
copy to vendor/github.com/containerd/continuity/sysx/copy_linux_ppc64le.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/copy_linux_amd64.go b/vendor/github.com/containerd/continuity/sysx/copy_linux_s390x.go
similarity index 100%
copy from vendor/github.com/stevvooe/continuity/sysx/copy_linux_amd64.go
copy to vendor/github.com/containerd/continuity/sysx/copy_linux_s390x.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/nodata_linux.go b/vendor/github.com/containerd/continuity/sysx/nodata_linux.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/nodata_linux.go
rename to vendor/github.com/containerd/continuity/sysx/nodata_linux.go
diff --git a/vendor/github.com/containerd/continuity/sysx/nodata_solaris.go b/vendor/github.com/containerd/continuity/sysx/nodata_solaris.go
new file mode 100644
index 0000000..53cc8e0
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/sysx/nodata_solaris.go
@@ -0,0 +1,8 @@
+package sysx
+
+import (
+	"syscall"
+)
+
+// This should actually be a set that contains ENOENT and EPERM
+const ENODATA = syscall.ENOENT
diff --git a/vendor/github.com/stevvooe/continuity/sysx/nodata_unix.go b/vendor/github.com/containerd/continuity/sysx/nodata_unix.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/nodata_unix.go
rename to vendor/github.com/containerd/continuity/sysx/nodata_unix.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/sys.go b/vendor/github.com/containerd/continuity/sysx/sys.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/sys.go
rename to vendor/github.com/containerd/continuity/sysx/sys.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_386.go b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_386.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_386.go
rename to vendor/github.com/containerd/continuity/sysx/sysnum_linux_386.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_amd64.go b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_amd64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_amd64.go
rename to vendor/github.com/containerd/continuity/sysx/sysnum_linux_amd64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_arm.go b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_arm.go
rename to vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_arm64.go b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/sysnum_linux_arm64.go
rename to vendor/github.com/containerd/continuity/sysx/sysnum_linux_arm64.go
diff --git a/vendor/github.com/containerd/continuity/sysx/sysnum_linux_ppc64le.go b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_ppc64le.go
new file mode 100644
index 0000000..5dea25a
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_ppc64le.go
@@ -0,0 +1,7 @@
+package sysx
+
+const (
+	// SYS_COPYFILERANGE defined in Kernel 4.5+
+	// Number defined in /usr/include/asm/unistd_64.h
+	SYS_COPY_FILE_RANGE = 379
+)
diff --git a/vendor/github.com/containerd/continuity/sysx/sysnum_linux_s390x.go b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_s390x.go
new file mode 100644
index 0000000..8a6f2a7
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/sysx/sysnum_linux_s390x.go
@@ -0,0 +1,7 @@
+package sysx
+
+const (
+	// SYS_COPYFILERANGE defined in Kernel 4.5+
+	// Number defined in /usr/include/asm/unistd_64.h
+	SYS_COPY_FILE_RANGE = 375
+)
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr.go b/vendor/github.com/containerd/continuity/sysx/xattr.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr.go
rename to vendor/github.com/containerd/continuity/sysx/xattr.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_darwin.go b/vendor/github.com/containerd/continuity/sysx/xattr_darwin.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_darwin.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_darwin.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_darwin_386.go b/vendor/github.com/containerd/continuity/sysx/xattr_darwin_386.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_darwin_386.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_darwin_386.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_darwin_amd64.go b/vendor/github.com/containerd/continuity/sysx/xattr_darwin_amd64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_darwin_amd64.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_darwin_amd64.go
diff --git a/vendor/github.com/containerd/continuity/sysx/xattr_freebsd.go b/vendor/github.com/containerd/continuity/sysx/xattr_freebsd.go
new file mode 100644
index 0000000..e8017d3
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/sysx/xattr_freebsd.go
@@ -0,0 +1,12 @@
+package sysx
+
+import (
+	"errors"
+)
+
+// Initial stub version for FreeBSD. FreeBSD has a different
+// syscall API from Darwin and Linux for extended attributes;
+// it is also not widely used. It is not exposed at all by the
+// Go syscall package, so we need to implement directly eventually.
+
+var unsupported = errors.New("extended attributes unsupported on FreeBSD")
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux_386.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux_386.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux_386.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux_386.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux_amd64.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux_amd64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux_amd64.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux_amd64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux_arm.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux_arm.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux_arm.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux_arm.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux_arm64.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux_arm64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux_arm64.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux_arm64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux_ppc64.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux_ppc64.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux_ppc64.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux_ppc64.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux_ppc64le.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux_ppc64le.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux_ppc64le.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux_ppc64le.go
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_linux_s390x.go b/vendor/github.com/containerd/continuity/sysx/xattr_linux_s390x.go
similarity index 100%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_linux_s390x.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_linux_s390x.go
diff --git a/vendor/github.com/containerd/continuity/sysx/xattr_solaris.go b/vendor/github.com/containerd/continuity/sysx/xattr_solaris.go
new file mode 100644
index 0000000..fc523fc
--- /dev/null
+++ b/vendor/github.com/containerd/continuity/sysx/xattr_solaris.go
@@ -0,0 +1,12 @@
+package sysx
+
+import (
+	"errors"
+)
+
+// Initial stub version for Solaris. Solaris has a different
+// syscall API from Darwin and Linux for extended attributes;
+// it is also not widely used. It is not exposed at all by the
+// Go syscall package, so we need to implement directly eventually.
+
+var unsupported = errors.New("extended attributes unsupported on Solaris")
diff --git a/vendor/github.com/stevvooe/continuity/sysx/xattr_freebsd.go b/vendor/github.com/containerd/continuity/sysx/xattr_unsupported.go
similarity index 73%
rename from vendor/github.com/stevvooe/continuity/sysx/xattr_freebsd.go
rename to vendor/github.com/containerd/continuity/sysx/xattr_unsupported.go
index 80dba49..a8dd9f2 100644
--- a/vendor/github.com/stevvooe/continuity/sysx/xattr_freebsd.go
+++ b/vendor/github.com/containerd/continuity/sysx/xattr_unsupported.go
@@ -1,16 +1,7 @@
+// +build freebsd solaris
+
 package sysx
 
-import (
-	"errors"
-)
-
-// Initial stub version for FreeBSD. FreeBSD has a different
-// syscall API from Darwin and Linux for extended attributes;
-// it is also not widely used. It is not exposed at all by the
-// Go syscall package, so we need to implement directly eventually.
-
-var unsupported error = errors.New("extended attributes unsupported on FreeBSD")
-
 // Listxattr calls syscall listxattr and reads all content
 // and returns a string array
 func Listxattr(path string) ([]string, error) {
@@ -29,7 +20,7 @@
 
 // Getxattr calls syscall getxattr
 func Getxattr(path, attr string) ([]byte, error) {
-	return []byte{}, nil
+	return []byte{}, unsupported
 }
 
 // LListxattr lists xattrs, not following symlinks
diff --git a/vendor/github.com/docker/distribution/README.md b/vendor/github.com/docker/distribution/README.md
index a6e8db0..9988788 100644
--- a/vendor/github.com/docker/distribution/README.md
+++ b/vendor/github.com/docker/distribution/README.md
@@ -76,8 +76,7 @@
 For those who have previously deployed their own registry based on the Registry
 1.0 implementation and wish to deploy a Registry 2.0 while retaining images,
 data migration is required. A tool to assist with migration efforts has been
-created. For more information see [docker/migrator]
-(https://github.com/docker/migrator).
+created. For more information see [docker/migrator](https://github.com/docker/migrator).
 
 ## Contribute
 
diff --git a/vendor/github.com/docker/distribution/blobs.go b/vendor/github.com/docker/distribution/blobs.go
index 79c5fb3..01d3090 100644
--- a/vendor/github.com/docker/distribution/blobs.go
+++ b/vendor/github.com/docker/distribution/blobs.go
@@ -152,7 +152,7 @@
 
 // BlobServer can serve blobs via http.
 type BlobServer interface {
-	// ServeBlob attempts to serve the blob, identifed by dgst, via http. The
+	// ServeBlob attempts to serve the blob, identified by dgst, via http. The
 	// service may decide to redirect the client elsewhere or serve the data
 	// directly.
 	//
diff --git a/vendor/github.com/docker/distribution/context/doc.go b/vendor/github.com/docker/distribution/context/doc.go
index 3b4ab88..9b62307 100644
--- a/vendor/github.com/docker/distribution/context/doc.go
+++ b/vendor/github.com/docker/distribution/context/doc.go
@@ -64,7 +64,7 @@
 // Note that this only affects the new context, the previous context, with the
 // version field, can be used independently. Put another way, the new logger,
 // added to the request context, is unique to that context and can have
-// request scoped varaibles.
+// request scoped variables.
 //
 // HTTP Requests
 //
diff --git a/vendor/github.com/docker/distribution/context/http.go b/vendor/github.com/docker/distribution/context/http.go
index 7fe9b8a..7d65c85 100644
--- a/vendor/github.com/docker/distribution/context/http.go
+++ b/vendor/github.com/docker/distribution/context/http.go
@@ -8,9 +8,9 @@
 	"sync"
 	"time"
 
-	log "github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/uuid"
 	"github.com/gorilla/mux"
+	log "github.com/sirupsen/logrus"
 )
 
 // Common errors used with this package.
diff --git a/vendor/github.com/docker/distribution/context/logger.go b/vendor/github.com/docker/distribution/context/logger.go
index fbb6a05..86c5964 100644
--- a/vendor/github.com/docker/distribution/context/logger.go
+++ b/vendor/github.com/docker/distribution/context/logger.go
@@ -3,7 +3,7 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"runtime"
 )
 
diff --git a/vendor/github.com/docker/distribution/errors.go b/vendor/github.com/docker/distribution/errors.go
index 2062a06..020d332 100644
--- a/vendor/github.com/docker/distribution/errors.go
+++ b/vendor/github.com/docker/distribution/errors.go
@@ -77,7 +77,7 @@
 type ErrManifestUnverified struct{}
 
 func (ErrManifestUnverified) Error() string {
-	return fmt.Sprintf("unverified manifest")
+	return "unverified manifest"
 }
 
 // ErrManifestVerification provides a type to collect errors encountered
diff --git a/vendor/github.com/docker/distribution/manifest/manifestlist/manifestlist.go b/vendor/github.com/docker/distribution/manifest/manifestlist/manifestlist.go
index 7a8cabb..3aa0662 100644
--- a/vendor/github.com/docker/distribution/manifest/manifestlist/manifestlist.go
+++ b/vendor/github.com/docker/distribution/manifest/manifestlist/manifestlist.go
@@ -81,7 +81,7 @@
 	Manifests []ManifestDescriptor `json:"manifests"`
 }
 
-// References returnes the distribution descriptors for the referenced image
+// References returns the distribution descriptors for the referenced image
 // manifests.
 func (m ManifestList) References() []distribution.Descriptor {
 	dependencies := make([]distribution.Descriptor, len(m.Manifests))
diff --git a/vendor/github.com/docker/distribution/manifest/schema1/verify.go b/vendor/github.com/docker/distribution/manifest/schema1/verify.go
index fa8daa5..ef59065 100644
--- a/vendor/github.com/docker/distribution/manifest/schema1/verify.go
+++ b/vendor/github.com/docker/distribution/manifest/schema1/verify.go
@@ -3,8 +3,8 @@
 import (
 	"crypto/x509"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libtrust"
+	"github.com/sirupsen/logrus"
 )
 
 // Verify verifies the signature of the signed manifest returning the public
diff --git a/vendor/github.com/docker/distribution/reference/reference.go b/vendor/github.com/docker/distribution/reference/reference.go
index fd3510e..2f66cca 100644
--- a/vendor/github.com/docker/distribution/reference/reference.go
+++ b/vendor/github.com/docker/distribution/reference/reference.go
@@ -15,7 +15,7 @@
 //	tag                             := /[\w][\w.-]{0,127}/
 //
 //	digest                          := digest-algorithm ":" digest-hex
-//	digest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]
+//	digest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
 //	digest-algorithm-separator      := /[+.-_]/
 //	digest-algorithm-component      := /[A-Za-z][A-Za-z0-9]*/
 //	digest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
diff --git a/vendor/github.com/docker/distribution/registry/api/v2/urls.go b/vendor/github.com/docker/distribution/registry/api/v2/urls.go
index e2e242e..1337bdb 100644
--- a/vendor/github.com/docker/distribution/registry/api/v2/urls.go
+++ b/vendor/github.com/docker/distribution/registry/api/v2/urls.go
@@ -1,10 +1,9 @@
 package v2
 
 import (
-	"net"
+	"fmt"
 	"net/http"
 	"net/url"
-	"strconv"
 	"strings"
 
 	"github.com/docker/distribution/reference"
@@ -48,66 +47,42 @@
 // NewURLBuilderFromRequest uses information from an *http.Request to
 // construct the root url.
 func NewURLBuilderFromRequest(r *http.Request, relative bool) *URLBuilder {
-	var scheme string
-
-	forwardedProto := r.Header.Get("X-Forwarded-Proto")
-	// TODO: log the error
-	forwardedHeader, _, _ := parseForwardedHeader(r.Header.Get("Forwarded"))
-
-	switch {
-	case len(forwardedProto) > 0:
-		scheme = forwardedProto
-	case len(forwardedHeader["proto"]) > 0:
-		scheme = forwardedHeader["proto"]
-	case r.TLS != nil:
-		scheme = "https"
-	case len(r.URL.Scheme) > 0:
-		scheme = r.URL.Scheme
-	default:
+	var (
 		scheme = "http"
+		host   = r.Host
+	)
+
+	if r.TLS != nil {
+		scheme = "https"
+	} else if len(r.URL.Scheme) > 0 {
+		scheme = r.URL.Scheme
 	}
 
-	host := r.Host
-
-	if forwardedHost := r.Header.Get("X-Forwarded-Host"); len(forwardedHost) > 0 {
-		// According to the Apache mod_proxy docs, X-Forwarded-Host can be a
-		// comma-separated list of hosts, to which each proxy appends the
-		// requested host. We want to grab the first from this comma-separated
-		// list.
-		hosts := strings.SplitN(forwardedHost, ",", 2)
-		host = strings.TrimSpace(hosts[0])
-	} else if addr, exists := forwardedHeader["for"]; exists {
-		host = addr
-	} else if h, exists := forwardedHeader["host"]; exists {
-		host = h
-	}
-
-	portLessHost, port := host, ""
-	if !isIPv6Address(portLessHost) {
-		// with go 1.6, this would treat the last part of IPv6 address as a port
-		portLessHost, port, _ = net.SplitHostPort(host)
-	}
-	if forwardedPort := r.Header.Get("X-Forwarded-Port"); len(port) == 0 && len(forwardedPort) > 0 {
-		ports := strings.SplitN(forwardedPort, ",", 2)
-		forwardedPort = strings.TrimSpace(ports[0])
-		if _, err := strconv.ParseInt(forwardedPort, 10, 32); err == nil {
-			port = forwardedPort
+	// Handle fowarded headers
+	// Prefer "Forwarded" header as defined by rfc7239 if given
+	// see https://tools.ietf.org/html/rfc7239
+	if forwarded := r.Header.Get("Forwarded"); len(forwarded) > 0 {
+		forwardedHeader, _, err := parseForwardedHeader(forwarded)
+		if err == nil {
+			if fproto := forwardedHeader["proto"]; len(fproto) > 0 {
+				scheme = fproto
+			}
+			if fhost := forwardedHeader["host"]; len(fhost) > 0 {
+				host = fhost
+			}
 		}
-	}
-
-	if len(portLessHost) > 0 {
-		host = portLessHost
-	}
-	if len(port) > 0 {
-		// remove enclosing brackets of ipv6 address otherwise they will be duplicated
-		if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
-			host = host[1 : len(host)-1]
+	} else {
+		if forwardedProto := r.Header.Get("X-Forwarded-Proto"); len(forwardedProto) > 0 {
+			scheme = forwardedProto
 		}
-		// JoinHostPort properly encloses ipv6 addresses in square brackets
-		host = net.JoinHostPort(host, port)
-	} else if isIPv6Address(host) && host[0] != '[' {
-		// ipv6 needs to be enclosed in square brackets in urls
-		host = "[" + host + "]"
+		if forwardedHost := r.Header.Get("X-Forwarded-Host"); len(forwardedHost) > 0 {
+			// According to the Apache mod_proxy docs, X-Forwarded-Host can be a
+			// comma-separated list of hosts, to which each proxy appends the
+			// requested host. We want to grab the first from this comma-separated
+			// list.
+			hosts := strings.SplitN(forwardedHost, ",", 2)
+			host = strings.TrimSpace(hosts[0])
+		}
 	}
 
 	basePath := routeDescriptorsMap[RouteNameBase].Path
@@ -175,6 +150,8 @@
 		tagOrDigest = v.Tag()
 	case reference.Digested:
 		tagOrDigest = v.Digest().String()
+	default:
+		return "", fmt.Errorf("reference must have a tag or digest")
 	}
 
 	manifestURL, err := route.URL("name", ref.Name(), "reference", tagOrDigest)
@@ -287,28 +264,3 @@
 
 	return appendValuesURL(up, values...).String()
 }
-
-// isIPv6Address returns true if given string is a valid IPv6 address. No port is allowed. The address may be
-// enclosed in square brackets.
-func isIPv6Address(host string) bool {
-	if len(host) > 1 && host[0] == '[' && host[len(host)-1] == ']' {
-		host = host[1 : len(host)-1]
-	}
-	// The IPv6 scoped addressing zone identifier starts after the last percent sign.
-	if i := strings.LastIndexByte(host, '%'); i > 0 {
-		host = host[:i]
-	}
-	ip := net.ParseIP(host)
-	if ip == nil {
-		return false
-	}
-	if ip.To16() == nil {
-		return false
-	}
-	if ip.To4() == nil {
-		return true
-	}
-	// dot can be present in ipv4-mapped address, it needs to come after a colon though
-	i := strings.IndexAny(host, ":.")
-	return i >= 0 && host[i] == ':'
-}
diff --git a/vendor/github.com/docker/distribution/registry/client/auth/session.go b/vendor/github.com/docker/distribution/registry/client/auth/session.go
index 3ca5e8b..be474d8 100644
--- a/vendor/github.com/docker/distribution/registry/client/auth/session.go
+++ b/vendor/github.com/docker/distribution/registry/client/auth/session.go
@@ -10,10 +10,10 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/distribution/registry/client"
 	"github.com/docker/distribution/registry/client/auth/challenge"
 	"github.com/docker/distribution/registry/client/transport"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/vendor/github.com/docker/distribution/vendor.conf b/vendor/github.com/docker/distribution/vendor.conf
index 443b4bc..d67edd7 100644
--- a/vendor/github.com/docker/distribution/vendor.conf
+++ b/vendor/github.com/docker/distribution/vendor.conf
@@ -1,19 +1,21 @@
-github.com/Azure/azure-sdk-for-go c6f0533defaaaa26ea4dff3c9774e36033088112
-github.com/Sirupsen/logrus d26492970760ca5d33129d2d799e34be5c4782eb
+github.com/Azure/azure-sdk-for-go 088007b3b08cc02b27f2eadfdcd870958460ce7e
+github.com/Azure/go-autorest ec5f4903f77ed9927ac95b19ab8e44ada64c1356
+github.com/sirupsen/logrus 3d4380f53a34dcdc95f0c1db702615992b38d9a4
 github.com/aws/aws-sdk-go c6fc52983ea2375810aa38ddb5370e9cdf611716
-github.com/bshuster-repo/logrus-logstash-hook 5f729f2fb50a301153cae84ff5c58981d51c095a
+github.com/bshuster-repo/logrus-logstash-hook d2c0ecc1836d91814e15e23bb5dc309c3ef51f4a
 github.com/bugsnag/bugsnag-go b1d153021fcd90ca3f080db36bec96dc690fb274
 github.com/bugsnag/osext 0dd3f918b21bec95ace9dc86c7e70266cfc5c702
 github.com/bugsnag/panicwrap e2c28503fcd0675329da73bf48b33404db873782
 github.com/denverdino/aliyungo afedced274aa9a7fcdd47ac97018f0f8db4e5de2
+github.com/dgrijalva/jwt-go a601269ab70c205d26370c16f7c81e9017c14e04
 github.com/docker/goamz f0a21f5b2e12f83a505ecf79b633bb2035cf6f85
 github.com/docker/libtrust fa567046d9b14f6aa788882a950d69651d230b21
 github.com/garyburd/redigo 535138d7bcd717d6531c701ef5933d98b1866257
 github.com/go-ini/ini 2ba15ac2dc9cdf88c110ec2dc0ced7fa45f5678c
-github.com/golang/protobuf/proto 8d92cf5fc15a4382f8964b08e1f42a75c0591aa3
+github.com/golang/protobuf 8d92cf5fc15a4382f8964b08e1f42a75c0591aa3
 github.com/gorilla/context 14f550f51af52180c2eefed15e5fd18d63c0a64a
 github.com/gorilla/handlers 60c7bfde3e33c201519a200a4507a158cc03a17b
-github.com/gorilla/mux e444e69cbd2e2e3e0749a2f3c717cec491552bbf
+github.com/gorilla/mux 599cba5e7b6137d46ddf58fb1765f5d928e69604
 github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
 github.com/jmespath/go-jmespath bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
 github.com/miekg/dns 271c58e0c14f552178ea321a545ff9af38930f39
@@ -21,15 +23,15 @@
 github.com/ncw/swift b964f2ca856aac39885e258ad25aec08d5f64ee6
 github.com/spf13/cobra 312092086bed4968099259622145a0c9ae280064
 github.com/spf13/pflag 5644820622454e71517561946e3d94b9f9db6842
-github.com/stevvooe/resumable 51ad44105773cafcbe91927f70ac68e1bf78f8b4
-github.com/xenolf/lego/acme a9d8cec0e6563575e5868a005359ac97911b5985
+github.com/stevvooe/resumable 2aaf90b2ceea5072cb503ef2a620b08ff3119870
+github.com/xenolf/lego a9d8cec0e6563575e5868a005359ac97911b5985
 github.com/yvasiyarov/go-metrics 57bccd1ccd43f94bb17fdd8bf3007059b802f85e
 github.com/yvasiyarov/gorelic a9bba5b9ab508a086f9a12b8c51fab68478e2128
 github.com/yvasiyarov/newrelic_platform_go b21fdbd4370f3717f3bbd2bf41c223bc273068e6
 golang.org/x/crypto c10c31b5e94b6f7a0283272dc2bb27163dcea24b
 golang.org/x/net 4876518f9e71663000c348837735820161a42df7
 golang.org/x/oauth2 045497edb6234273d67dbc25da3f2ddbc4c4cacf
-golang.org/x/time/rate a4bde12657593d5e90d0533a3e4fd95e635124cb
+golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
 google.golang.org/api 9bf6e6e569ff057f75d9604a46c52928f17d2b54
 google.golang.org/appengine 12d5545dc1cfa6047a286d5e853841b6471f4c19
 google.golang.org/cloud 975617b05ea8a58727e6c1a06b6161ff4185a9f2
diff --git a/vendor/github.com/docker/go-events/broadcast.go b/vendor/github.com/docker/go-events/broadcast.go
index ee0a894..5120078 100644
--- a/vendor/github.com/docker/go-events/broadcast.go
+++ b/vendor/github.com/docker/go-events/broadcast.go
@@ -4,7 +4,7 @@
 	"fmt"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // Broadcaster sends events to multiple, reliable Sinks. The goal of this
@@ -160,7 +160,7 @@
 	}
 }
 
-func (b Broadcaster) String() string {
+func (b *Broadcaster) String() string {
 	// Serialize copy of this broadcaster without the sync.Once, to avoid
 	// a data race.
 
diff --git a/vendor/github.com/docker/go-events/channel.go b/vendor/github.com/docker/go-events/channel.go
index de95fa4..802cf51 100644
--- a/vendor/github.com/docker/go-events/channel.go
+++ b/vendor/github.com/docker/go-events/channel.go
@@ -50,7 +50,7 @@
 	return nil
 }
 
-func (ch Channel) String() string {
+func (ch *Channel) String() string {
 	// Serialize a copy of the Channel that doesn't contain the sync.Once,
 	// to avoid a data race.
 	ch2 := map[string]interface{}{
diff --git a/vendor/github.com/docker/go-events/queue.go b/vendor/github.com/docker/go-events/queue.go
index cbd657c..4bb770a 100644
--- a/vendor/github.com/docker/go-events/queue.go
+++ b/vendor/github.com/docker/go-events/queue.go
@@ -4,7 +4,7 @@
 	"container/list"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // Queue accepts all messages into a queue for asynchronous consumption
@@ -31,7 +31,7 @@
 }
 
 // Write accepts the events into the queue, only failing if the queue has
-// beend closed.
+// been closed.
 func (eq *Queue) Write(event Event) error {
 	eq.mu.Lock()
 	defer eq.mu.Unlock()
diff --git a/vendor/github.com/docker/go-events/retry.go b/vendor/github.com/docker/go-events/retry.go
index 55d40dc..2df55d2 100644
--- a/vendor/github.com/docker/go-events/retry.go
+++ b/vendor/github.com/docker/go-events/retry.go
@@ -7,7 +7,7 @@
 	"sync/atomic"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // RetryingSink retries the write until success or an ErrSinkClosed is
@@ -90,7 +90,7 @@
 	return nil
 }
 
-func (rs RetryingSink) String() string {
+func (rs *RetryingSink) String() string {
 	// Serialize a copy of the RetryingSink without the sync.Once, to avoid
 	// a data race.
 	rs2 := map[string]interface{}{
diff --git a/vendor/github.com/docker/libnetwork/agent.go b/vendor/github.com/docker/libnetwork/agent.go
index 4877df1..b0d6647 100644
--- a/vendor/github.com/docker/libnetwork/agent.go
+++ b/vendor/github.com/docker/libnetwork/agent.go
@@ -10,7 +10,6 @@
 	"sort"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/go-events"
 	"github.com/docker/libnetwork/cluster"
@@ -20,6 +19,7 @@
 	"github.com/docker/libnetwork/networkdb"
 	"github.com/docker/libnetwork/types"
 	"github.com/gogo/protobuf/proto"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -741,11 +741,12 @@
 			return
 		}
 
-		agent.networkDB.WalkTable(table.name, func(nid, key string, value []byte) bool {
-			if nid == n.ID() {
+		agent.networkDB.WalkTable(table.name, func(nid, key string, value []byte, deleted bool) bool {
+			// skip the entries that are mark for deletion, this is safe because this function is
+			// called at initialization time so there is no state to delete
+			if nid == n.ID() && !deleted {
 				d.EventNotify(driverapi.Create, nid, table.name, key, value)
 			}
-
 			return false
 		})
 	}
@@ -891,13 +892,13 @@
 		if svcID != "" {
 			// This is a remote task part of a service
 			if err := c.addServiceBinding(svcName, svcID, nid, eid, containerName, vip, ingressPorts, serviceAliases, taskAliases, ip, "handleEpTableEvent"); err != nil {
-				logrus.Errorf("failed adding service binding for %s epRec:%v err:%s", eid, epRec, err)
+				logrus.Errorf("failed adding service binding for %s epRec:%v err:%v", eid, epRec, err)
 				return
 			}
 		} else {
 			// This is a remote container simply attached to an attachable network
 			if err := c.addContainerNameResolution(nid, eid, containerName, taskAliases, ip, "handleEpTableEvent"); err != nil {
-				logrus.Errorf("failed adding service binding for %s epRec:%v err:%s", eid, epRec, err)
+				logrus.Errorf("failed adding container name resolution for %s epRec:%v err:%v", eid, epRec, err)
 			}
 		}
 	} else {
@@ -905,13 +906,13 @@
 		if svcID != "" {
 			// This is a remote task part of a service
 			if err := c.rmServiceBinding(svcName, svcID, nid, eid, containerName, vip, ingressPorts, serviceAliases, taskAliases, ip, "handleEpTableEvent", true); err != nil {
-				logrus.Errorf("failed removing service binding for %s epRec:%v err:%s", eid, epRec, err)
+				logrus.Errorf("failed removing service binding for %s epRec:%v err:%v", eid, epRec, err)
 				return
 			}
 		} else {
 			// This is a remote container simply attached to an attachable network
 			if err := c.delContainerNameResolution(nid, eid, containerName, taskAliases, ip, "handleEpTableEvent"); err != nil {
-				logrus.Errorf("failed adding service binding for %s epRec:%v err:%s", eid, epRec, err)
+				logrus.Errorf("failed removing container name resolution for %s epRec:%v err:%v", eid, epRec, err)
 			}
 		}
 	}
diff --git a/vendor/github.com/docker/libnetwork/bitseq/sequence.go b/vendor/github.com/docker/libnetwork/bitseq/sequence.go
index 86cf69b..3946473 100644
--- a/vendor/github.com/docker/libnetwork/bitseq/sequence.go
+++ b/vendor/github.com/docker/libnetwork/bitseq/sequence.go
@@ -10,9 +10,9 @@
 	"fmt"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // block sequence constants
@@ -497,7 +497,10 @@
 	// Derive the this sequence offsets
 	byteOffset := byteStart - inBlockBytePos
 	bitOffset := inBlockBytePos*8 + bitStart
-
+	var firstOffset uint64
+	if current == head {
+		firstOffset = byteOffset
+	}
 	for current != nil {
 		if current.block != blockMAX {
 			bytePos, bitPos, err := current.getAvailableBit(bitOffset)
@@ -505,7 +508,8 @@
 		}
 		// Moving to next block: Reset bit offset.
 		bitOffset = 0
-		byteOffset += current.count * blockBytes
+		byteOffset += (current.count * blockBytes) - firstOffset
+		firstOffset = 0
 		current = current.next
 	}
 	return invalidPos, invalidPos, ErrNoBitAvailable
diff --git a/vendor/github.com/docker/libnetwork/common/caller.go b/vendor/github.com/docker/libnetwork/common/caller.go
new file mode 100644
index 0000000..0dec3bc
--- /dev/null
+++ b/vendor/github.com/docker/libnetwork/common/caller.go
@@ -0,0 +1,29 @@
+package common
+
+import (
+	"runtime"
+	"strings"
+)
+
+func callerInfo(i int) string {
+	ptr, _, _, ok := runtime.Caller(i)
+	fName := "unknown"
+	if ok {
+		f := runtime.FuncForPC(ptr)
+		if f != nil {
+			// f.Name() is like: github.com/docker/libnetwork/common.MethodName
+			tmp := strings.Split(f.Name(), ".")
+			if len(tmp) > 0 {
+				fName = tmp[len(tmp)-1]
+			}
+		}
+	}
+
+	return fName
+}
+
+// CallerName returns the name of the function at the specified level
+// level == 0 means current method name
+func CallerName(level int) string {
+	return callerInfo(2 + level)
+}
diff --git a/vendor/github.com/docker/libnetwork/config/config.go b/vendor/github.com/docker/libnetwork/config/config.go
index a2e43e3..3e8473d 100644
--- a/vendor/github.com/docker/libnetwork/config/config.go
+++ b/vendor/github.com/docker/libnetwork/config/config.go
@@ -4,7 +4,6 @@
 	"strings"
 
 	"github.com/BurntSushi/toml"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/go-connections/tlsconfig"
@@ -13,6 +12,12 @@
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/osl"
+	"github.com/sirupsen/logrus"
+)
+
+const (
+	warningThNetworkControlPlaneMTU = 1500
+	minimumNetworkControlPlaneMTU   = 500
 )
 
 // Config encapsulates configurations of various Libnetwork components
@@ -226,9 +231,12 @@
 func OptionNetworkControlPlaneMTU(exp int) Option {
 	return func(c *Config) {
 		logrus.Debugf("Network Control Plane MTU: %d", exp)
-		if exp < 1500 {
-			// if exp == 0 the value won't be used
-			logrus.Warnf("Received a MTU of %d, this value is very low, the network control plane can misbehave", exp)
+		if exp < warningThNetworkControlPlaneMTU {
+			logrus.Warnf("Received a MTU of %d, this value is very low, the network control plane can misbehave,"+
+				" defaulting to minimum value (%d)", exp, minimumNetworkControlPlaneMTU)
+			if exp < minimumNetworkControlPlaneMTU {
+				exp = minimumNetworkControlPlaneMTU
+			}
 		}
 		c.Daemon.NetworkControlPlaneMTU = exp
 	}
diff --git a/vendor/github.com/docker/libnetwork/controller.go b/vendor/github.com/docker/libnetwork/controller.go
index 1696e07..801097a 100644
--- a/vendor/github.com/docker/libnetwork/controller.go
+++ b/vendor/github.com/docker/libnetwork/controller.go
@@ -52,7 +52,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/pkg/locker"
 	"github.com/docker/docker/pkg/plugingetter"
@@ -69,6 +68,7 @@
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // NetworkController provides the interface for controller instance which manages
diff --git a/vendor/github.com/docker/libnetwork/default_gateway.go b/vendor/github.com/docker/libnetwork/default_gateway.go
index bf15924..9a60fd6 100644
--- a/vendor/github.com/docker/libnetwork/default_gateway.go
+++ b/vendor/github.com/docker/libnetwork/default_gateway.go
@@ -4,9 +4,9 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/diagnose/diagnose.go b/vendor/github.com/docker/libnetwork/diagnose/diagnose.go
new file mode 100644
index 0000000..2849397
--- /dev/null
+++ b/vendor/github.com/docker/libnetwork/diagnose/diagnose.go
@@ -0,0 +1,133 @@
+package diagnose
+
+import (
+	"fmt"
+	"net"
+	"net/http"
+	"sync"
+
+	"github.com/sirupsen/logrus"
+)
+
+// HTTPHandlerFunc TODO
+type HTTPHandlerFunc func(interface{}, http.ResponseWriter, *http.Request)
+
+type httpHandlerCustom struct {
+	ctx interface{}
+	F   func(interface{}, http.ResponseWriter, *http.Request)
+}
+
+// ServeHTTP TODO
+func (h httpHandlerCustom) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	h.F(h.ctx, w, r)
+}
+
+var diagPaths2Func = map[string]HTTPHandlerFunc{
+	"/":      notImplemented,
+	"/help":  help,
+	"/ready": ready,
+}
+
+// Server when the debug is enabled exposes a
+// This data structure is protected by the Agent mutex so does not require and additional mutex here
+type Server struct {
+	sk                net.Listener
+	port              int
+	mux               *http.ServeMux
+	registeredHanders []string
+	sync.Mutex
+}
+
+// Init TODO
+func (n *Server) Init() {
+	n.mux = http.NewServeMux()
+
+	// Register local handlers
+	n.RegisterHandler(n, diagPaths2Func)
+}
+
+// RegisterHandler TODO
+func (n *Server) RegisterHandler(ctx interface{}, hdlrs map[string]HTTPHandlerFunc) {
+	n.Lock()
+	defer n.Unlock()
+	for path, fun := range hdlrs {
+		n.mux.Handle(path, httpHandlerCustom{ctx, fun})
+		n.registeredHanders = append(n.registeredHanders, path)
+	}
+}
+
+// EnableDebug opens a TCP socket to debug the passed network DB
+func (n *Server) EnableDebug(ip string, port int) {
+	n.Lock()
+	defer n.Unlock()
+
+	n.port = port
+	logrus.SetLevel(logrus.DebugLevel)
+
+	if n.sk != nil {
+		logrus.Infof("The server is already up and running")
+		return
+	}
+
+	logrus.Infof("Starting the server listening on %d for commands", port)
+
+	// // Create the socket
+	// var err error
+	// n.sk, err = net.Listen("tcp", listeningAddr)
+	// if err != nil {
+	// 	log.Fatal(err)
+	// }
+	//
+	// go func() {
+	// 	http.Serve(n.sk, n.mux)
+	// }()
+	http.ListenAndServe(":8000", n.mux)
+}
+
+// DisableDebug stop the dubug and closes the tcp socket
+func (n *Server) DisableDebug() {
+	n.Lock()
+	defer n.Unlock()
+	n.sk.Close()
+	n.sk = nil
+}
+
+// IsDebugEnable returns true when the debug is enabled
+func (n *Server) IsDebugEnable() bool {
+	n.Lock()
+	defer n.Unlock()
+	return n.sk != nil
+}
+
+func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	fmt.Fprintf(w, "URL path: %s no method implemented check /help\n", r.URL.Path)
+}
+
+func help(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	n, ok := ctx.(*Server)
+	if ok {
+		for _, path := range n.registeredHanders {
+			fmt.Fprintf(w, "%s\n", path)
+		}
+	}
+}
+
+func ready(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	fmt.Fprintf(w, "OK\n")
+}
+
+// DebugHTTPForm TODO
+func DebugHTTPForm(r *http.Request) {
+	r.ParseForm()
+	for k, v := range r.Form {
+		logrus.Debugf("Form[%q] = %q\n", k, v)
+	}
+}
+
+// HTTPReplyError TODO
+func HTTPReplyError(w http.ResponseWriter, message, usage string) {
+	fmt.Fprintf(w, "%s\n", message)
+	if usage != "" {
+		fmt.Fprintf(w, "Usage: %s\n", usage)
+	}
+}
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go b/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go
index dd79f04..1742c8d 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go
@@ -12,7 +12,6 @@
 	"sync"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
@@ -24,6 +23,7 @@
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/portmapper"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
@@ -763,11 +763,7 @@
 
 	// Apply the prepared list of steps, and abort at the first error.
 	bridgeSetup.queueStep(setupDeviceUp)
-	if err = bridgeSetup.apply(); err != nil {
-		return err
-	}
-
-	return nil
+	return bridgeSetup.apply()
 }
 
 func (d *driver) DeleteNetwork(nid string) error {
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/bridge_store.go b/vendor/github.com/docker/libnetwork/drivers/bridge/bridge_store.go
index c7c83d8..b0e4ff0 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/bridge_store.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/bridge_store.go
@@ -5,11 +5,11 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/interface.go b/vendor/github.com/docker/libnetwork/drivers/bridge/interface.go
index 9b20900..c9f3e8d 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/interface.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/interface.go
@@ -4,7 +4,7 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/link.go b/vendor/github.com/docker/libnetwork/drivers/bridge/link.go
index 53e9eee..d364516 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/link.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/link.go
@@ -4,9 +4,9 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/iptables"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 type link struct {
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go b/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go
index 965cc9a..48010e9 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go
@@ -6,8 +6,8 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go
index 884c711..9b90acf 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go
@@ -7,7 +7,7 @@
 	"os"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // Enumeration type saying which versions of IP protocol to process.
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go
index 0961bea..a9dfd06 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go
@@ -3,9 +3,9 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/libnetwork/netutils"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_forwarding.go b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_forwarding.go
index d46f8dd..355a14d 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_forwarding.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_forwarding.go
@@ -4,8 +4,8 @@
 	"fmt"
 	"io/ioutil"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/iptables"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go
index 769debc..da65444 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go
@@ -5,8 +5,8 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/iptables"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
@@ -169,11 +169,7 @@
 	}
 
 	// Set Accept on all non-intercontainer outgoing packets.
-	if err := programChainRule(outRule, "ACCEPT NON_ICC OUTGOING", enable); err != nil {
-		return err
-	}
-
-	return nil
+	return programChainRule(outRule, "ACCEPT NON_ICC OUTGOING", enable)
 }
 
 func programChainRule(rule iptRule, ruleDescr string, insert bool) error {
@@ -304,10 +300,7 @@
 		return err
 	}
 	// Set Inter Container Communication.
-	if err := setIcc(bridgeIface, icc, insert); err != nil {
-		return err
-	}
-	return nil
+	return setIcc(bridgeIface, icc, insert)
 }
 
 func clearEndpointConnections(nlh *netlink.Handle, ep *bridgeEndpoint) {
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv4.go b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv4.go
index 7f87072..671bd33 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv4.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv4.go
@@ -7,8 +7,8 @@
 	"net"
 	"path/filepath"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go
index ee3d753..b944be0 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go
@@ -6,8 +6,8 @@
 	"net"
 	"os"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_verify.go b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_verify.go
index 330a5b4..de77c38 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/setup_verify.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/setup_verify.go
@@ -4,9 +4,9 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_endpoint.go b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_endpoint.go
index d30aeac..1fe44f2 100644
--- a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_endpoint.go
+++ b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_endpoint.go
@@ -3,12 +3,12 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // CreateEndpoint assigns the mac, ip and endpoint id for the new container
diff --git a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_joinleave.go b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_joinleave.go
index 0c08dfc..9d229a2 100644
--- a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_joinleave.go
+++ b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_joinleave.go
@@ -4,12 +4,12 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 type staticRoute struct {
diff --git a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_network.go b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_network.go
index 801fc20..a9544b5 100644
--- a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_network.go
+++ b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_network.go
@@ -3,7 +3,6 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/libnetwork/driverapi"
@@ -12,6 +11,7 @@
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // CreateNetwork the network for the specified driver type
diff --git a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_setup.go b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_setup.go
index 75f0821..28d6cca 100644
--- a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_setup.go
+++ b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_setup.go
@@ -5,8 +5,8 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/ns"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
@@ -201,5 +201,5 @@
 
 // getDummyName returns the name of a dummy parent with truncated net ID and driver prefix
 func getDummyName(netID string) string {
-	return fmt.Sprintf("%s%s", dummyPrefix, netID)
+	return dummyPrefix + netID
 }
diff --git a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_state.go b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_state.go
index 2d8cb2d..2a4ad25 100644
--- a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_state.go
+++ b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_state.go
@@ -3,9 +3,9 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 func (d *driver) network(nid string) *network {
diff --git a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_store.go b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_store.go
index de994fa..197e299 100644
--- a/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_store.go
+++ b/vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_store.go
@@ -5,11 +5,11 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go
index 3e5ccb2..d9fae57 100644
--- a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go
+++ b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go
@@ -3,13 +3,13 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // CreateEndpoint assigns the mac, ip and endpoint id for the new container
diff --git a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_joinleave.go b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_joinleave.go
index cf5c2a4..778613d 100644
--- a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_joinleave.go
+++ b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_joinleave.go
@@ -4,11 +4,11 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/osl"
+	"github.com/sirupsen/logrus"
 )
 
 // Join method is invoked when a Sandbox is attached to an endpoint.
diff --git a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go
index c455b91..914c6cd 100644
--- a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go
+++ b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go
@@ -3,7 +3,6 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/libnetwork/driverapi"
@@ -12,6 +11,7 @@
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // CreateNetwork the network for the specified driver type
diff --git a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go
index b5b4be3..98d4bd3 100644
--- a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go
+++ b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go
@@ -5,8 +5,8 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/ns"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
@@ -205,5 +205,5 @@
 
 // getDummyName returns the name of a dummy parent with truncated net ID and driver prefix
 func getDummyName(netID string) string {
-	return fmt.Sprintf("%s%s", dummyPrefix, netID)
+	return dummyPrefix + netID
 }
diff --git a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_state.go b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_state.go
index 8ac3d28..8fd1a9e 100644
--- a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_state.go
+++ b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_state.go
@@ -3,9 +3,9 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 func (d *driver) network(nid string) *network {
diff --git a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go
index 3fd9278..655a49c 100644
--- a/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go
+++ b/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go
@@ -5,11 +5,11 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/encryption.go b/vendor/github.com/docker/libnetwork/drivers/overlay/encryption.go
index 1d59f23..f12d7a8 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/encryption.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/encryption.go
@@ -12,10 +12,10 @@
 
 	"strconv"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/iptables"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/filter.go b/vendor/github.com/docker/libnetwork/drivers/overlay/filter.go
index 40cd7d9..1601803 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/filter.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/filter.go
@@ -4,8 +4,8 @@
 	"fmt"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/iptables"
+	"github.com/sirupsen/logrus"
 )
 
 const globalChain = "DOCKER-OVERLAY"
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/joinleave.go b/vendor/github.com/docker/libnetwork/drivers/overlay/joinleave.go
index cdbb428..a07838b 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/joinleave.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/joinleave.go
@@ -5,11 +5,11 @@
 	"net"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/types"
 	"github.com/gogo/protobuf/proto"
+	"github.com/sirupsen/logrus"
 )
 
 // Join method is invoked when a Sandbox is attached to an endpoint.
@@ -120,8 +120,7 @@
 		}
 	}
 
-	d.peerDbAdd(nid, eid, ep.addr.IP, ep.addr.Mask, ep.mac,
-		net.ParseIP(d.advertiseAddress), true)
+	d.peerAdd(nid, eid, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), false, false, true)
 
 	if err := d.checkEncryption(nid, nil, n.vxlanID(s), true, true); err != nil {
 		logrus.Warn(err)
@@ -201,11 +200,11 @@
 	}
 
 	if etype == driverapi.Delete {
-		d.peerDelete(nid, eid, addr.IP, addr.Mask, mac, vtep, true)
+		d.peerDelete(nid, eid, addr.IP, addr.Mask, mac, vtep)
 		return
 	}
 
-	d.peerAdd(nid, eid, addr.IP, addr.Mask, mac, vtep, true, false, false)
+	d.peerAdd(nid, eid, addr.IP, addr.Mask, mac, vtep, false, false, false)
 }
 
 // Leave method is invoked when a Sandbox detaches from an endpoint.
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ostweaks_linux.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ostweaks_linux.go
index 85840cf..c00243a 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/ostweaks_linux.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ostweaks_linux.go
@@ -5,7 +5,7 @@
 	"path"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 var sysctlConf = map[string]string{
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go
index ebcab51..bb08de4 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go
@@ -5,12 +5,12 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 type endpointTable map[string]*endpoint
@@ -144,11 +144,7 @@
 		return fmt.Errorf("overlay local store not initialized, ep not deleted")
 	}
 
-	if err := d.localStore.DeleteObjectAtomic(e); err != nil {
-		return err
-	}
-
-	return nil
+	return d.localStore.DeleteObjectAtomic(e)
 }
 
 func (d *driver) writeEndpointToStore(e *endpoint) error {
@@ -156,10 +152,7 @@
 		return fmt.Errorf("overlay local store not initialized, ep not added")
 	}
 
-	if err := d.localStore.PutObjectAtomic(e); err != nil {
-		return err
-	}
-	return nil
+	return d.localStore.PutObjectAtomic(e)
 }
 
 func (ep *endpoint) DataScope() string {
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go
index 01f6287..0e9ca77 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go
@@ -8,13 +8,13 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
 	"strconv"
 	"strings"
 	"sync"
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
@@ -24,6 +24,7 @@
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/resolvconf"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
@@ -81,6 +82,10 @@
 		logrus.Error("insufficient number of arguments")
 		os.Exit(1)
 	}
+
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
 	nsPath := os.Args[1]
 	ns, err := netns.GetFromPath(nsPath)
 	if err != nil {
@@ -489,7 +494,7 @@
 	brIfaceOption := make([]osl.IfaceOption, 2)
 	brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Address(s.gwIP))
 	brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Bridge(true))
-	Ifaces[fmt.Sprintf("%s+%s", brName, "br")] = brIfaceOption
+	Ifaces[brName+"+br"] = brIfaceOption
 
 	err := sbox.Restore(Ifaces, nil, nil, nil)
 	if err != nil {
@@ -499,7 +504,7 @@
 	Ifaces = make(map[string][]osl.IfaceOption)
 	vxlanIfaceOption := make([]osl.IfaceOption, 1)
 	vxlanIfaceOption = append(vxlanIfaceOption, sbox.InterfaceOptions().Master(brName))
-	Ifaces[fmt.Sprintf("%s+%s", vxlanName, "vxlan")] = vxlanIfaceOption
+	Ifaces[vxlanName+"+vxlan"] = vxlanIfaceOption
 	err = sbox.Restore(Ifaces, nil, nil, nil)
 	if err != nil {
 		return err
@@ -683,10 +688,12 @@
 		return fmt.Errorf("could not get network sandbox (oper %t): %v", restore, err)
 	}
 
+	// this is needed to let the peerAdd configure the sandbox
 	n.setSandbox(sbox)
 
 	if !restore {
-		n.driver.peerDbUpdateSandbox(n.id)
+		// Initialize the sandbox with all the peers previously received from networkdb
+		n.driver.initSandboxPeerDB(n.id)
 	}
 
 	var nlSock *nl.NetlinkSocket
@@ -765,10 +772,7 @@
 					logrus.Errorf("could not resolve peer %q: %v", ip, err)
 					continue
 				}
-
-				if err := n.driver.peerAdd(n.id, "dummy", ip, IPmask, mac, vtep, true, l2Miss, l3Miss); err != nil {
-					logrus.Errorf("could not add neighbor entry for missed peer %q: %v", ip, err)
-				}
+				n.driver.peerAdd(n.id, "dummy", ip, IPmask, mac, vtep, l2Miss, l3Miss, false)
 			} else {
 				// If the gc_thresh values are lower kernel might knock off the neighor entries.
 				// When we get a L3 miss check if its a valid peer and reprogram the neighbor
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_serf.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_serf.go
index 9002bce..6e034ad 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_serf.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_serf.go
@@ -6,8 +6,8 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/hashicorp/serf/serf"
+	"github.com/sirupsen/logrus"
 )
 
 type ovNotify struct {
@@ -120,15 +120,9 @@
 
 	switch action {
 	case "join":
-		if err := d.peerAdd(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
-			net.ParseIP(vtepStr), true, false, false); err != nil {
-			logrus.Errorf("Peer add failed in the driver: %v\n", err)
-		}
+		d.peerAdd(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac, net.ParseIP(vtepStr), false, false, false)
 	case "leave":
-		if err := d.peerDelete(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac,
-			net.ParseIP(vtepStr), true); err != nil {
-			logrus.Errorf("Peer delete failed in the driver: %v\n", err)
-		}
+		d.peerDelete(nid, eid, net.ParseIP(ipStr), net.IPMask(net.ParseIP(maskStr).To4()), mac, net.ParseIP(vtepStr))
 	}
 }
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go
index 8a01914..27f57c1 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go
@@ -5,10 +5,10 @@
 	"strings"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/osl"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netns"
 )
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/overlay.go b/vendor/github.com/docker/libnetwork/drivers/overlay/overlay.go
index 8d19b2e..2bae082 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/overlay.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/overlay.go
@@ -3,11 +3,11 @@
 //go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto
 
 import (
+	"context"
 	"fmt"
 	"net"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
@@ -16,6 +16,7 @@
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
 	"github.com/hashicorp/serf/serf"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -50,6 +51,8 @@
 	joinOnce         sync.Once
 	localJoinOnce    sync.Once
 	keys             []*key
+	peerOpCh         chan *peerOperation
+	peerOpCancel     context.CancelFunc
 	sync.Mutex
 }
 
@@ -64,10 +67,16 @@
 		peerDb: peerNetworkMap{
 			mp: map[string]*peerMap{},
 		},
-		secMap: &encrMap{nodes: map[string][]*spi{}},
-		config: config,
+		secMap:   &encrMap{nodes: map[string][]*spi{}},
+		config:   config,
+		peerOpCh: make(chan *peerOperation),
 	}
 
+	// Launch the go routine for processing peer operations
+	ctx, cancel := context.WithCancel(context.Background())
+	d.peerOpCancel = cancel
+	go d.peerOpRoutine(ctx, d.peerOpCh)
+
 	if data, ok := config[netlabel.GlobalKVClient]; ok {
 		var err error
 		dsc, ok := data.(discoverapi.DatastoreConfigData)
@@ -153,7 +162,7 @@
 		Ifaces := make(map[string][]osl.IfaceOption)
 		vethIfaceOption := make([]osl.IfaceOption, 1)
 		vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName))
-		Ifaces[fmt.Sprintf("%s+%s", "veth", "veth")] = vethIfaceOption
+		Ifaces["veth+veth"] = vethIfaceOption
 
 		err := n.sbox.Restore(Ifaces, nil, nil, nil)
 		if err != nil {
@@ -161,7 +170,7 @@
 		}
 
 		n.incEndpointCount()
-		d.peerDbAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), true)
+		d.peerAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), false, false, true)
 	}
 	return nil
 }
@@ -170,6 +179,11 @@
 func Fini(drv driverapi.Driver) {
 	d := drv.(*driver)
 
+	// Notify the peer go routine to return
+	if d.peerOpCancel != nil {
+		d.peerOpCancel()
+	}
+
 	if d.exitCh != nil {
 		waitCh := make(chan struct{})
 
@@ -256,7 +270,7 @@
 		// If there is no cluster store there is no need to start serf.
 		if d.store != nil {
 			if err := validateSelf(advertiseAddress); err != nil {
-				logrus.Warnf("%s", err.Error())
+				logrus.Warn(err.Error())
 			}
 			err := d.serfInit()
 			if err != nil {
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go
index 3c3c0bb..a80f335 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ovmanager/ovmanager.go
@@ -7,13 +7,13 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/idm"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go b/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go
index 21cd1fb..f953e3c 100644
--- a/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go
+++ b/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go
@@ -1,12 +1,14 @@
 package overlay
 
 import (
+	"context"
 	"fmt"
 	"net"
 	"sync"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/docker/libnetwork/common"
+	"github.com/sirupsen/logrus"
 )
 
 const ovPeerTable = "overlay_peer_table"
@@ -59,8 +61,6 @@
 	return nil
 }
 
-var peerDbWg sync.WaitGroup
-
 func (d *driver) peerDbWalk(f func(string, *peerKey, *peerEntry) bool) error {
 	d.peerDb.Lock()
 	nids := []string{}
@@ -141,8 +141,6 @@
 func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
 	peerMac net.HardwareAddr, vtep net.IP, isLocal bool) {
 
-	peerDbWg.Wait()
-
 	d.peerDb.Lock()
 	pMap, ok := d.peerDb.mp[nid]
 	if !ok {
@@ -173,7 +171,6 @@
 
 func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
 	peerMac net.HardwareAddr, vtep net.IP) peerEntry {
-	peerDbWg.Wait()
 
 	d.peerDb.Lock()
 	pMap, ok := d.peerDb.mp[nid]
@@ -206,62 +203,117 @@
 	return pEntry
 }
 
-func (d *driver) peerDbUpdateSandbox(nid string) {
-	d.peerDb.Lock()
-	pMap, ok := d.peerDb.mp[nid]
-	if !ok {
-		d.peerDb.Unlock()
-		return
-	}
-	d.peerDb.Unlock()
+// The overlay uses a lazy initialization approach, this means that when a network is created
+// and the driver registered the overlay does not allocate resources till the moment that a
+// sandbox is actually created.
+// At the moment of this call, that happens when a sandbox is initialized, is possible that
+// networkDB has already delivered some events of peers already available on remote nodes,
+// these peers are saved into the peerDB and this function is used to properly configure
+// the network sandbox with all those peers that got previously notified.
+// Note also that this method sends a single message on the channel and the go routine on the
+// other side, will atomically loop on the whole table of peers and will program their state
+// in one single atomic operation. This is fundamental to guarantee consistency, and avoid that
+// new peerAdd or peerDelete gets reordered during the sandbox init.
+func (d *driver) initSandboxPeerDB(nid string) {
+	d.peerInit(nid)
+}
 
-	peerDbWg.Add(1)
+type peerOperationType int32
 
-	var peerOps []func()
-	pMap.Lock()
-	for pKeyStr, pEntry := range pMap.mp {
-		var pKey peerKey
-		if _, err := fmt.Sscan(pKeyStr, &pKey); err != nil {
-			logrus.Errorf("peer key scan failed: %v", err)
-		}
+const (
+	peerOperationINIT peerOperationType = iota
+	peerOperationADD
+	peerOperationDELETE
+)
 
-		if pEntry.isLocal {
-			continue
-		}
+type peerOperation struct {
+	opType     peerOperationType
+	networkID  string
+	endpointID string
+	peerIP     net.IP
+	peerIPMask net.IPMask
+	peerMac    net.HardwareAddr
+	vtepIP     net.IP
+	l2Miss     bool
+	l3Miss     bool
+	localPeer  bool
+	callerName string
+}
 
-		// Go captures variables by reference. The pEntry could be
-		// pointing to the same memory location for every iteration. Make
-		// a copy of pEntry before capturing it in the following closure.
-		entry := pEntry
-		op := func() {
-			if err := d.peerAdd(nid, entry.eid, pKey.peerIP, entry.peerIPMask,
-				pKey.peerMac, entry.vtep,
-				false, false, false); err != nil {
-				logrus.Errorf("peerdbupdate in sandbox failed for ip %s and mac %s: %v",
-					pKey.peerIP, pKey.peerMac, err)
+func (d *driver) peerOpRoutine(ctx context.Context, ch chan *peerOperation) {
+	var err error
+	for {
+		select {
+		case <-ctx.Done():
+			return
+		case op := <-ch:
+			switch op.opType {
+			case peerOperationINIT:
+				err = d.peerInitOp(op.networkID)
+			case peerOperationADD:
+				err = d.peerAddOp(op.networkID, op.endpointID, op.peerIP, op.peerIPMask, op.peerMac, op.vtepIP, op.l2Miss, op.l3Miss, true, op.localPeer)
+			case peerOperationDELETE:
+				err = d.peerDeleteOp(op.networkID, op.endpointID, op.peerIP, op.peerIPMask, op.peerMac, op.vtepIP)
+			}
+			if err != nil {
+				logrus.Warnf("Peer operation failed:%s op:%v", err, op)
 			}
 		}
-
-		peerOps = append(peerOps, op)
 	}
-	pMap.Unlock()
+}
 
-	for _, op := range peerOps {
-		op()
+func (d *driver) peerInit(nid string) {
+	callerName := common.CallerName(1)
+	d.peerOpCh <- &peerOperation{
+		opType:     peerOperationINIT,
+		networkID:  nid,
+		callerName: callerName,
 	}
+}
 
-	peerDbWg.Done()
+func (d *driver) peerInitOp(nid string) error {
+	return d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool {
+		// Local entries do not need to be added
+		if pEntry.isLocal {
+			return false
+		}
+
+		d.peerAddOp(nid, pEntry.eid, pKey.peerIP, pEntry.peerIPMask, pKey.peerMac, pEntry.vtep, false, false, false, pEntry.isLocal)
+		// return false to loop on all entries
+		return false
+	})
 }
 
 func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
-	peerMac net.HardwareAddr, vtep net.IP, updateDb, l2Miss, l3Miss bool) error {
+	peerMac net.HardwareAddr, vtep net.IP, l2Miss, l3Miss, localPeer bool) {
+	callerName := common.CallerName(1)
+	d.peerOpCh <- &peerOperation{
+		opType:     peerOperationADD,
+		networkID:  nid,
+		endpointID: eid,
+		peerIP:     peerIP,
+		peerIPMask: peerIPMask,
+		peerMac:    peerMac,
+		vtepIP:     vtep,
+		l2Miss:     l2Miss,
+		l3Miss:     l3Miss,
+		localPeer:  localPeer,
+		callerName: callerName,
+	}
+}
+
+func (d *driver) peerAddOp(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
+	peerMac net.HardwareAddr, vtep net.IP, l2Miss, l3Miss, updateDB, updateOnlyDB bool) error {
 
 	if err := validateID(nid, eid); err != nil {
 		return err
 	}
 
-	if updateDb {
+	if updateDB {
 		d.peerDbAdd(nid, eid, peerIP, peerIPMask, peerMac, vtep, false)
+		if updateOnlyDB {
+			return nil
+		}
 	}
 
 	n := d.network(nid)
@@ -271,6 +323,9 @@
 
 	sbox := n.sandbox()
 	if sbox == nil {
+		// We are hitting this case for all the events that are arriving before that the sandbox
+		// is being created. The peer got already added into the database and the sanbox init will
+		// call the peerDbUpdateSandbox that will configure all these peers from the database
 		return nil
 	}
 
@@ -311,16 +366,28 @@
 }
 
 func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
-	peerMac net.HardwareAddr, vtep net.IP, updateDb bool) error {
+	peerMac net.HardwareAddr, vtep net.IP) {
+	callerName := common.CallerName(1)
+	d.peerOpCh <- &peerOperation{
+		opType:     peerOperationDELETE,
+		networkID:  nid,
+		endpointID: eid,
+		peerIP:     peerIP,
+		peerIPMask: peerIPMask,
+		peerMac:    peerMac,
+		vtepIP:     vtep,
+		callerName: callerName,
+	}
+}
+
+func (d *driver) peerDeleteOp(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
+	peerMac net.HardwareAddr, vtep net.IP) error {
 
 	if err := validateID(nid, eid); err != nil {
 		return err
 	}
 
-	var pEntry peerEntry
-	if updateDb {
-		pEntry = d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep)
-	}
+	pEntry := d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep)
 
 	n := d.network(nid)
 	if n == nil {
diff --git a/vendor/github.com/docker/libnetwork/drivers/remote/driver.go b/vendor/github.com/docker/libnetwork/drivers/remote/driver.go
index ffe0730..b521630 100644
--- a/vendor/github.com/docker/libnetwork/drivers/remote/driver.go
+++ b/vendor/github.com/docker/libnetwork/drivers/remote/driver.go
@@ -5,13 +5,13 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/drivers/remote/api"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 type driver struct {
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go b/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go
index 2547016..558157a 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge.go
@@ -13,7 +13,6 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
@@ -23,6 +22,7 @@
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/portmapper"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge_store.go b/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge_store.go
index 956e829..6f5db4f 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge_store.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/bridge_store.go
@@ -7,11 +7,11 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go b/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go
index 1cf22c1..3b67db3 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/bridge/port_mapping.go
@@ -10,8 +10,8 @@
 	"os"
 	"os/exec"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/encryption.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/encryption.go
index ca7b60b..0af3474 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/encryption.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/encryption.go
@@ -9,8 +9,8 @@
 	"net"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/joinleave.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/joinleave.go
index fd41198..ff03f3c 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/joinleave.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/joinleave.go
@@ -4,10 +4,10 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/types"
 	"github.com/gogo/protobuf/proto"
+	"github.com/sirupsen/logrus"
 )
 
 // Join method is invoked when a Sandbox is attached to an endpoint.
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go
index ca0c477..9df7a58 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go
@@ -5,11 +5,11 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 type endpointTable map[string]*endpoint
@@ -134,11 +134,7 @@
 		return fmt.Errorf("overlay local store not initialized, ep not deleted")
 	}
 
-	if err := d.localStore.DeleteObjectAtomic(e); err != nil {
-		return err
-	}
-
-	return nil
+	return d.localStore.DeleteObjectAtomic(e)
 }
 
 func (d *driver) writeEndpointToStore(e *endpoint) error {
@@ -146,10 +142,7 @@
 		return fmt.Errorf("overlay local store not initialized, ep not added")
 	}
 
-	if err := d.localStore.PutObjectAtomic(e); err != nil {
-		return err
-	}
-	return nil
+	return d.localStore.PutObjectAtomic(e)
 }
 
 func (ep *endpoint) DataScope() string {
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_network.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_network.go
index b056726..4e3f9ae 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_network.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_network.go
@@ -10,7 +10,6 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
@@ -18,6 +17,7 @@
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/resolvconf"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -331,7 +331,7 @@
 	brIfaceOption := make([]osl.IfaceOption, 2)
 	brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Address(s.gwIP))
 	brIfaceOption = append(brIfaceOption, sbox.InterfaceOptions().Bridge(true))
-	Ifaces[fmt.Sprintf("%s+%s", brName, "br")] = brIfaceOption
+	Ifaces[brName+"+br"] = brIfaceOption
 
 	err := sbox.Restore(Ifaces, nil, nil, nil)
 	if err != nil {
@@ -341,7 +341,7 @@
 	Ifaces = make(map[string][]osl.IfaceOption)
 	vxlanIfaceOption := make([]osl.IfaceOption, 1)
 	vxlanIfaceOption = append(vxlanIfaceOption, sbox.InterfaceOptions().Master(brName))
-	Ifaces[fmt.Sprintf("%s+%s", vxlanName, "vxlan")] = vxlanIfaceOption
+	Ifaces[vxlanName+"+vxlan"] = vxlanIfaceOption
 	err = sbox.Restore(Ifaces, nil, nil, nil)
 	if err != nil {
 		return err
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_serf.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_serf.go
index 53c59b4..ddc0509 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_serf.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_serf.go
@@ -6,8 +6,8 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/hashicorp/serf/serf"
+	"github.com/sirupsen/logrus"
 )
 
 type ovNotify struct {
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/overlay.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/overlay.go
index 0a5a1bf..92b0a4e 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/overlay.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/overlay.go
@@ -7,7 +7,6 @@
 	"net"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
@@ -16,6 +15,7 @@
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
 	"github.com/hashicorp/serf/serf"
+	"github.com/sirupsen/logrus"
 )
 
 // XXX OVERLAY_SOLARIS
@@ -141,7 +141,7 @@
 		Ifaces := make(map[string][]osl.IfaceOption)
 		vethIfaceOption := make([]osl.IfaceOption, 1)
 		vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName))
-		Ifaces[fmt.Sprintf("%s+%s", "veth", "veth")] = vethIfaceOption
+		Ifaces["veth+veth"] = vethIfaceOption
 
 		err := n.sbox.Restore(Ifaces, nil, nil, nil)
 		if err != nil {
@@ -234,7 +234,7 @@
 		// If there is no cluster store there is no need to start serf.
 		if d.store != nil {
 			if err := validateSelf(advertiseAddress); err != nil {
-				logrus.Warnf("%s", err.Error())
+				logrus.Warn(err.Error())
 			}
 			err := d.serfInit()
 			if err != nil {
diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go
index d1499e2..23d9a97 100644
--- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go
+++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go
@@ -5,7 +5,7 @@
 	"net"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 const ovPeerTable = "overlay_peer_table"
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/joinleave_windows.go b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/joinleave_windows.go
index 91dcf28..83bee5a 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/joinleave_windows.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/joinleave_windows.go
@@ -4,10 +4,10 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/types"
 	"github.com/gogo/protobuf/proto"
+	"github.com/sirupsen/logrus"
 )
 
 // Join method is invoked when a Sandbox is attached to an endpoint.
@@ -39,6 +39,11 @@
 	if err := jinfo.AddTableEntry(ovPeerTable, eid, buf); err != nil {
 		logrus.Errorf("overlay: Failed adding table entry to joininfo: %v", err)
 	}
+
+	if ep.disablegateway {
+		jinfo.DisableGatewayService()
+	}
+
 	return nil
 }
 
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_endpoint_windows.go b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_endpoint_windows.go
index 3e45115..b7bda4a 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_endpoint_windows.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_endpoint_windows.go
@@ -6,8 +6,12 @@
 	"net"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/pkg/system"
 	"github.com/docker/libnetwork/driverapi"
+	"github.com/docker/libnetwork/drivers/windows"
+	"github.com/docker/libnetwork/netlabel"
+	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 type endpointTable map[string]*endpoint
@@ -15,12 +19,14 @@
 const overlayEndpointPrefix = "overlay/endpoint"
 
 type endpoint struct {
-	id        string
-	nid       string
-	profileId string
-	remote    bool
-	mac       net.HardwareAddr
-	addr      *net.IPNet
+	id             string
+	nid            string
+	profileID      string
+	remote         bool
+	mac            net.HardwareAddr
+	addr           *net.IPNet
+	disablegateway bool
+	portMapping    []types.PortBinding // Operation port bindings
 }
 
 func validateID(nid, eid string) error {
@@ -71,7 +77,7 @@
 
 	if networkEndpoint != nil {
 		logrus.Debugf("Removing stale endpoint from HNS")
-		_, err := hcsshim.HNSEndpointRequest("DELETE", networkEndpoint.profileId, "")
+		_, err := hcsshim.HNSEndpointRequest("DELETE", networkEndpoint.profileID, "")
 
 		if err != nil {
 			logrus.Debugf("Failed to delete stale overlay endpoint (%s) from hns", networkEndpoint.id[0:7])
@@ -96,7 +102,7 @@
 		logrus.Debugf("Deleting stale endpoint %s", eid)
 		n.deleteEndpoint(eid)
 
-		_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
+		_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileID, "")
 		if err != nil {
 			return err
 		}
@@ -113,17 +119,19 @@
 		return fmt.Errorf("create endpoint was not passed interface IP address")
 	}
 
-	if s := n.getSubnetforIP(ep.addr); s == nil {
-		return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
+	s := n.getSubnetforIP(ep.addr)
+	if s == nil {
+		return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
 	}
 
 	// Todo: Add port bindings and qos policies here
 
 	hnsEndpoint := &hcsshim.HNSEndpoint{
 		Name:              eid,
-		VirtualNetwork:    n.hnsId,
+		VirtualNetwork:    n.hnsID,
 		IPAddress:         ep.addr.IP,
 		EnableInternalDNS: true,
+		GatewayAddress:    s.gwIP.String(),
 	}
 
 	if ep.mac != nil {
@@ -141,6 +149,31 @@
 
 	hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)
 
+	if system.GetOSVersion().Build > 16236 {
+		natPolicy, err := json.Marshal(hcsshim.PaPolicy{
+			Type: "OutBoundNAT",
+		})
+
+		if err != nil {
+			return err
+		}
+
+		hnsEndpoint.Policies = append(hnsEndpoint.Policies, natPolicy)
+
+		epConnectivity, err := windows.ParseEndpointConnectivity(epOptions)
+		if err != nil {
+			return err
+		}
+
+		pbPolicy, err := windows.ConvertPortBindings(epConnectivity.PortBindings)
+		if err != nil {
+			return err
+		}
+		hnsEndpoint.Policies = append(hnsEndpoint.Policies, pbPolicy...)
+
+		ep.disablegateway = true
+	}
+
 	configurationb, err := json.Marshal(hnsEndpoint)
 	if err != nil {
 		return err
@@ -151,7 +184,7 @@
 		return err
 	}
 
-	ep.profileId = hnsresponse.Id
+	ep.profileID = hnsresponse.Id
 
 	if ep.mac == nil {
 		ep.mac, err = net.ParseMAC(hnsresponse.MacAddress)
@@ -164,6 +197,12 @@
 		}
 	}
 
+	ep.portMapping, err = windows.ParsePortBindingPolicies(hnsresponse.Policies)
+	if err != nil {
+		hcsshim.HNSEndpointRequest("DELETE", hnsresponse.Id, "")
+		return err
+	}
+
 	n.addEndpoint(ep)
 
 	return nil
@@ -186,7 +225,7 @@
 
 	n.deleteEndpoint(eid)
 
-	_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
+	_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileID, "")
 	if err != nil {
 		return err
 	}
@@ -210,7 +249,17 @@
 	}
 
 	data := make(map[string]interface{}, 1)
-	data["hnsid"] = ep.profileId
+	data["hnsid"] = ep.profileID
 	data["AllowUnqualifiedDNSQuery"] = true
+
+	if ep.portMapping != nil {
+		// Return a copy of the operational data
+		pmc := make([]types.PortBinding, 0, len(ep.portMapping))
+		for _, pm := range ep.portMapping {
+			pmc = append(pmc, pm.GetCopy())
+		}
+		data[netlabel.PortMap] = pmc
+	}
+
 	return data, nil
 }
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_network_windows.go b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_network_windows.go
index 65b7e38..9cc46f8 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_network_windows.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/ov_network_windows.go
@@ -9,10 +9,10 @@
 	"sync"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 var (
@@ -37,7 +37,7 @@
 type network struct {
 	id              string
 	name            string
-	hnsId           string
+	hnsID           string
 	providerAddress string
 	interfaceName   string
 	endpoints       endpointTable
@@ -108,7 +108,7 @@
 		case "com.docker.network.windowsshim.interface":
 			interfaceName = value
 		case "com.docker.network.windowsshim.hnsid":
-			n.hnsId = value
+			n.hnsID = value
 		case netlabel.OverlayVxlanIDList:
 			vniStrings := strings.Split(value, ",")
 			for _, vniStr := range vniStrings {
@@ -181,7 +181,7 @@
 	if err != nil {
 		d.deleteNetwork(id)
 	} else {
-		genData["com.docker.network.windowsshim.hnsid"] = n.hnsId
+		genData["com.docker.network.windowsshim.hnsid"] = n.hnsID
 	}
 
 	return err
@@ -197,7 +197,7 @@
 		return types.ForbiddenErrorf("could not find network with id %s", nid)
 	}
 
-	_, err := hcsshim.HNSNetworkRequest("DELETE", n.hnsId, "")
+	_, err := hcsshim.HNSNetworkRequest("DELETE", n.hnsID, "")
 	if err != nil {
 		return types.ForbiddenErrorf(err.Error())
 	}
@@ -242,7 +242,7 @@
 // 	}
 
 // 	for _, endpoint := range hnsresponse {
-// 		if endpoint.VirtualNetwork != n.hnsId {
+// 		if endpoint.VirtualNetwork != n.hnsID {
 // 			continue
 // 		}
 
@@ -260,7 +260,7 @@
 func (n *network) convertToOverlayEndpoint(v *hcsshim.HNSEndpoint) *endpoint {
 	ep := &endpoint{
 		id:        v.Name,
-		profileId: v.Id,
+		profileID: v.Id,
 		nid:       n.id,
 		remote:    v.IsRemoteEndpoint,
 	}
@@ -311,6 +311,7 @@
 		Type:               d.Type(),
 		Subnets:            subnets,
 		NetworkAdapterName: n.interfaceName,
+		AutomaticDNS:       true,
 	}
 
 	configurationb, err := json.Marshal(network)
@@ -326,7 +327,7 @@
 		return err
 	}
 
-	n.hnsId = hnsresponse.Id
+	n.hnsID = hnsresponse.Id
 	n.providerAddress = hnsresponse.ManagementIP
 
 	return nil
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/overlay_windows.go b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/overlay_windows.go
index 111e517..65ad62a 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/overlay_windows.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/overlay_windows.go
@@ -8,12 +8,12 @@
 	"sync"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -104,7 +104,7 @@
 func (d *driver) convertToOverlayNetwork(v *hcsshim.HNSNetwork) *network {
 	n := &network{
 		id:              v.Name,
-		hnsId:           v.Id,
+		hnsID:           v.Id,
 		driver:          d,
 		endpoints:       endpointTable{},
 		subnets:         []*subnet{},
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/peerdb_windows.go b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/peerdb_windows.go
index 04581f7..159bfd6 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/overlay/peerdb_windows.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/overlay/peerdb_windows.go
@@ -6,8 +6,8 @@
 
 	"encoding/json"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 
 	"github.com/Microsoft/hcsshim"
 )
@@ -33,7 +33,7 @@
 
 		hnsEndpoint := &hcsshim.HNSEndpoint{
 			Name:             eid,
-			VirtualNetwork:   n.hnsId,
+			VirtualNetwork:   n.hnsID,
 			MacAddress:       peerMac.String(),
 			IPAddress:        peerIP,
 			IsRemoteEndpoint: true,
@@ -78,7 +78,7 @@
 			nid:       nid,
 			addr:      addr,
 			mac:       peerMac,
-			profileId: hnsresponse.Id,
+			profileID: hnsresponse.Id,
 			remote:    true,
 		}
 
@@ -108,7 +108,7 @@
 	}
 
 	if updateDb {
-		_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileId, "")
+		_, err := hcsshim.HNSEndpointRequest("DELETE", ep.profileID, "")
 		if err != nil {
 			return err
 		}
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/windows.go b/vendor/github.com/docker/libnetwork/drivers/windows/windows.go
index 19b2e68..0b15b2a 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/windows.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/windows.go
@@ -20,12 +20,12 @@
 	"sync"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // networkConfiguration for network specific configuration
@@ -55,7 +55,8 @@
 	DisableICC  bool
 }
 
-type endpointConnectivity struct {
+// EndpointConnectivity stores the port bindings and exposed ports that the user has specified in epOptions.
+type EndpointConnectivity struct {
 	PortBindings []types.PortBinding
 	ExposedPorts []types.TransportPort
 }
@@ -67,7 +68,7 @@
 	Type           string
 	macAddress     net.HardwareAddr
 	epOption       *endpointOption       // User specified parameters
-	epConnectivity *endpointConnectivity // User specified parameters
+	epConnectivity *EndpointConnectivity // User specified parameters
 	portMapping    []types.PortBinding   // Operation port bindings
 	addr           *net.IPNet
 	gateway        net.IP
@@ -95,7 +96,7 @@
 	errNotFound = "HNS failed with error : The object identifier does not represent a valid object. "
 )
 
-// IsBuiltinWindowsDriver vaidates if network-type is a builtin local-scoped driver
+// IsBuiltinLocalDriver validates if network-type is a builtin local-scoped driver
 func IsBuiltinLocalDriver(networkType string) bool {
 	if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "ics" == networkType || "transparent" == networkType {
 		return true
@@ -396,7 +397,8 @@
 	return qps, nil
 }
 
-func convertPortBindings(portBindings []types.PortBinding) ([]json.RawMessage, error) {
+// ConvertPortBindings converts PortBindings to JSON for HNS request
+func ConvertPortBindings(portBindings []types.PortBinding) ([]json.RawMessage, error) {
 	var pbs []json.RawMessage
 
 	// Enumerate through the port bindings specified by the user and convert
@@ -431,7 +433,8 @@
 	return pbs, nil
 }
 
-func parsePortBindingPolicies(policies []json.RawMessage) ([]types.PortBinding, error) {
+// ParsePortBindingPolicies parses HNS endpoint response message to PortBindings
+func ParsePortBindingPolicies(policies []json.RawMessage) ([]types.PortBinding, error) {
 	var bindings []types.PortBinding
 	hcsPolicy := &hcsshim.NatPolicy{}
 
@@ -505,12 +508,13 @@
 	return ec, nil
 }
 
-func parseEndpointConnectivity(epOptions map[string]interface{}) (*endpointConnectivity, error) {
+// ParseEndpointConnectivity parses options passed to CreateEndpoint, specifically port bindings, and store in a endpointConnectivity object.
+func ParseEndpointConnectivity(epOptions map[string]interface{}) (*EndpointConnectivity, error) {
 	if epOptions == nil {
 		return nil, nil
 	}
 
-	ec := &endpointConnectivity{}
+	ec := &EndpointConnectivity{}
 
 	if opt, ok := epOptions[netlabel.PortMap]; ok {
 		if bs, ok := opt.([]types.PortBinding); ok {
@@ -550,7 +554,7 @@
 	if err != nil {
 		return err
 	}
-	epConnectivity, err := parseEndpointConnectivity(epOptions)
+	epConnectivity, err := ParseEndpointConnectivity(epOptions)
 	if err != nil {
 		return err
 	}
@@ -561,7 +565,7 @@
 		endpointStruct.MacAddress = strings.Replace(macAddress.String(), ":", "-", -1)
 	}
 
-	endpointStruct.Policies, err = convertPortBindings(epConnectivity.PortBindings)
+	endpointStruct.Policies, err = ConvertPortBindings(epConnectivity.PortBindings)
 	if err != nil {
 		return err
 	}
@@ -615,7 +619,7 @@
 	endpoint.profileID = hnsresponse.Id
 	endpoint.epConnectivity = epConnectivity
 	endpoint.epOption = epOption
-	endpoint.portMapping, err = parsePortBindingPolicies(hnsresponse.Policies)
+	endpoint.portMapping, err = ParsePortBindingPolicies(hnsresponse.Policies)
 
 	if err != nil {
 		hcsshim.HNSEndpointRequest("DELETE", hnsresponse.Id, "")
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/windows_store.go b/vendor/github.com/docker/libnetwork/drivers/windows/windows_store.go
index bbed5ae..caa93c6 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/windows_store.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/windows_store.go
@@ -7,11 +7,11 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/endpoint.go b/vendor/github.com/docker/libnetwork/endpoint.go
index 111b747..a2d1dbc 100644
--- a/vendor/github.com/docker/libnetwork/endpoint.go
+++ b/vendor/github.com/docker/libnetwork/endpoint.go
@@ -8,12 +8,12 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // Endpoint represents a logical connection between a network and a sandbox.
@@ -75,6 +75,7 @@
 	dbIndex           uint64
 	dbExists          bool
 	serviceEnabled    bool
+	loadBalancer      bool
 	sync.Mutex
 }
 
@@ -101,6 +102,7 @@
 	epMap["virtualIP"] = ep.virtualIP.String()
 	epMap["ingressPorts"] = ep.ingressPorts
 	epMap["svcAliases"] = ep.svcAliases
+	epMap["loadBalancer"] = ep.loadBalancer
 
 	return json.Marshal(epMap)
 }
@@ -201,6 +203,10 @@
 		ep.virtualIP = net.ParseIP(vip.(string))
 	}
 
+	if v, ok := epMap["loadBalancer"]; ok {
+		ep.loadBalancer = v.(bool)
+	}
+
 	sal, _ := json.Marshal(epMap["svcAliases"])
 	var svcAliases []string
 	json.Unmarshal(sal, &svcAliases)
@@ -238,6 +244,7 @@
 	dstEp.svcName = ep.svcName
 	dstEp.svcID = ep.svcID
 	dstEp.virtualIP = ep.virtualIP
+	dstEp.loadBalancer = ep.loadBalancer
 
 	dstEp.svcAliases = make([]string, len(ep.svcAliases))
 	copy(dstEp.svcAliases, ep.svcAliases)
@@ -985,7 +992,7 @@
 	}
 }
 
-//CreateOptionAlias function returns an option setter for setting endpoint alias
+// CreateOptionAlias function returns an option setter for setting endpoint alias
 func CreateOptionAlias(name string, alias string) EndpointOption {
 	return func(ep *endpoint) {
 		if ep.aliases == nil {
@@ -1006,13 +1013,20 @@
 	}
 }
 
-//CreateOptionMyAlias function returns an option setter for setting endpoint's self alias
+// CreateOptionMyAlias function returns an option setter for setting endpoint's self alias
 func CreateOptionMyAlias(alias string) EndpointOption {
 	return func(ep *endpoint) {
 		ep.myAliases = append(ep.myAliases, alias)
 	}
 }
 
+// CreateOptionLoadBalancer function returns an option setter for denoting the endpoint is a load balancer for a network
+func CreateOptionLoadBalancer() EndpointOption {
+	return func(ep *endpoint) {
+		ep.loadBalancer = true
+	}
+}
+
 // JoinOptionPriority function returns an option setter for priority option to
 // be passed to the endpoint.Join() method.
 func JoinOptionPriority(ep Endpoint, prio int) EndpointOption {
diff --git a/vendor/github.com/docker/libnetwork/endpoint_info.go b/vendor/github.com/docker/libnetwork/endpoint_info.go
index 17e93b9..68d3e86 100644
--- a/vendor/github.com/docker/libnetwork/endpoint_info.go
+++ b/vendor/github.com/docker/libnetwork/endpoint_info.go
@@ -31,6 +31,9 @@
 
 	// Sandbox returns the attached sandbox if there, nil otherwise.
 	Sandbox() Sandbox
+
+	// LoadBalancer returns whether the endpoint is the load balancer endpoint for the network.
+	LoadBalancer() bool
 }
 
 // InterfaceInfo provides an interface to retrieve interface addresses bound to the endpoint.
@@ -199,11 +202,7 @@
 		return ep
 	}
 
-	if epi := sb.getEndpoint(ep.ID()); epi != nil {
-		return epi
-	}
-
-	return nil
+	return sb.getEndpoint(ep.ID())
 }
 
 func (ep *endpoint) Iface() InterfaceInfo {
@@ -327,6 +326,12 @@
 	return cnt
 }
 
+func (ep *endpoint) LoadBalancer() bool {
+	ep.Lock()
+	defer ep.Unlock()
+	return ep.loadBalancer
+}
+
 func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
 	ep.Lock()
 	defer ep.Unlock()
@@ -413,7 +418,7 @@
 		return err
 	}
 	if v, ok := epMap["gw"]; ok {
-		epj.gw6 = net.ParseIP(v.(string))
+		epj.gw = net.ParseIP(v.(string))
 	}
 	if v, ok := epMap["gw6"]; ok {
 		epj.gw6 = net.ParseIP(v.(string))
@@ -442,6 +447,6 @@
 	dstEpj.driverTableEntries = make([]*tableEntry, len(epj.driverTableEntries))
 	copy(dstEpj.driverTableEntries, epj.driverTableEntries)
 	dstEpj.gw = types.GetIPCopy(epj.gw)
-	dstEpj.gw = types.GetIPCopy(epj.gw6)
+	dstEpj.gw6 = types.GetIPCopy(epj.gw6)
 	return nil
 }
diff --git a/vendor/github.com/docker/libnetwork/firewall_linux.go b/vendor/github.com/docker/libnetwork/firewall_linux.go
index 8c27c1d..b2232ac 100644
--- a/vendor/github.com/docker/libnetwork/firewall_linux.go
+++ b/vendor/github.com/docker/libnetwork/firewall_linux.go
@@ -1,8 +1,8 @@
 package libnetwork
 
 import (
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/iptables"
+	"github.com/sirupsen/logrus"
 )
 
 const userChain = "DOCKER-USER"
diff --git a/vendor/github.com/docker/libnetwork/hostdiscovery/hostdiscovery.go b/vendor/github.com/docker/libnetwork/hostdiscovery/hostdiscovery.go
index a45ecb6..452b562 100644
--- a/vendor/github.com/docker/libnetwork/hostdiscovery/hostdiscovery.go
+++ b/vendor/github.com/docker/libnetwork/hostdiscovery/hostdiscovery.go
@@ -4,7 +4,7 @@
 	"net"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 
 	mapset "github.com/deckarep/golang-set"
 	"github.com/docker/docker/pkg/discovery"
diff --git a/vendor/github.com/docker/libnetwork/ipam/allocator.go b/vendor/github.com/docker/libnetwork/ipam/allocator.go
index b3876ff..c4ed9a0 100644
--- a/vendor/github.com/docker/libnetwork/ipam/allocator.go
+++ b/vendor/github.com/docker/libnetwork/ipam/allocator.go
@@ -6,13 +6,13 @@
 	"sort"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/bitseq"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/ipamutils"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -579,7 +579,7 @@
 		s = fmt.Sprintf("\n\n%s Config", as)
 		aSpace.Lock()
 		for k, config := range aSpace.subnets {
-			s = fmt.Sprintf("%s%s", s, fmt.Sprintf("\n%v: %v", k, config))
+			s += fmt.Sprintf("\n%v: %v", k, config)
 			if config.Range == nil {
 				a.retrieveBitmask(k, config.Pool)
 			}
@@ -589,7 +589,7 @@
 
 	s = fmt.Sprintf("%s\n\nBitmasks", s)
 	for k, bm := range a.addresses {
-		s = fmt.Sprintf("%s%s", s, fmt.Sprintf("\n%s: %s", k, bm))
+		s += fmt.Sprintf("\n%s: %s", k, bm)
 	}
 
 	return s
diff --git a/vendor/github.com/docker/libnetwork/ipam/store.go b/vendor/github.com/docker/libnetwork/ipam/store.go
index d05e1b7..124d585 100644
--- a/vendor/github.com/docker/libnetwork/ipam/store.go
+++ b/vendor/github.com/docker/libnetwork/ipam/store.go
@@ -3,9 +3,9 @@
 import (
 	"encoding/json"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // Key provides the Key to be used in KV Store
diff --git a/vendor/github.com/docker/libnetwork/ipams/remote/remote.go b/vendor/github.com/docker/libnetwork/ipams/remote/remote.go
index d2e2b4f..9f2f1d5 100644
--- a/vendor/github.com/docker/libnetwork/ipams/remote/remote.go
+++ b/vendor/github.com/docker/libnetwork/ipams/remote/remote.go
@@ -4,12 +4,12 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/ipams/remote/api"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 type allocator struct {
diff --git a/vendor/github.com/docker/libnetwork/ipams/windowsipam/windowsipam.go b/vendor/github.com/docker/libnetwork/ipams/windowsipam/windowsipam.go
index 6b124d4..9cf99d4 100644
--- a/vendor/github.com/docker/libnetwork/ipams/windowsipam/windowsipam.go
+++ b/vendor/github.com/docker/libnetwork/ipams/windowsipam/windowsipam.go
@@ -3,11 +3,11 @@
 import (
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/discoverapi"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/iptables/conntrack.go b/vendor/github.com/docker/libnetwork/iptables/conntrack.go
index 5731c53..08317c3 100644
--- a/vendor/github.com/docker/libnetwork/iptables/conntrack.go
+++ b/vendor/github.com/docker/libnetwork/iptables/conntrack.go
@@ -5,7 +5,7 @@
 	"net"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/iptables/firewalld.go b/vendor/github.com/docker/libnetwork/iptables/firewalld.go
index 7dc5127..c9838d5 100644
--- a/vendor/github.com/docker/libnetwork/iptables/firewalld.go
+++ b/vendor/github.com/docker/libnetwork/iptables/firewalld.go
@@ -4,8 +4,8 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/godbus/dbus"
+	"github.com/sirupsen/logrus"
 )
 
 // IPV defines the table string
diff --git a/vendor/github.com/docker/libnetwork/iptables/iptables.go b/vendor/github.com/docker/libnetwork/iptables/iptables.go
index caa202b..3e12005 100644
--- a/vendor/github.com/docker/libnetwork/iptables/iptables.go
+++ b/vendor/github.com/docker/libnetwork/iptables/iptables.go
@@ -10,7 +10,7 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 )
 
 // Action signifies the iptable action.
@@ -276,11 +276,7 @@
 		"--dport", strconv.Itoa(destPort),
 		"-j", "MASQUERADE",
 	}
-	if err := ProgramRule(Nat, "POSTROUTING", action, args); err != nil {
-		return err
-	}
-
-	return nil
+	return ProgramRule(Nat, "POSTROUTING", action, args)
 }
 
 // Link adds reciprocal ACCEPT rule for two supplied IP addresses.
@@ -301,10 +297,7 @@
 	// reverse
 	args[7], args[9] = args[9], args[7]
 	args[10] = "--sport"
-	if err := ProgramRule(Filter, c.Name, action, args); err != nil {
-		return err
-	}
-	return nil
+	return ProgramRule(Filter, c.Name, action, args)
 }
 
 // ProgramRule adds the rule specified by args only if the
diff --git a/vendor/github.com/docker/libnetwork/ipvs/ipvs.go b/vendor/github.com/docker/libnetwork/ipvs/ipvs.go
index a285e10..ebcdd80 100644
--- a/vendor/github.com/docker/libnetwork/ipvs/ipvs.go
+++ b/vendor/github.com/docker/libnetwork/ipvs/ipvs.go
@@ -116,6 +116,13 @@
 	return i.doCmd(s, nil, ipvsCmdDelService)
 }
 
+// Flush deletes all existing services in the passed
+// handle.
+func (i *Handle) Flush() error {
+	_, err := i.doCmdWithoutAttr(ipvsCmdFlush)
+	return err
+}
+
 // NewDestination creates a new real server in the passed ipvs
 // service which should already be existing in the passed handle.
 func (i *Handle) NewDestination(s *Service, d *Destination) error {
diff --git a/vendor/github.com/docker/libnetwork/ipvs/netlink.go b/vendor/github.com/docker/libnetwork/ipvs/netlink.go
index 5450679..2089283 100644
--- a/vendor/github.com/docker/libnetwork/ipvs/netlink.go
+++ b/vendor/github.com/docker/libnetwork/ipvs/netlink.go
@@ -14,7 +14,7 @@
 	"syscall"
 	"unsafe"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
 )
@@ -402,6 +402,13 @@
 	return res, nil
 }
 
+// doCmdWithoutAttr a simple wrapper of netlink socket execute command
+func (i *Handle) doCmdWithoutAttr(cmd uint8) ([][]byte, error) {
+	req := newIPVSRequest(cmd)
+	req.Seq = atomic.AddUint32(&i.seq, 1)
+	return execute(i.sock, req, 0)
+}
+
 func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) {
 
 	var d Destination
diff --git a/vendor/github.com/docker/libnetwork/network.go b/vendor/github.com/docker/libnetwork/network.go
index 72deeea..3f44553 100644
--- a/vendor/github.com/docker/libnetwork/network.go
+++ b/vendor/github.com/docker/libnetwork/network.go
@@ -8,7 +8,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/libnetwork/common"
 	"github.com/docker/libnetwork/config"
@@ -21,6 +20,7 @@
 	"github.com/docker/libnetwork/networkdb"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // A Network represents a logical connectivity zone that containers may
diff --git a/vendor/github.com/docker/libnetwork/network_windows.go b/vendor/github.com/docker/libnetwork/network_windows.go
index ddcd334..388b811 100644
--- a/vendor/github.com/docker/libnetwork/network_windows.go
+++ b/vendor/github.com/docker/libnetwork/network_windows.go
@@ -7,10 +7,10 @@
 	"time"
 
 	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/drivers/windows"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/ipams/windowsipam"
+	"github.com/sirupsen/logrus"
 )
 
 func executeInCompartment(compartmentID uint32, x func()) {
diff --git a/vendor/github.com/docker/libnetwork/networkdb/broadcast.go b/vendor/github.com/docker/libnetwork/networkdb/broadcast.go
index 3fe9f62..8317ed0 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/broadcast.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/broadcast.go
@@ -114,7 +114,8 @@
 }
 
 func (m *tableEventMessage) Invalidates(other memberlist.Broadcast) bool {
-	return false
+	otherm := other.(*tableEventMessage)
+	return m.tname == otherm.tname && m.id == otherm.id && m.key == otherm.key
 }
 
 func (m *tableEventMessage) Message() []byte {
@@ -133,6 +134,8 @@
 		TableName: tname,
 		Key:       key,
 		Value:     entry.value,
+		// The duration in second is a float that below would be truncated
+		ResidualReapTime: int32(entry.reapTime.Seconds()),
 	}
 
 	raw, err := encodeMessage(MessageTypeTableEvent, &tEvent)
diff --git a/vendor/github.com/docker/libnetwork/networkdb/cluster.go b/vendor/github.com/docker/libnetwork/networkdb/cluster.go
index e011a53..af6f5d9 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/cluster.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/cluster.go
@@ -12,16 +12,20 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/hashicorp/memberlist"
+	"github.com/sirupsen/logrus"
 )
 
 const (
-	reapInterval     = 30 * time.Minute
-	reapPeriod       = 5 * time.Second
-	retryInterval    = 1 * time.Second
-	nodeReapInterval = 24 * time.Hour
-	nodeReapPeriod   = 2 * time.Hour
+	// The garbage collection logic for entries leverage the presence of the network.
+	// For this reason the expiration time of the network is put slightly higher than the entry expiration so that
+	// there is at least 5 extra cycle to make sure that all the entries are properly deleted before deleting the network.
+	reapEntryInterval   = 30 * time.Minute
+	reapNetworkInterval = reapEntryInterval + 5*reapPeriod
+	reapPeriod          = 5 * time.Second
+	retryInterval       = 1 * time.Second
+	nodeReapInterval    = 24 * time.Hour
+	nodeReapPeriod      = 2 * time.Hour
 )
 
 type logWriter struct{}
@@ -290,13 +294,6 @@
 		return
 	}
 
-	// Update all the local table state to a new time to
-	// force update on the node we are trying to rejoin, just in
-	// case that node has these in deleting state still. This is
-	// facilitate fast convergence after recovering from a gossip
-	// failure.
-	nDB.updateLocalTableTime()
-
 	logrus.Debugf("Initiating bulk sync with node %s after reconnect", node.Name)
 	nDB.bulkSync([]string{node.Name}, true)
 }
@@ -307,8 +304,9 @@
 // the reaper runs. NOTE nDB.reapTableEntries updates the reapTime with a readlock. This
 // is safe as long as no other concurrent path touches the reapTime field.
 func (nDB *NetworkDB) reapState() {
-	nDB.reapNetworks()
+	// The reapTableEntries leverage the presence of the network so garbage collect entries first
 	nDB.reapTableEntries()
+	nDB.reapNetworks()
 }
 
 func (nDB *NetworkDB) reapNetworks() {
@@ -328,43 +326,51 @@
 }
 
 func (nDB *NetworkDB) reapTableEntries() {
-	var paths []string
-
+	var nodeNetworks []string
+	// This is best effort, if the list of network changes will be picked up in the next cycle
 	nDB.RLock()
-	nDB.indexes[byTable].Walk(func(path string, v interface{}) bool {
-		entry, ok := v.(*entry)
-		if !ok {
-			return false
-		}
-
-		if !entry.deleting {
-			return false
-		}
-		if entry.reapTime > 0 {
-			entry.reapTime -= reapPeriod
-			return false
-		}
-		paths = append(paths, path)
-		return false
-	})
+	for nid := range nDB.networks[nDB.config.NodeName] {
+		nodeNetworks = append(nodeNetworks, nid)
+	}
 	nDB.RUnlock()
 
-	nDB.Lock()
-	for _, path := range paths {
-		params := strings.Split(path[1:], "/")
-		tname := params[0]
-		nid := params[1]
-		key := params[2]
+	cycleStart := time.Now()
+	// In order to avoid blocking the database for a long time, apply the garbage collection logic by network
+	// The lock is taken at the beginning of the cycle and the deletion is inline
+	for _, nid := range nodeNetworks {
+		nDB.Lock()
+		nDB.indexes[byNetwork].WalkPrefix(fmt.Sprintf("/%s", nid), func(path string, v interface{}) bool {
+			// timeCompensation compensate in case the lock took some time to be released
+			timeCompensation := time.Since(cycleStart)
+			entry, ok := v.(*entry)
+			if !ok || !entry.deleting {
+				return false
+			}
 
-		if _, ok := nDB.indexes[byTable].Delete(fmt.Sprintf("/%s/%s/%s", tname, nid, key)); !ok {
-			logrus.Errorf("Could not delete entry in table %s with network id %s and key %s as it does not exist", tname, nid, key)
-		}
+			// In this check we are adding an extra 1 second to guarantee that when the number is truncated to int32 to fit the packet
+			// for the tableEvent the number is always strictly > 1 and never 0
+			if entry.reapTime > reapPeriod+timeCompensation+time.Second {
+				entry.reapTime -= reapPeriod + timeCompensation
+				return false
+			}
 
-		if _, ok := nDB.indexes[byNetwork].Delete(fmt.Sprintf("/%s/%s/%s", nid, tname, key)); !ok {
-			logrus.Errorf("Could not delete entry in network %s with table name %s and key %s as it does not exist", nid, tname, key)
-		}
+			params := strings.Split(path[1:], "/")
+			nid := params[0]
+			tname := params[1]
+			key := params[2]
+
+			okTable, okNetwork := nDB.deleteEntry(nid, tname, key)
+			if !okTable {
+				logrus.Errorf("Table tree delete failed, entry with key:%s does not exists in the table:%s network:%s", key, tname, nid)
+			}
+			if !okNetwork {
+				logrus.Errorf("Network tree delete failed, entry with key:%s does not exists in the network:%s table:%s", key, nid, tname)
+			}
+
+			return false
+		})
+		nDB.Unlock()
 	}
-	nDB.Unlock()
 }
 
 func (nDB *NetworkDB) gossip() {
@@ -413,8 +419,9 @@
 		// Collect stats and print the queue info, note this code is here also to have a view of the queues empty
 		network.qMessagesSent += len(msgs)
 		if printStats {
-			logrus.Infof("NetworkDB stats - Queue net:%s qLen:%d netPeers:%d netMsg/s:%d",
-				nid, broadcastQ.NumQueued(), broadcastQ.NumNodes(), network.qMessagesSent/int((nDB.config.StatsPrintPeriod/time.Second)))
+			logrus.Infof("NetworkDB stats - netID:%s leaving:%t netPeers:%d entries:%d Queue qLen:%d netMsg/s:%d",
+				nid, network.leaving, broadcastQ.NumNodes(), network.entriesNumber, broadcastQ.NumQueued(),
+				network.qMessagesSent/int((nDB.config.StatsPrintPeriod/time.Second)))
 			network.qMessagesSent = 0
 		}
 
@@ -579,6 +586,8 @@
 				TableName: params[1],
 				Key:       params[2],
 				Value:     entry.value,
+				// The duration in second is a float that below would be truncated
+				ResidualReapTime: int32(entry.reapTime.Seconds()),
 			}
 
 			msg, err := encodeMessage(MessageTypeTableEvent, &tEvent)
diff --git a/vendor/github.com/docker/libnetwork/networkdb/delegate.go b/vendor/github.com/docker/libnetwork/networkdb/delegate.go
index b3ef000..28919cf 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/delegate.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/delegate.go
@@ -1,12 +1,12 @@
 package networkdb
 
 import (
-	"fmt"
 	"net"
 	"strings"
+	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/gogo/protobuf/proto"
+	"github.com/sirupsen/logrus"
 )
 
 type delegate struct {
@@ -104,6 +104,9 @@
 	}
 
 	n = nDB.checkAndGetNode(nEvent)
+	if n == nil {
+		return false
+	}
 
 	nDB.purgeSameNode(n)
 	n.ltime = nEvent.LTime
@@ -130,25 +133,12 @@
 }
 
 func (nDB *NetworkDB) handleNetworkEvent(nEvent *NetworkEvent) bool {
-	var flushEntries bool
 	// Update our local clock if the received messages has newer
 	// time.
 	nDB.networkClock.Witness(nEvent.LTime)
 
 	nDB.Lock()
-	defer func() {
-		nDB.Unlock()
-		// When a node leaves a network on the last task removal cleanup the
-		// local entries for this network & node combination. When the tasks
-		// on a network are removed we could have missed the gossip updates.
-		// Not doing this cleanup can leave stale entries because bulksyncs
-		// from the node will no longer include this network state.
-		//
-		// deleteNodeNetworkEntries takes nDB lock.
-		if flushEntries {
-			nDB.deleteNodeNetworkEntries(nEvent.NetworkID, nEvent.NodeName)
-		}
-	}()
+	defer nDB.Unlock()
 
 	if nEvent.NodeName == nDB.config.NodeName {
 		return false
@@ -175,8 +165,13 @@
 		n.ltime = nEvent.LTime
 		n.leaving = nEvent.Type == NetworkEventTypeLeave
 		if n.leaving {
-			n.reapTime = reapInterval
-			flushEntries = true
+			n.reapTime = reapNetworkInterval
+
+			// The remote node is leaving the network, but not the gossip cluster.
+			// Mark all its entries in deleted state, this will guarantee that
+			// if some node bulk sync with us, the deleted state of
+			// these entries will be propagated.
+			nDB.deleteNodeNetworkEntries(nEvent.NetworkID, nEvent.NodeName)
 		}
 
 		if nEvent.Type == NetworkEventTypeLeave {
@@ -203,25 +198,29 @@
 }
 
 func (nDB *NetworkDB) handleTableEvent(tEvent *TableEvent) bool {
-	// Update our local clock if the received messages has newer
-	// time.
+	// Update our local clock if the received messages has newer time.
 	nDB.tableClock.Witness(tEvent.LTime)
 
 	// Ignore the table events for networks that are in the process of going away
 	nDB.RLock()
 	networks := nDB.networks[nDB.config.NodeName]
 	network, ok := networks[tEvent.NetworkID]
-	nDB.RUnlock()
-	if !ok || network.leaving {
-		return true
+	// Check if the owner of the event is still part of the network
+	nodes := nDB.networkNodes[tEvent.NetworkID]
+	var nodePresent bool
+	for _, node := range nodes {
+		if node == tEvent.NodeName {
+			nodePresent = true
+			break
+		}
 	}
-
-	e, err := nDB.getEntry(tEvent.TableName, tEvent.NetworkID, tEvent.Key)
-	if err != nil && tEvent.Type == TableEventTypeDelete {
-		// If it is a delete event and we don't have the entry here nothing to do.
+	nDB.RUnlock()
+	if !ok || network.leaving || !nodePresent {
+		// I'm out of the network OR the event owner is not anymore part of the network so do not propagate
 		return false
 	}
 
+	e, err := nDB.getEntry(tEvent.TableName, tEvent.NetworkID, tEvent.Key)
 	if err == nil {
 		// We have the latest state. Ignore the event
 		// since it is stale.
@@ -235,17 +234,28 @@
 		node:     tEvent.NodeName,
 		value:    tEvent.Value,
 		deleting: tEvent.Type == TableEventTypeDelete,
+		reapTime: time.Duration(tEvent.ResidualReapTime) * time.Second,
 	}
 
-	if e.deleting {
-		e.reapTime = reapInterval
+	// All the entries marked for deletion should have a reapTime set greater than 0
+	// This case can happen if the cluster is running different versions of the engine where the old version does not have the
+	// field. If that is not the case, this can be a BUG
+	if e.deleting && e.reapTime == 0 {
+		logrus.Warnf("handleTableEvent object %+v has a 0 reapTime, is the cluster running the same docker engine version?", tEvent)
+		e.reapTime = reapEntryInterval
 	}
 
 	nDB.Lock()
-	nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.TableName, tEvent.NetworkID, tEvent.Key), e)
-	nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", tEvent.NetworkID, tEvent.TableName, tEvent.Key), e)
+	nDB.createOrUpdateEntry(tEvent.NetworkID, tEvent.TableName, tEvent.Key, e)
 	nDB.Unlock()
 
+	if err != nil && tEvent.Type == TableEventTypeDelete {
+		// If it is a delete event and we did not have a state for it, don't propagate to the application
+		// If the residual reapTime is lower or equal to 1/6 of the total reapTime don't bother broadcasting it around
+		// most likely the cluster is already aware of it, if not who will sync with this node will catch the state too.
+		return e.reapTime > reapPeriod/6
+	}
+
 	var op opType
 	switch tEvent.Type {
 	case TableEventTypeCreate:
@@ -286,8 +296,7 @@
 		return
 	}
 
-	// Do not rebroadcast a bulk sync
-	if rebroadcast := nDB.handleTableEvent(&tEvent); rebroadcast && !isBulkSync {
+	if rebroadcast := nDB.handleTableEvent(&tEvent); rebroadcast {
 		var err error
 		buf, err = encodeRawMessage(MessageTypeTableEvent, buf)
 		if err != nil {
@@ -299,22 +308,17 @@
 		n, ok := nDB.networks[nDB.config.NodeName][tEvent.NetworkID]
 		nDB.RUnlock()
 
-		if !ok {
+		// if the network is not there anymore, OR we are leaving the network OR the broadcast queue is not present
+		if !ok || n.leaving || n.tableBroadcasts == nil {
 			return
 		}
 
-		broadcastQ := n.tableBroadcasts
-
-		if broadcastQ == nil {
-			return
-		}
-
-		broadcastQ.QueueBroadcast(&tableEventMessage{
+		n.tableBroadcasts.QueueBroadcast(&tableEventMessage{
 			msg:   buf,
 			id:    tEvent.NetworkID,
 			tname: tEvent.TableName,
 			key:   tEvent.Key,
-			node:  nDB.config.NodeName,
+			node:  tEvent.NodeName,
 		})
 	}
 }
diff --git a/vendor/github.com/docker/libnetwork/networkdb/event_delegate.go b/vendor/github.com/docker/libnetwork/networkdb/event_delegate.go
index 23e1683..74aa465 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/event_delegate.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/event_delegate.go
@@ -4,8 +4,8 @@
 	"encoding/json"
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/hashicorp/memberlist"
+	"github.com/sirupsen/logrus"
 )
 
 type eventDelegate struct {
@@ -45,9 +45,12 @@
 	var failed bool
 	logrus.Infof("Node %s/%s, left gossip cluster", mn.Name, mn.Addr)
 	e.broadcastNodeEvent(mn.Addr, opDelete)
-	e.nDB.deleteNodeTableEntries(mn.Name)
-	e.nDB.deleteNetworkEntriesForNode(mn.Name)
+	// The node left or failed, delete all the entries created by it.
+	// If the node was temporary down, deleting the entries will guarantee that the CREATE events will be accepted
+	// If the node instead left because was going down, then it makes sense to just delete all its state
 	e.nDB.Lock()
+	e.nDB.deleteNetworkEntriesForNode(mn.Name)
+	e.nDB.deleteNodeTableEntries(mn.Name)
 	if n, ok := e.nDB.nodes[mn.Name]; ok {
 		delete(e.nDB.nodes, mn.Name)
 
@@ -61,7 +64,6 @@
 	if failed {
 		logrus.Infof("Node %s/%s, added to failed nodes list", mn.Name, mn.Addr)
 	}
-
 }
 
 func (e *eventDelegate) NotifyUpdate(n *memberlist.Node) {
diff --git a/vendor/github.com/docker/libnetwork/networkdb/networkdb.go b/vendor/github.com/docker/libnetwork/networkdb/networkdb.go
index e4cc9df..afdf32e 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/networkdb.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/networkdb.go
@@ -10,12 +10,12 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/armon/go-radix"
 	"github.com/docker/go-events"
 	"github.com/docker/libnetwork/types"
 	"github.com/hashicorp/memberlist"
 	"github.com/hashicorp/serf/serf"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -108,6 +108,11 @@
 	IP   string
 }
 
+// PeerClusterInfo represents the peer (gossip cluster) nodes
+type PeerClusterInfo struct {
+	PeerInfo
+}
+
 type node struct {
 	memberlist.Node
 	ltime serf.LamportTime
@@ -136,6 +141,11 @@
 
 	// Number of gossip messages sent related to this network during the last stats collection period
 	qMessagesSent int
+
+	// Number of entries on the network. This value is the sum of all the entries of all the tables of a specific network.
+	// Its use is for statistics purposes. It keep tracks of database size and is printed per network every StatsPrintPeriod
+	// interval
+	entriesNumber int
 }
 
 // Config represents the configuration of the networdb instance and
@@ -253,6 +263,20 @@
 	}
 }
 
+// ClusterPeers returns all the gossip cluster peers.
+func (nDB *NetworkDB) ClusterPeers() []PeerInfo {
+	nDB.RLock()
+	defer nDB.RUnlock()
+	peers := make([]PeerInfo, 0, len(nDB.nodes))
+	for _, node := range nDB.nodes {
+		peers = append(peers, PeerInfo{
+			Name: node.Name,
+			IP:   node.Node.Addr.String(),
+		})
+	}
+	return peers
+}
+
 // Peers returns the gossip peers for a given network.
 func (nDB *NetworkDB) Peers(nid string) []PeerInfo {
 	nDB.RLock()
@@ -319,8 +343,7 @@
 	}
 
 	nDB.Lock()
-	nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry)
-	nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry)
+	nDB.createOrUpdateEntry(nid, tname, key, entry)
 	nDB.Unlock()
 
 	return nil
@@ -346,8 +369,7 @@
 	}
 
 	nDB.Lock()
-	nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry)
-	nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry)
+	nDB.createOrUpdateEntry(nid, tname, key, entry)
 	nDB.Unlock()
 
 	return nil
@@ -383,7 +405,7 @@
 		node:     nDB.config.NodeName,
 		value:    value,
 		deleting: true,
-		reapTime: reapInterval,
+		reapTime: reapEntryInterval,
 	}
 
 	if err := nDB.sendTableEvent(TableEventTypeDelete, nid, tname, key, entry); err != nil {
@@ -391,15 +413,13 @@
 	}
 
 	nDB.Lock()
-	nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry)
-	nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry)
+	nDB.createOrUpdateEntry(nid, tname, key, entry)
 	nDB.Unlock()
 
 	return nil
 }
 
 func (nDB *NetworkDB) deleteNetworkEntriesForNode(deletedNode string) {
-	nDB.Lock()
 	for nid, nodes := range nDB.networkNodes {
 		updatedNodes := make([]string, 0, len(nodes))
 		for _, node := range nodes {
@@ -414,11 +434,25 @@
 	}
 
 	delete(nDB.networks, deletedNode)
-	nDB.Unlock()
 }
 
+// deleteNodeNetworkEntries is called in 2 conditions with 2 different outcomes:
+// 1) when a notification is coming of a node leaving the network
+//		- Walk all the network entries and mark the leaving node's entries for deletion
+//			These will be garbage collected when the reap timer will expire
+// 2) when the local node is leaving the network
+//		- Walk all the network entries:
+//			A) if the entry is owned by the local node
+//		  then we will mark it for deletion. This will ensure that if a node did not
+//		  yet received the notification that the local node is leaving, will be aware
+//		  of the entries to be deleted.
+//			B) if the entry is owned by a remote node, then we can safely delete it. This
+//			ensures that if we join back this network as we receive the CREATE event for
+//		  entries owned by remote nodes, we will accept them and we notify the application
 func (nDB *NetworkDB) deleteNodeNetworkEntries(nid, node string) {
-	nDB.Lock()
+	// Indicates if the delete is triggered for the local node
+	isNodeLocal := node == nDB.config.NodeName
+
 	nDB.indexes[byNetwork].WalkPrefix(fmt.Sprintf("/%s", nid),
 		func(path string, v interface{}) bool {
 			oldEntry := v.(*entry)
@@ -427,29 +461,47 @@
 			tname := params[1]
 			key := params[2]
 
-			if oldEntry.node != node {
+			// If the entry is owned by a remote node and this node is not leaving the network
+			if oldEntry.node != node && !isNodeLocal {
+				// Don't do anything because the event is triggered for a node that does not own this entry
+				return false
+			}
+
+			// If this entry is already marked for deletion and this node is not leaving the network
+			if oldEntry.deleting && !isNodeLocal {
+				// Don't do anything this entry will be already garbage collected using the old reapTime
 				return false
 			}
 
 			entry := &entry{
 				ltime:    oldEntry.ltime,
-				node:     node,
+				node:     oldEntry.node,
 				value:    oldEntry.value,
 				deleting: true,
-				reapTime: reapInterval,
+				reapTime: reapEntryInterval,
 			}
 
-			nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry)
-			nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry)
+			// we arrived at this point in 2 cases:
+			// 1) this entry is owned by the node that is leaving the network
+			// 2) the local node is leaving the network
+			if oldEntry.node == node {
+				if isNodeLocal {
+					// TODO fcrisciani: this can be removed if there is no way to leave the network
+					// without doing a delete of all the objects
+					entry.ltime++
+				}
+				nDB.createOrUpdateEntry(nid, tname, key, entry)
+			} else {
+				// the local node is leaving the network, all the entries of remote nodes can be safely removed
+				nDB.deleteEntry(nid, tname, key)
+			}
 
 			nDB.broadcaster.Write(makeEvent(opDelete, tname, nid, key, entry.value))
 			return false
 		})
-	nDB.Unlock()
 }
 
 func (nDB *NetworkDB) deleteNodeTableEntries(node string) {
-	nDB.Lock()
 	nDB.indexes[byTable].Walk(func(path string, v interface{}) bool {
 		oldEntry := v.(*entry)
 		if oldEntry.node != node {
@@ -461,27 +513,17 @@
 		nid := params[1]
 		key := params[2]
 
-		entry := &entry{
-			ltime:    oldEntry.ltime,
-			node:     node,
-			value:    oldEntry.value,
-			deleting: true,
-			reapTime: reapInterval,
-		}
+		nDB.deleteEntry(nid, tname, key)
 
-		nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry)
-		nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry)
-
-		nDB.broadcaster.Write(makeEvent(opDelete, tname, nid, key, entry.value))
+		nDB.broadcaster.Write(makeEvent(opDelete, tname, nid, key, oldEntry.value))
 		return false
 	})
-	nDB.Unlock()
 }
 
 // WalkTable walks a single table in NetworkDB and invokes the passed
 // function for each entry in the table passing the network, key,
 // value. The walk stops if the passed function returns a true.
-func (nDB *NetworkDB) WalkTable(tname string, fn func(string, string, []byte) bool) error {
+func (nDB *NetworkDB) WalkTable(tname string, fn func(string, string, []byte, bool) bool) error {
 	nDB.RLock()
 	values := make(map[string]interface{})
 	nDB.indexes[byTable].WalkPrefix(fmt.Sprintf("/%s", tname), func(path string, v interface{}) bool {
@@ -494,7 +536,7 @@
 		params := strings.Split(k[1:], "/")
 		nid := params[1]
 		key := params[2]
-		if fn(nid, key, v.(*entry).value) {
+		if fn(nid, key, v.(*entry).value, v.(*entry).deleting) {
 			return nil
 		}
 	}
@@ -515,7 +557,12 @@
 		nodeNetworks = make(map[string]*network)
 		nDB.networks[nDB.config.NodeName] = nodeNetworks
 	}
-	nodeNetworks[nid] = &network{id: nid, ltime: ltime}
+	n, ok := nodeNetworks[nid]
+	var entries int
+	if ok {
+		entries = n.entriesNumber
+	}
+	nodeNetworks[nid] = &network{id: nid, ltime: ltime, entriesNumber: entries}
 	nodeNetworks[nid].tableBroadcasts = &memberlist.TransmitLimitedQueue{
 		NumNodes: func() int {
 			nDB.RLock()
@@ -524,6 +571,7 @@
 		},
 		RetransmitMult: 4,
 	}
+
 	nDB.addNetworkNode(nid, nDB.config.NodeName)
 	networkNodes := nDB.networkNodes[nid]
 	nDB.Unlock()
@@ -554,37 +602,12 @@
 
 	nDB.Lock()
 	defer nDB.Unlock()
-	var (
-		paths   []string
-		entries []*entry
-	)
 
+	// Remove myself from the list of the nodes participating to the network
 	nDB.deleteNetworkNode(nid, nDB.config.NodeName)
 
-	nwWalker := func(path string, v interface{}) bool {
-		entry, ok := v.(*entry)
-		if !ok {
-			return false
-		}
-		paths = append(paths, path)
-		entries = append(entries, entry)
-		return false
-	}
-
-	nDB.indexes[byNetwork].WalkPrefix(fmt.Sprintf("/%s", nid), nwWalker)
-	for _, path := range paths {
-		params := strings.Split(path[1:], "/")
-		tname := params[1]
-		key := params[2]
-
-		if _, ok := nDB.indexes[byTable].Delete(fmt.Sprintf("/%s/%s/%s", tname, nid, key)); !ok {
-			logrus.Errorf("Could not delete entry in table %s with network id %s and key %s as it does not exist", tname, nid, key)
-		}
-
-		if _, ok := nDB.indexes[byNetwork].Delete(fmt.Sprintf("/%s/%s/%s", nid, tname, key)); !ok {
-			logrus.Errorf("Could not delete entry in network %s with table name %s and key %s as it does not exist", nid, tname, key)
-		}
-	}
+	// Update all the local entries marking them for deletion and delete all the remote entries
+	nDB.deleteNodeNetworkEntries(nid, nDB.config.NodeName)
 
 	nodeNetworks, ok := nDB.networks[nDB.config.NodeName]
 	if !ok {
@@ -596,7 +619,9 @@
 		return fmt.Errorf("could not find network %s while trying to leave", nid)
 	}
 
+	logrus.Debugf("%s: leaving network %s", nDB.config.NodeName, nid)
 	n.ltime = ltime
+	n.reapTime = reapNetworkInterval
 	n.leaving = true
 	return nil
 }
@@ -661,26 +686,32 @@
 	}
 }
 
-func (nDB *NetworkDB) updateLocalTableTime() {
-	nDB.Lock()
-	defer nDB.Unlock()
-
-	ltime := nDB.tableClock.Increment()
-	nDB.indexes[byTable].Walk(func(path string, v interface{}) bool {
-		entry := v.(*entry)
-		if entry.node != nDB.config.NodeName {
-			return false
+// createOrUpdateEntry this function handles the creation or update of entries into the local
+// tree store. It is also used to keep in sync the entries number of the network (all tables are aggregated)
+func (nDB *NetworkDB) createOrUpdateEntry(nid, tname, key string, entry interface{}) (bool, bool) {
+	_, okTable := nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry)
+	_, okNetwork := nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry)
+	if !okNetwork {
+		// Add only if it is an insert not an update
+		n, ok := nDB.networks[nDB.config.NodeName][nid]
+		if ok {
+			n.entriesNumber++
 		}
+	}
+	return okTable, okNetwork
+}
 
-		params := strings.Split(path[1:], "/")
-		tname := params[0]
-		nid := params[1]
-		key := params[2]
-		entry.ltime = ltime
-
-		nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry)
-		nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry)
-
-		return false
-	})
+// deleteEntry this function handles the deletion of entries into the local tree store.
+// It is also used to keep in sync the entries number of the network (all tables are aggregated)
+func (nDB *NetworkDB) deleteEntry(nid, tname, key string) (bool, bool) {
+	_, okTable := nDB.indexes[byTable].Delete(fmt.Sprintf("/%s/%s/%s", tname, nid, key))
+	_, okNetwork := nDB.indexes[byNetwork].Delete(fmt.Sprintf("/%s/%s/%s", nid, tname, key))
+	if okNetwork {
+		// Remove only if the delete is successful
+		n, ok := nDB.networks[nDB.config.NodeName][nid]
+		if ok {
+			n.entriesNumber--
+		}
+	}
+	return okTable, okNetwork
 }
diff --git a/vendor/github.com/docker/libnetwork/networkdb/networkdb.pb.go b/vendor/github.com/docker/libnetwork/networkdb/networkdb.pb.go
index dfbc713..7087a57 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/networkdb.pb.go
+++ b/vendor/github.com/docker/libnetwork/networkdb/networkdb.pb.go
@@ -1,6 +1,5 @@
-// Code generated by protoc-gen-gogo.
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: networkdb.proto
-// DO NOT EDIT!
 
 /*
 	Package networkdb is a generated protocol buffer package.
@@ -28,9 +27,6 @@
 import github_com_hashicorp_serf_serf "github.com/hashicorp/serf/serf"
 
 import strings "strings"
-import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
-import sort "sort"
-import strconv "strconv"
 import reflect "reflect"
 
 import io "io"
@@ -42,7 +38,9 @@
 
 // This is a compile-time assertion to ensure that this generated file
 // is compatible with the proto package it is being compiled against.
-const _ = proto.GoGoProtoPackageIsVersion1
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
 
 // MessageType enum defines all the core message types that networkdb
 // uses to communicate to peers.
@@ -192,6 +190,20 @@
 func (*GossipMessage) ProtoMessage()               {}
 func (*GossipMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{0} }
 
+func (m *GossipMessage) GetType() MessageType {
+	if m != nil {
+		return m.Type
+	}
+	return MessageTypeInvalid
+}
+
+func (m *GossipMessage) GetData() []byte {
+	if m != nil {
+		return m.Data
+	}
+	return nil
+}
+
 // NodeEvent message payload definition.
 type NodeEvent struct {
 	Type NodeEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=networkdb.NodeEvent_Type" json:"type,omitempty"`
@@ -207,6 +219,20 @@
 func (*NodeEvent) ProtoMessage()               {}
 func (*NodeEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{1} }
 
+func (m *NodeEvent) GetType() NodeEvent_Type {
+	if m != nil {
+		return m.Type
+	}
+	return NodeEventTypeInvalid
+}
+
+func (m *NodeEvent) GetNodeName() string {
+	if m != nil {
+		return m.NodeName
+	}
+	return ""
+}
+
 // NetworkEvent message payload definition.
 type NetworkEvent struct {
 	Type NetworkEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=networkdb.NetworkEvent_Type" json:"type,omitempty"`
@@ -224,6 +250,27 @@
 func (*NetworkEvent) ProtoMessage()               {}
 func (*NetworkEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{2} }
 
+func (m *NetworkEvent) GetType() NetworkEvent_Type {
+	if m != nil {
+		return m.Type
+	}
+	return NetworkEventTypeInvalid
+}
+
+func (m *NetworkEvent) GetNodeName() string {
+	if m != nil {
+		return m.NodeName
+	}
+	return ""
+}
+
+func (m *NetworkEvent) GetNetworkID() string {
+	if m != nil {
+		return m.NetworkID
+	}
+	return ""
+}
+
 // NetworkEntry for push pull of networks.
 type NetworkEntry struct {
 	// ID of the network
@@ -241,6 +288,27 @@
 func (*NetworkEntry) ProtoMessage()               {}
 func (*NetworkEntry) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{3} }
 
+func (m *NetworkEntry) GetNetworkID() string {
+	if m != nil {
+		return m.NetworkID
+	}
+	return ""
+}
+
+func (m *NetworkEntry) GetNodeName() string {
+	if m != nil {
+		return m.NodeName
+	}
+	return ""
+}
+
+func (m *NetworkEntry) GetLeaving() bool {
+	if m != nil {
+		return m.Leaving
+	}
+	return false
+}
+
 // NetworkPushpull message payload definition.
 type NetworkPushPull struct {
 	// Lamport time when this push pull was initiated.
@@ -261,6 +329,13 @@
 	return nil
 }
 
+func (m *NetworkPushPull) GetNodeName() string {
+	if m != nil {
+		return m.NodeName
+	}
+	return ""
+}
+
 // TableEvent message payload definition.
 type TableEvent struct {
 	Type TableEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=networkdb.TableEvent_Type" json:"type,omitempty"`
@@ -276,12 +351,63 @@
 	Key string `protobuf:"bytes,6,opt,name=key,proto3" json:"key,omitempty"`
 	// Entry value.
 	Value []byte `protobuf:"bytes,7,opt,name=value,proto3" json:"value,omitempty"`
+	// Residual reap time for the entry before getting deleted in seconds
+	ResidualReapTime int32 `protobuf:"varint,8,opt,name=residual_reap_time,json=residualReapTime,proto3" json:"residual_reap_time,omitempty"`
 }
 
 func (m *TableEvent) Reset()                    { *m = TableEvent{} }
 func (*TableEvent) ProtoMessage()               {}
 func (*TableEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{5} }
 
+func (m *TableEvent) GetType() TableEvent_Type {
+	if m != nil {
+		return m.Type
+	}
+	return TableEventTypeInvalid
+}
+
+func (m *TableEvent) GetNodeName() string {
+	if m != nil {
+		return m.NodeName
+	}
+	return ""
+}
+
+func (m *TableEvent) GetNetworkID() string {
+	if m != nil {
+		return m.NetworkID
+	}
+	return ""
+}
+
+func (m *TableEvent) GetTableName() string {
+	if m != nil {
+		return m.TableName
+	}
+	return ""
+}
+
+func (m *TableEvent) GetKey() string {
+	if m != nil {
+		return m.Key
+	}
+	return ""
+}
+
+func (m *TableEvent) GetValue() []byte {
+	if m != nil {
+		return m.Value
+	}
+	return nil
+}
+
+func (m *TableEvent) GetResidualReapTime() int32 {
+	if m != nil {
+		return m.ResidualReapTime
+	}
+	return 0
+}
+
 // BulkSync message payload definition.
 type BulkSyncMessage struct {
 	// Lamport time when this bulk sync was initiated.
@@ -302,6 +428,34 @@
 func (*BulkSyncMessage) ProtoMessage()               {}
 func (*BulkSyncMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{6} }
 
+func (m *BulkSyncMessage) GetUnsolicited() bool {
+	if m != nil {
+		return m.Unsolicited
+	}
+	return false
+}
+
+func (m *BulkSyncMessage) GetNodeName() string {
+	if m != nil {
+		return m.NodeName
+	}
+	return ""
+}
+
+func (m *BulkSyncMessage) GetNetworks() []string {
+	if m != nil {
+		return m.Networks
+	}
+	return nil
+}
+
+func (m *BulkSyncMessage) GetPayload() []byte {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
 // Compound message payload definition.
 type CompoundMessage struct {
 	// A list of simple messages.
@@ -322,7 +476,7 @@
 type CompoundMessage_SimpleMessage struct {
 	// Bytestring payload of a message constructed using
 	// other message type definitions.
-	Payload []byte `protobuf:"bytes,1,opt,name=Payload,json=payload,proto3" json:"Payload,omitempty"`
+	Payload []byte `protobuf:"bytes,1,opt,name=Payload,proto3" json:"Payload,omitempty"`
 }
 
 func (m *CompoundMessage_SimpleMessage) Reset()      { *m = CompoundMessage_SimpleMessage{} }
@@ -331,6 +485,13 @@
 	return fileDescriptorNetworkdb, []int{7, 0}
 }
 
+func (m *CompoundMessage_SimpleMessage) GetPayload() []byte {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
 func init() {
 	proto.RegisterType((*GossipMessage)(nil), "networkdb.GossipMessage")
 	proto.RegisterType((*NodeEvent)(nil), "networkdb.NodeEvent")
@@ -413,7 +574,7 @@
 	if this == nil {
 		return "nil"
 	}
-	s := make([]string, 0, 11)
+	s := make([]string, 0, 12)
 	s = append(s, "&networkdb.TableEvent{")
 	s = append(s, "Type: "+fmt.Sprintf("%#v", this.Type)+",\n")
 	s = append(s, "LTime: "+fmt.Sprintf("%#v", this.LTime)+",\n")
@@ -422,6 +583,7 @@
 	s = append(s, "TableName: "+fmt.Sprintf("%#v", this.TableName)+",\n")
 	s = append(s, "Key: "+fmt.Sprintf("%#v", this.Key)+",\n")
 	s = append(s, "Value: "+fmt.Sprintf("%#v", this.Value)+",\n")
+	s = append(s, "ResidualReapTime: "+fmt.Sprintf("%#v", this.ResidualReapTime)+",\n")
 	s = append(s, "}")
 	return strings.Join(s, "")
 }
@@ -469,197 +631,180 @@
 	pv := reflect.Indirect(rv).Interface()
 	return fmt.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
 }
-func extensionToGoStringNetworkdb(e map[int32]github_com_gogo_protobuf_proto.Extension) string {
-	if e == nil {
-		return "nil"
-	}
-	s := "map[int32]proto.Extension{"
-	keys := make([]int, 0, len(e))
-	for k := range e {
-		keys = append(keys, int(k))
-	}
-	sort.Ints(keys)
-	ss := []string{}
-	for _, k := range keys {
-		ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
-	}
-	s += strings.Join(ss, ",") + "}"
-	return s
-}
-func (m *GossipMessage) Marshal() (data []byte, err error) {
+func (m *GossipMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *GossipMessage) MarshalTo(data []byte) (int, error) {
+func (m *GossipMessage) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if m.Type != 0 {
-		data[i] = 0x8
+		dAtA[i] = 0x8
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.Type))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
 	}
 	if len(m.Data) > 0 {
-		data[i] = 0x12
+		dAtA[i] = 0x12
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.Data)))
-		i += copy(data[i:], m.Data)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Data)))
+		i += copy(dAtA[i:], m.Data)
 	}
 	return i, nil
 }
 
-func (m *NodeEvent) Marshal() (data []byte, err error) {
+func (m *NodeEvent) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *NodeEvent) MarshalTo(data []byte) (int, error) {
+func (m *NodeEvent) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if m.Type != 0 {
-		data[i] = 0x8
+		dAtA[i] = 0x8
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.Type))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
 	}
 	if m.LTime != 0 {
-		data[i] = 0x10
+		dAtA[i] = 0x10
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.LTime))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
 	}
 	if len(m.NodeName) > 0 {
-		data[i] = 0x1a
+		dAtA[i] = 0x1a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName)))
-		i += copy(data[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i += copy(dAtA[i:], m.NodeName)
 	}
 	return i, nil
 }
 
-func (m *NetworkEvent) Marshal() (data []byte, err error) {
+func (m *NetworkEvent) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *NetworkEvent) MarshalTo(data []byte) (int, error) {
+func (m *NetworkEvent) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if m.Type != 0 {
-		data[i] = 0x8
+		dAtA[i] = 0x8
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.Type))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
 	}
 	if m.LTime != 0 {
-		data[i] = 0x10
+		dAtA[i] = 0x10
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.LTime))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
 	}
 	if len(m.NodeName) > 0 {
-		data[i] = 0x1a
+		dAtA[i] = 0x1a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName)))
-		i += copy(data[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i += copy(dAtA[i:], m.NodeName)
 	}
 	if len(m.NetworkID) > 0 {
-		data[i] = 0x22
+		dAtA[i] = 0x22
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NetworkID)))
-		i += copy(data[i:], m.NetworkID)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
+		i += copy(dAtA[i:], m.NetworkID)
 	}
 	return i, nil
 }
 
-func (m *NetworkEntry) Marshal() (data []byte, err error) {
+func (m *NetworkEntry) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *NetworkEntry) MarshalTo(data []byte) (int, error) {
+func (m *NetworkEntry) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if len(m.NetworkID) > 0 {
-		data[i] = 0xa
+		dAtA[i] = 0xa
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NetworkID)))
-		i += copy(data[i:], m.NetworkID)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
+		i += copy(dAtA[i:], m.NetworkID)
 	}
 	if m.LTime != 0 {
-		data[i] = 0x10
+		dAtA[i] = 0x10
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.LTime))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
 	}
 	if len(m.NodeName) > 0 {
-		data[i] = 0x1a
+		dAtA[i] = 0x1a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName)))
-		i += copy(data[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i += copy(dAtA[i:], m.NodeName)
 	}
 	if m.Leaving {
-		data[i] = 0x20
+		dAtA[i] = 0x20
 		i++
 		if m.Leaving {
-			data[i] = 1
+			dAtA[i] = 1
 		} else {
-			data[i] = 0
+			dAtA[i] = 0
 		}
 		i++
 	}
 	return i, nil
 }
 
-func (m *NetworkPushPull) Marshal() (data []byte, err error) {
+func (m *NetworkPushPull) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *NetworkPushPull) MarshalTo(data []byte) (int, error) {
+func (m *NetworkPushPull) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if m.LTime != 0 {
-		data[i] = 0x8
+		dAtA[i] = 0x8
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.LTime))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
 	}
 	if len(m.Networks) > 0 {
 		for _, msg := range m.Networks {
-			data[i] = 0x12
+			dAtA[i] = 0x12
 			i++
-			i = encodeVarintNetworkdb(data, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(data[i:])
+			i = encodeVarintNetworkdb(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
 			if err != nil {
 				return 0, err
 			}
@@ -667,153 +812,158 @@
 		}
 	}
 	if len(m.NodeName) > 0 {
-		data[i] = 0x1a
+		dAtA[i] = 0x1a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName)))
-		i += copy(data[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i += copy(dAtA[i:], m.NodeName)
 	}
 	return i, nil
 }
 
-func (m *TableEvent) Marshal() (data []byte, err error) {
+func (m *TableEvent) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *TableEvent) MarshalTo(data []byte) (int, error) {
+func (m *TableEvent) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if m.Type != 0 {
-		data[i] = 0x8
+		dAtA[i] = 0x8
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.Type))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
 	}
 	if m.LTime != 0 {
-		data[i] = 0x10
+		dAtA[i] = 0x10
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.LTime))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
 	}
 	if len(m.NodeName) > 0 {
-		data[i] = 0x1a
+		dAtA[i] = 0x1a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName)))
-		i += copy(data[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i += copy(dAtA[i:], m.NodeName)
 	}
 	if len(m.NetworkID) > 0 {
-		data[i] = 0x22
+		dAtA[i] = 0x22
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NetworkID)))
-		i += copy(data[i:], m.NetworkID)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
+		i += copy(dAtA[i:], m.NetworkID)
 	}
 	if len(m.TableName) > 0 {
-		data[i] = 0x2a
+		dAtA[i] = 0x2a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.TableName)))
-		i += copy(data[i:], m.TableName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.TableName)))
+		i += copy(dAtA[i:], m.TableName)
 	}
 	if len(m.Key) > 0 {
-		data[i] = 0x32
+		dAtA[i] = 0x32
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.Key)))
-		i += copy(data[i:], m.Key)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Key)))
+		i += copy(dAtA[i:], m.Key)
 	}
 	if len(m.Value) > 0 {
-		data[i] = 0x3a
+		dAtA[i] = 0x3a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.Value)))
-		i += copy(data[i:], m.Value)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Value)))
+		i += copy(dAtA[i:], m.Value)
+	}
+	if m.ResidualReapTime != 0 {
+		dAtA[i] = 0x40
+		i++
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.ResidualReapTime))
 	}
 	return i, nil
 }
 
-func (m *BulkSyncMessage) Marshal() (data []byte, err error) {
+func (m *BulkSyncMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *BulkSyncMessage) MarshalTo(data []byte) (int, error) {
+func (m *BulkSyncMessage) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if m.LTime != 0 {
-		data[i] = 0x8
+		dAtA[i] = 0x8
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(m.LTime))
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
 	}
 	if m.Unsolicited {
-		data[i] = 0x10
+		dAtA[i] = 0x10
 		i++
 		if m.Unsolicited {
-			data[i] = 1
+			dAtA[i] = 1
 		} else {
-			data[i] = 0
+			dAtA[i] = 0
 		}
 		i++
 	}
 	if len(m.NodeName) > 0 {
-		data[i] = 0x1a
+		dAtA[i] = 0x1a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName)))
-		i += copy(data[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i += copy(dAtA[i:], m.NodeName)
 	}
 	if len(m.Networks) > 0 {
 		for _, s := range m.Networks {
-			data[i] = 0x22
+			dAtA[i] = 0x22
 			i++
 			l = len(s)
 			for l >= 1<<7 {
-				data[i] = uint8(uint64(l)&0x7f | 0x80)
+				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
 				l >>= 7
 				i++
 			}
-			data[i] = uint8(l)
+			dAtA[i] = uint8(l)
 			i++
-			i += copy(data[i:], s)
+			i += copy(dAtA[i:], s)
 		}
 	}
 	if len(m.Payload) > 0 {
-		data[i] = 0x2a
+		dAtA[i] = 0x2a
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.Payload)))
-		i += copy(data[i:], m.Payload)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Payload)))
+		i += copy(dAtA[i:], m.Payload)
 	}
 	return i, nil
 }
 
-func (m *CompoundMessage) Marshal() (data []byte, err error) {
+func (m *CompoundMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *CompoundMessage) MarshalTo(data []byte) (int, error) {
+func (m *CompoundMessage) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if len(m.Messages) > 0 {
 		for _, msg := range m.Messages {
-			data[i] = 0xa
+			dAtA[i] = 0xa
 			i++
-			i = encodeVarintNetworkdb(data, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(data[i:])
+			i = encodeVarintNetworkdb(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
 			if err != nil {
 				return 0, err
 			}
@@ -823,55 +973,55 @@
 	return i, nil
 }
 
-func (m *CompoundMessage_SimpleMessage) Marshal() (data []byte, err error) {
+func (m *CompoundMessage_SimpleMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
-	data = make([]byte, size)
-	n, err := m.MarshalTo(data)
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
 	if err != nil {
 		return nil, err
 	}
-	return data[:n], nil
+	return dAtA[:n], nil
 }
 
-func (m *CompoundMessage_SimpleMessage) MarshalTo(data []byte) (int, error) {
+func (m *CompoundMessage_SimpleMessage) MarshalTo(dAtA []byte) (int, error) {
 	var i int
 	_ = i
 	var l int
 	_ = l
 	if len(m.Payload) > 0 {
-		data[i] = 0xa
+		dAtA[i] = 0xa
 		i++
-		i = encodeVarintNetworkdb(data, i, uint64(len(m.Payload)))
-		i += copy(data[i:], m.Payload)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Payload)))
+		i += copy(dAtA[i:], m.Payload)
 	}
 	return i, nil
 }
 
-func encodeFixed64Networkdb(data []byte, offset int, v uint64) int {
-	data[offset] = uint8(v)
-	data[offset+1] = uint8(v >> 8)
-	data[offset+2] = uint8(v >> 16)
-	data[offset+3] = uint8(v >> 24)
-	data[offset+4] = uint8(v >> 32)
-	data[offset+5] = uint8(v >> 40)
-	data[offset+6] = uint8(v >> 48)
-	data[offset+7] = uint8(v >> 56)
+func encodeFixed64Networkdb(dAtA []byte, offset int, v uint64) int {
+	dAtA[offset] = uint8(v)
+	dAtA[offset+1] = uint8(v >> 8)
+	dAtA[offset+2] = uint8(v >> 16)
+	dAtA[offset+3] = uint8(v >> 24)
+	dAtA[offset+4] = uint8(v >> 32)
+	dAtA[offset+5] = uint8(v >> 40)
+	dAtA[offset+6] = uint8(v >> 48)
+	dAtA[offset+7] = uint8(v >> 56)
 	return offset + 8
 }
-func encodeFixed32Networkdb(data []byte, offset int, v uint32) int {
-	data[offset] = uint8(v)
-	data[offset+1] = uint8(v >> 8)
-	data[offset+2] = uint8(v >> 16)
-	data[offset+3] = uint8(v >> 24)
+func encodeFixed32Networkdb(dAtA []byte, offset int, v uint32) int {
+	dAtA[offset] = uint8(v)
+	dAtA[offset+1] = uint8(v >> 8)
+	dAtA[offset+2] = uint8(v >> 16)
+	dAtA[offset+3] = uint8(v >> 24)
 	return offset + 4
 }
-func encodeVarintNetworkdb(data []byte, offset int, v uint64) int {
+func encodeVarintNetworkdb(dAtA []byte, offset int, v uint64) int {
 	for v >= 1<<7 {
-		data[offset] = uint8(v&0x7f | 0x80)
+		dAtA[offset] = uint8(v&0x7f | 0x80)
 		v >>= 7
 		offset++
 	}
-	data[offset] = uint8(v)
+	dAtA[offset] = uint8(v)
 	return offset + 1
 }
 func (m *GossipMessage) Size() (n int) {
@@ -991,6 +1141,9 @@
 	if l > 0 {
 		n += 1 + l + sovNetworkdb(uint64(l))
 	}
+	if m.ResidualReapTime != 0 {
+		n += 1 + sovNetworkdb(uint64(m.ResidualReapTime))
+	}
 	return n
 }
 
@@ -1128,6 +1281,7 @@
 		`TableName:` + fmt.Sprintf("%v", this.TableName) + `,`,
 		`Key:` + fmt.Sprintf("%v", this.Key) + `,`,
 		`Value:` + fmt.Sprintf("%v", this.Value) + `,`,
+		`ResidualReapTime:` + fmt.Sprintf("%v", this.ResidualReapTime) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -1174,8 +1328,8 @@
 	pv := reflect.Indirect(rv).Interface()
 	return fmt.Sprintf("*%v", pv)
 }
-func (m *GossipMessage) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *GossipMessage) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -1187,7 +1341,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -1215,7 +1369,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.Type |= (MessageType(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1234,7 +1388,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				byteLen |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1248,14 +1402,14 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Data = append(m.Data[:0], data[iNdEx:postIndex]...)
+			m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...)
 			if m.Data == nil {
 				m.Data = []byte{}
 			}
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -1274,8 +1428,8 @@
 	}
 	return nil
 }
-func (m *NodeEvent) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *NodeEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -1287,7 +1441,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -1315,7 +1469,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.Type |= (NodeEvent_Type(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1334,7 +1488,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1353,7 +1507,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1368,11 +1522,11 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NodeName = string(data[iNdEx:postIndex])
+			m.NodeName = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -1391,8 +1545,8 @@
 	}
 	return nil
 }
-func (m *NetworkEvent) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -1404,7 +1558,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -1432,7 +1586,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.Type |= (NetworkEvent_Type(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1451,7 +1605,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1470,7 +1624,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1485,7 +1639,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NodeName = string(data[iNdEx:postIndex])
+			m.NodeName = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 4:
 			if wireType != 2 {
@@ -1499,7 +1653,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1514,11 +1668,11 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NetworkID = string(data[iNdEx:postIndex])
+			m.NetworkID = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -1537,8 +1691,8 @@
 	}
 	return nil
 }
-func (m *NetworkEntry) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -1550,7 +1704,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -1578,7 +1732,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1593,7 +1747,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NetworkID = string(data[iNdEx:postIndex])
+			m.NetworkID = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 2:
 			if wireType != 0 {
@@ -1607,7 +1761,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1626,7 +1780,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1641,7 +1795,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NodeName = string(data[iNdEx:postIndex])
+			m.NodeName = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 4:
 			if wireType != 0 {
@@ -1655,7 +1809,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				v |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1665,7 +1819,7 @@
 			m.Leaving = bool(v != 0)
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -1684,8 +1838,8 @@
 	}
 	return nil
 }
-func (m *NetworkPushPull) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -1697,7 +1851,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -1725,7 +1879,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1744,7 +1898,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				msglen |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1759,7 +1913,7 @@
 				return io.ErrUnexpectedEOF
 			}
 			m.Networks = append(m.Networks, &NetworkEntry{})
-			if err := m.Networks[len(m.Networks)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {
+			if err := m.Networks[len(m.Networks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
 			iNdEx = postIndex
@@ -1775,7 +1929,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1790,11 +1944,11 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NodeName = string(data[iNdEx:postIndex])
+			m.NodeName = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -1813,8 +1967,8 @@
 	}
 	return nil
 }
-func (m *TableEvent) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *TableEvent) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -1826,7 +1980,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -1854,7 +2008,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.Type |= (TableEvent_Type(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1873,7 +2027,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1892,7 +2046,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1907,7 +2061,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NodeName = string(data[iNdEx:postIndex])
+			m.NodeName = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 4:
 			if wireType != 2 {
@@ -1921,7 +2075,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1936,7 +2090,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NetworkID = string(data[iNdEx:postIndex])
+			m.NetworkID = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 5:
 			if wireType != 2 {
@@ -1950,7 +2104,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1965,7 +2119,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.TableName = string(data[iNdEx:postIndex])
+			m.TableName = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 6:
 			if wireType != 2 {
@@ -1979,7 +2133,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -1994,7 +2148,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Key = string(data[iNdEx:postIndex])
+			m.Key = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 7:
 			if wireType != 2 {
@@ -2008,7 +2162,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				byteLen |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2022,14 +2176,33 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Value = append(m.Value[:0], data[iNdEx:postIndex]...)
+			m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
 			if m.Value == nil {
 				m.Value = []byte{}
 			}
 			iNdEx = postIndex
+		case 8:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ResidualReapTime", wireType)
+			}
+			m.ResidualReapTime = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowNetworkdb
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ResidualReapTime |= (int32(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -2048,8 +2221,8 @@
 	}
 	return nil
 }
-func (m *BulkSyncMessage) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -2061,7 +2234,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -2089,7 +2262,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2108,7 +2281,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				v |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2128,7 +2301,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2143,7 +2316,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NodeName = string(data[iNdEx:postIndex])
+			m.NodeName = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
 		case 4:
 			if wireType != 2 {
@@ -2157,7 +2330,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				stringLen |= (uint64(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2172,7 +2345,7 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Networks = append(m.Networks, string(data[iNdEx:postIndex]))
+			m.Networks = append(m.Networks, string(dAtA[iNdEx:postIndex]))
 			iNdEx = postIndex
 		case 5:
 			if wireType != 2 {
@@ -2186,7 +2359,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				byteLen |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2200,14 +2373,14 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Payload = append(m.Payload[:0], data[iNdEx:postIndex]...)
+			m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...)
 			if m.Payload == nil {
 				m.Payload = []byte{}
 			}
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -2226,8 +2399,8 @@
 	}
 	return nil
 }
-func (m *CompoundMessage) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *CompoundMessage) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -2239,7 +2412,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -2267,7 +2440,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				msglen |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2282,13 +2455,13 @@
 				return io.ErrUnexpectedEOF
 			}
 			m.Messages = append(m.Messages, &CompoundMessage_SimpleMessage{})
-			if err := m.Messages[len(m.Messages)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {
+			if err := m.Messages[len(m.Messages)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -2307,8 +2480,8 @@
 	}
 	return nil
 }
-func (m *CompoundMessage_SimpleMessage) Unmarshal(data []byte) error {
-	l := len(data)
+func (m *CompoundMessage_SimpleMessage) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		preIndex := iNdEx
@@ -2320,7 +2493,7 @@
 			if iNdEx >= l {
 				return io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -2348,7 +2521,7 @@
 				if iNdEx >= l {
 					return io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				byteLen |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2362,14 +2535,14 @@
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Payload = append(m.Payload[:0], data[iNdEx:postIndex]...)
+			m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...)
 			if m.Payload == nil {
 				m.Payload = []byte{}
 			}
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
-			skippy, err := skipNetworkdb(data[iNdEx:])
+			skippy, err := skipNetworkdb(dAtA[iNdEx:])
 			if err != nil {
 				return err
 			}
@@ -2388,8 +2561,8 @@
 	}
 	return nil
 }
-func skipNetworkdb(data []byte) (n int, err error) {
-	l := len(data)
+func skipNetworkdb(dAtA []byte) (n int, err error) {
+	l := len(dAtA)
 	iNdEx := 0
 	for iNdEx < l {
 		var wire uint64
@@ -2400,7 +2573,7 @@
 			if iNdEx >= l {
 				return 0, io.ErrUnexpectedEOF
 			}
-			b := data[iNdEx]
+			b := dAtA[iNdEx]
 			iNdEx++
 			wire |= (uint64(b) & 0x7F) << shift
 			if b < 0x80 {
@@ -2418,7 +2591,7 @@
 					return 0, io.ErrUnexpectedEOF
 				}
 				iNdEx++
-				if data[iNdEx-1] < 0x80 {
+				if dAtA[iNdEx-1] < 0x80 {
 					break
 				}
 			}
@@ -2435,7 +2608,7 @@
 				if iNdEx >= l {
 					return 0, io.ErrUnexpectedEOF
 				}
-				b := data[iNdEx]
+				b := dAtA[iNdEx]
 				iNdEx++
 				length |= (int(b) & 0x7F) << shift
 				if b < 0x80 {
@@ -2458,7 +2631,7 @@
 					if iNdEx >= l {
 						return 0, io.ErrUnexpectedEOF
 					}
-					b := data[iNdEx]
+					b := dAtA[iNdEx]
 					iNdEx++
 					innerWire |= (uint64(b) & 0x7F) << shift
 					if b < 0x80 {
@@ -2469,7 +2642,7 @@
 				if innerWireType == 4 {
 					break
 				}
-				next, err := skipNetworkdb(data[start:])
+				next, err := skipNetworkdb(dAtA[start:])
 				if err != nil {
 					return 0, err
 				}
@@ -2493,62 +2666,68 @@
 	ErrIntOverflowNetworkdb   = fmt.Errorf("proto: integer overflow")
 )
 
+func init() { proto.RegisterFile("networkdb.proto", fileDescriptorNetworkdb) }
+
 var fileDescriptorNetworkdb = []byte{
-	// 887 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x96, 0xc1, 0x6e, 0xe3, 0x44,
-	0x18, 0xc7, 0xeb, 0xc4, 0x49, 0xe3, 0xaf, 0x0d, 0x1b, 0xbc, 0xdd, 0xad, 0xd7, 0x0b, 0x49, 0x31,
-	0xcb, 0x2a, 0x44, 0xe0, 0xa2, 0xee, 0x13, 0x24, 0xb1, 0x05, 0xd9, 0xf5, 0x3a, 0x91, 0x93, 0x14,
-	0x71, 0x8a, 0x9c, 0x78, 0x48, 0xac, 0x3a, 0xb6, 0x15, 0x3b, 0x45, 0x39, 0x81, 0x38, 0xad, 0x78,
-	0x07, 0x4e, 0xcb, 0x99, 0x07, 0xe0, 0xc0, 0x89, 0xc3, 0x8a, 0x13, 0xdc, 0x10, 0x87, 0x8a, 0xee,
-	0x13, 0xf0, 0x08, 0x8c, 0xc7, 0x76, 0x32, 0x4e, 0xa3, 0x5e, 0x40, 0xc0, 0xc1, 0xad, 0x67, 0xe6,
-	0xe7, 0xcf, 0xdf, 0xf7, 0x9f, 0xff, 0xe7, 0x09, 0xdc, 0x71, 0x51, 0xf8, 0x85, 0xb7, 0xb8, 0xb0,
-	0xc6, 0xb2, 0xbf, 0xf0, 0x42, 0x8f, 0xe7, 0xd6, 0x13, 0xe2, 0xd1, 0xd4, 0x9b, 0x7a, 0x64, 0xf6,
-	0x34, 0xba, 0x8b, 0x01, 0xa9, 0x0b, 0xe5, 0x8f, 0xbd, 0x20, 0xb0, 0xfd, 0xe7, 0x28, 0x08, 0xcc,
-	0x29, 0xe2, 0x1b, 0xc0, 0x86, 0x2b, 0x1f, 0x09, 0xcc, 0x09, 0x53, 0x7f, 0xe3, 0xec, 0xbe, 0xbc,
-	0x89, 0x98, 0x10, 0x03, 0xbc, 0x6a, 0x10, 0x86, 0xe7, 0x81, 0xb5, 0xcc, 0xd0, 0x14, 0x72, 0x98,
-	0x3d, 0x34, 0xc8, 0xbd, 0xf4, 0x32, 0x07, 0x9c, 0xee, 0x59, 0x48, 0xbd, 0x44, 0x6e, 0xc8, 0x7f,
-	0x98, 0x89, 0xf6, 0x80, 0x8a, 0xb6, 0x66, 0x64, 0x2a, 0x60, 0x07, 0x8a, 0xce, 0x28, 0xb4, 0xe7,
-	0x88, 0x84, 0x64, 0x5b, 0x67, 0xaf, 0xae, 0x6a, 0x7b, 0xbf, 0x5f, 0xd5, 0x1a, 0x53, 0x3b, 0x9c,
-	0x2d, 0xc7, 0xf2, 0xc4, 0x9b, 0x9f, 0xce, 0xcc, 0x60, 0x66, 0x4f, 0xbc, 0x85, 0x7f, 0x1a, 0xa0,
-	0xc5, 0xe7, 0xe4, 0x8f, 0xac, 0x99, 0x73, 0xdf, 0x5b, 0x84, 0x03, 0xfc, 0xa4, 0x51, 0x70, 0xa2,
-	0x7f, 0xfc, 0x43, 0xe0, 0x5c, 0xfc, 0x8a, 0x91, 0x6b, 0xe2, 0x68, 0x79, 0x1c, 0x8d, 0x33, 0x4a,
-	0xd1, 0x84, 0x8e, 0xc7, 0xd2, 0x97, 0xc0, 0x46, 0x6f, 0xe5, 0xdf, 0x83, 0xfd, 0x8e, 0x7e, 0xde,
-	0xd4, 0x3a, 0x4a, 0x65, 0x4f, 0x14, 0xbe, 0xf9, 0xf6, 0xe4, 0x68, 0x9d, 0x56, 0xb4, 0xde, 0x71,
-	0x2f, 0x4d, 0xc7, 0xb6, 0xf8, 0x1a, 0xb0, 0x4f, 0xbb, 0x1d, 0xbd, 0xc2, 0x88, 0xf7, 0x30, 0xf3,
-	0x66, 0x86, 0x79, 0xea, 0xd9, 0x2e, 0xff, 0x0e, 0x14, 0x34, 0xb5, 0x79, 0xae, 0x56, 0x72, 0xe2,
-	0x7d, 0x4c, 0xf0, 0x19, 0x42, 0x43, 0xe6, 0x25, 0x12, 0x0f, 0x5f, 0xbc, 0xac, 0xee, 0xfd, 0xf0,
-	0x5d, 0x95, 0xbc, 0x58, 0xba, 0xce, 0xc1, 0xa1, 0x1e, 0x6b, 0x11, 0x0b, 0xf5, 0x51, 0x46, 0xa8,
-	0xb7, 0x68, 0xa1, 0x28, 0xec, 0x3f, 0xd0, 0x8a, 0xff, 0x00, 0x20, 0x49, 0x66, 0x64, 0x5b, 0x02,
-	0x1b, 0xad, 0xb6, 0xca, 0xaf, 0xaf, 0x6a, 0x5c, 0x92, 0x58, 0x47, 0x31, 0x52, 0x97, 0x75, 0x2c,
-	0xe9, 0x05, 0x93, 0x48, 0x5b, 0xa7, 0xa5, 0x7d, 0x88, 0x45, 0x39, 0xa6, 0x0b, 0xa1, 0xd5, 0x95,
-	0xd6, 0xea, 0xc6, 0x3b, 0xb0, 0x85, 0x11, 0x81, 0x1f, 0x6d, 0x04, 0x7e, 0x80, 0xa1, 0x7b, 0xdb,
-	0xd0, 0x2e, 0x8d, 0x7f, 0x64, 0x36, 0x1a, 0xbb, 0xe1, 0x62, 0xb5, 0x55, 0x09, 0x73, 0x7b, 0x25,
-	0xff, 0x9a, 0xbe, 0x02, 0xec, 0x3b, 0x38, 0x7b, 0xdb, 0x9d, 0x12, 0x71, 0x4b, 0x46, 0x3a, 0x94,
-	0xbe, 0x67, 0xe0, 0x4e, 0x92, 0x5a, 0x6f, 0x19, 0xcc, 0x7a, 0x4b, 0xc7, 0xa1, 0xb2, 0x62, 0xfe,
-	0x6e, 0x56, 0x4f, 0xa0, 0x94, 0x54, 0x1b, 0xe0, 0x12, 0xf3, 0xf5, 0x83, 0xb3, 0xe3, 0x1d, 0xb6,
-	0x8b, 0x94, 0x33, 0xd6, 0xe0, 0xed, 0x6d, 0xf5, 0x73, 0x1e, 0x60, 0x60, 0x8e, 0x9d, 0xa4, 0xf9,
-	0xe5, 0x8c, 0xa7, 0x45, 0x2a, 0xf8, 0x06, 0xfa, 0xdf, 0x3b, 0x9a, 0x7f, 0x1b, 0x20, 0x8c, 0xd2,
-	0x8d, 0x63, 0x15, 0x48, 0x2c, 0x8e, 0xcc, 0x90, 0x60, 0x15, 0xc8, 0x5f, 0xa0, 0x95, 0x50, 0x24,
-	0xf3, 0xd1, 0x2d, 0x7f, 0x04, 0x05, 0x6c, 0xec, 0x25, 0x12, 0xf6, 0xc9, 0x67, 0x31, 0x1e, 0x44,
-	0x9b, 0x19, 0x37, 0xc6, 0x63, 0xba, 0x31, 0x88, 0x99, 0x37, 0x6a, 0xd0, 0x6d, 0xf1, 0x08, 0x8a,
-	0x6d, 0x43, 0x6d, 0x0e, 0xd4, 0xb4, 0x31, 0xb2, 0x58, 0x7b, 0x81, 0xcc, 0x10, 0x45, 0xd4, 0xb0,
-	0xa7, 0x44, 0x54, 0x6e, 0x17, 0x35, 0xf4, 0xad, 0x84, 0x52, 0x54, 0x4d, 0xc5, 0x54, 0x7e, 0x17,
-	0xa5, 0x20, 0x07, 0x85, 0xdb, 0xed, 0xf3, 0x2b, 0x76, 0x5f, 0x6b, 0xe9, 0x5c, 0xf4, 0x57, 0xee,
-	0x24, 0x3d, 0x1c, 0xfe, 0x41, 0xf7, 0x9d, 0xc0, 0xc1, 0xd2, 0x0d, 0x3c, 0xc7, 0x9e, 0xd8, 0x21,
-	0xb2, 0xc8, 0x8e, 0x97, 0x0c, 0x7a, 0xea, 0xf6, 0x3d, 0x14, 0x29, 0xf3, 0xb2, 0xd8, 0xbc, 0x1c,
-	0xe5, 0x51, 0xdc, 0x51, 0xbe, 0xb9, 0x72, 0x3c, 0xd3, 0x22, 0xdb, 0x75, 0x68, 0xa4, 0x43, 0xe9,
-	0x6b, 0x5c, 0x53, 0xdb, 0xc3, 0xb9, 0x2c, 0x5d, 0x2b, 0xad, 0x49, 0x81, 0xd2, 0x3c, 0xbe, 0x0d,
-	0x70, 0x55, 0x51, 0x1b, 0xd4, 0x29, 0xa7, 0x6e, 0xd1, 0x72, 0xdf, 0x9e, 0xfb, 0x0e, 0x4a, 0x46,
-	0xc6, 0xfa, 0x49, 0xf1, 0x7d, 0x28, 0x67, 0x96, 0xa2, 0x24, 0x7a, 0x49, 0x12, 0x4c, 0x26, 0x89,
-	0xc6, 0x4f, 0x39, 0x38, 0xa0, 0xce, 0x52, 0xfe, 0x5d, 0xda, 0x10, 0xe4, 0xf8, 0xa0, 0x56, 0x53,
-	0x37, 0xc8, 0x50, 0xd6, 0xd5, 0xc1, 0xa7, 0x5d, 0xe3, 0xd9, 0x48, 0x3d, 0x57, 0xf5, 0x01, 0x36,
-	0x05, 0xf9, 0xa8, 0x52, 0x68, 0xe6, 0x3c, 0x69, 0xc0, 0xc1, 0xa0, 0xd9, 0xd2, 0xd4, 0x84, 0x4e,
-	0x3e, 0x9b, 0x14, 0x4d, 0xf5, 0xe9, 0x63, 0xe0, 0x7a, 0xc3, 0xfe, 0x27, 0xa3, 0xde, 0x50, 0xd3,
-	0xb0, 0x41, 0x8e, 0x31, 0x79, 0x97, 0x22, 0xd7, 0xdf, 0x1e, 0xcc, 0xb5, 0x86, 0xda, 0xb3, 0x51,
-	0xff, 0x33, 0xbd, 0x5d, 0x61, 0x6f, 0x70, 0xa9, 0x59, 0xf0, 0xa9, 0x5a, 0x6a, 0x77, 0x9f, 0xf7,
-	0xba, 0x43, 0x5d, 0xa9, 0x14, 0x6e, 0x60, 0xa9, 0xa2, 0xf8, 0x84, 0x00, 0xbd, 0xab, 0xa4, 0x19,
-	0x16, 0x63, 0x63, 0xd2, 0xf5, 0xa4, 0x87, 0xa8, 0x78, 0x37, 0x31, 0x26, 0x2d, 0x5b, 0x4b, 0xf8,
-	0xed, 0xba, 0xba, 0xf7, 0xe7, 0x75, 0x95, 0xf9, 0xea, 0x75, 0x95, 0x79, 0x85, 0xaf, 0x5f, 0xf0,
-	0xf5, 0x07, 0xbe, 0xc6, 0x45, 0xf2, 0xd3, 0xe6, 0xc9, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x21,
-	0x78, 0x72, 0xc3, 0x0e, 0x09, 0x00, 0x00,
+	// 953 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x96, 0xcd, 0x6e, 0xe3, 0x54,
+	0x14, 0xc7, 0x7b, 0xf3, 0xd5, 0xe4, 0x34, 0xa5, 0xe6, 0x4e, 0x67, 0xc6, 0xe3, 0x81, 0xc4, 0x98,
+	0x99, 0x2a, 0x53, 0x41, 0x8a, 0x3a, 0x4f, 0xd0, 0x24, 0x16, 0x64, 0x26, 0xe3, 0x44, 0x6e, 0x52,
+	0xc4, 0x2a, 0xba, 0xad, 0x2f, 0xa9, 0x55, 0xc7, 0xb6, 0x6c, 0x27, 0x28, 0x2b, 0x10, 0xab, 0x51,
+	0x16, 0xbc, 0x41, 0x56, 0xc3, 0x9a, 0x07, 0x40, 0x2c, 0x59, 0xcc, 0x82, 0x05, 0xec, 0x10, 0x8b,
+	0x88, 0xe6, 0x09, 0x78, 0x04, 0xe4, 0x6b, 0x3b, 0xb9, 0x49, 0xab, 0x91, 0x10, 0x23, 0xc1, 0x26,
+	0xb9, 0x1f, 0xbf, 0x1c, 0x9f, 0xf3, 0xf7, 0xff, 0xdc, 0x1b, 0xd8, 0xb3, 0x69, 0xf0, 0x95, 0xe3,
+	0x5d, 0x19, 0xe7, 0x55, 0xd7, 0x73, 0x02, 0x07, 0x17, 0x96, 0x0b, 0xd2, 0xfe, 0xc0, 0x19, 0x38,
+	0x6c, 0xf5, 0x28, 0x1c, 0x45, 0x80, 0xd2, 0x86, 0xdd, 0x4f, 0x1d, 0xdf, 0x37, 0xdd, 0x17, 0xd4,
+	0xf7, 0xc9, 0x80, 0xe2, 0x43, 0xc8, 0x04, 0x13, 0x97, 0x8a, 0x48, 0x46, 0x95, 0x77, 0x8e, 0xef,
+	0x55, 0x57, 0x11, 0x63, 0xa2, 0x3b, 0x71, 0xa9, 0xce, 0x18, 0x8c, 0x21, 0x63, 0x90, 0x80, 0x88,
+	0x29, 0x19, 0x55, 0x8a, 0x3a, 0x1b, 0x2b, 0xaf, 0x52, 0x50, 0xd0, 0x1c, 0x83, 0xaa, 0x63, 0x6a,
+	0x07, 0xf8, 0xe3, 0xb5, 0x68, 0x0f, 0xb8, 0x68, 0x4b, 0xa6, 0xca, 0x05, 0x6c, 0x42, 0xce, 0xea,
+	0x07, 0xe6, 0x90, 0xb2, 0x90, 0x99, 0xda, 0xf1, 0xeb, 0x79, 0x79, 0xeb, 0x8f, 0x79, 0xf9, 0x70,
+	0x60, 0x06, 0x97, 0xa3, 0xf3, 0xea, 0x85, 0x33, 0x3c, 0xba, 0x24, 0xfe, 0xa5, 0x79, 0xe1, 0x78,
+	0xee, 0x91, 0x4f, 0xbd, 0x2f, 0xd9, 0x47, 0xb5, 0x45, 0x86, 0xae, 0xe3, 0x05, 0x5d, 0x73, 0x48,
+	0xf5, 0xac, 0x15, 0x7e, 0xe1, 0x87, 0x50, 0xb0, 0x1d, 0x83, 0xf6, 0x6d, 0x32, 0xa4, 0x62, 0x5a,
+	0x46, 0x95, 0x82, 0x9e, 0x0f, 0x17, 0x34, 0x32, 0xa4, 0xca, 0xd7, 0x90, 0x09, 0x9f, 0x8a, 0x1f,
+	0xc3, 0x76, 0x53, 0x3b, 0x3b, 0x69, 0x35, 0x1b, 0xc2, 0x96, 0x24, 0x4e, 0x67, 0xf2, 0xfe, 0x32,
+	0xad, 0x70, 0xbf, 0x69, 0x8f, 0x89, 0x65, 0x1a, 0xb8, 0x0c, 0x99, 0x67, 0xed, 0xa6, 0x26, 0x20,
+	0xe9, 0xee, 0x74, 0x26, 0xbf, 0xbb, 0xc6, 0x3c, 0x73, 0x4c, 0x1b, 0x7f, 0x00, 0xd9, 0x96, 0x7a,
+	0x72, 0xa6, 0x0a, 0x29, 0xe9, 0xde, 0x74, 0x26, 0xe3, 0x35, 0xa2, 0x45, 0xc9, 0x98, 0x4a, 0xc5,
+	0x97, 0xaf, 0x4a, 0x5b, 0x3f, 0x7e, 0x5f, 0x62, 0x0f, 0x56, 0xae, 0x53, 0x50, 0xd4, 0x22, 0x2d,
+	0x22, 0xa1, 0x3e, 0x59, 0x13, 0xea, 0x3d, 0x5e, 0x28, 0x0e, 0xfb, 0x0f, 0xb4, 0xc2, 0x1f, 0x01,
+	0xc4, 0xc9, 0xf4, 0x4d, 0x43, 0xcc, 0x84, 0xbb, 0xb5, 0xdd, 0xc5, 0xbc, 0x5c, 0x88, 0x13, 0x6b,
+	0x36, 0xf4, 0xc4, 0x65, 0x4d, 0x43, 0x79, 0x89, 0x62, 0x69, 0x2b, 0xbc, 0xb4, 0x0f, 0xa7, 0x33,
+	0xf9, 0x3e, 0x5f, 0x08, 0xaf, 0xae, 0xb2, 0x54, 0x37, 0x7a, 0x03, 0x1b, 0x18, 0x13, 0xf8, 0xd1,
+	0x4a, 0xe0, 0x07, 0xd3, 0x99, 0x7c, 0x77, 0x13, 0xba, 0x4d, 0xe3, 0x5f, 0xd0, 0x4a, 0x63, 0x3b,
+	0xf0, 0x26, 0x1b, 0x95, 0xa0, 0x37, 0x57, 0xf2, 0x36, 0xf5, 0x7d, 0x72, 0x43, 0xdf, 0x5a, 0x71,
+	0x31, 0x2f, 0xe7, 0xb5, 0x58, 0x63, 0x4e, 0x6d, 0x11, 0xb6, 0x2d, 0x4a, 0xc6, 0xa6, 0x3d, 0x60,
+	0x52, 0xe7, 0xf5, 0x64, 0xaa, 0xfc, 0x84, 0x60, 0x2f, 0x4e, 0xb4, 0x33, 0xf2, 0x2f, 0x3b, 0x23,
+	0xcb, 0xe2, 0x72, 0x44, 0xff, 0x36, 0xc7, 0xa7, 0x90, 0x8f, 0x6b, 0xf7, 0xc5, 0x94, 0x9c, 0xae,
+	0xec, 0x1c, 0xdf, 0xbf, 0xc5, 0x84, 0xa1, 0x8e, 0xfa, 0x12, 0xfc, 0x07, 0x85, 0x29, 0xdf, 0x65,
+	0x00, 0xba, 0xe4, 0xdc, 0x8a, 0x0f, 0x86, 0xea, 0x9a, 0xdf, 0x25, 0xee, 0x51, 0x2b, 0xe8, 0x7f,
+	0xef, 0x76, 0xfc, 0x3e, 0x40, 0x10, 0xa6, 0x1b, 0xc5, 0xca, 0xb2, 0x58, 0x05, 0xb6, 0xc2, 0x82,
+	0x09, 0x90, 0xbe, 0xa2, 0x13, 0x31, 0xc7, 0xd6, 0xc3, 0x21, 0xde, 0x87, 0xec, 0x98, 0x58, 0x23,
+	0x2a, 0x6e, 0xb3, 0x23, 0x33, 0x9a, 0xe0, 0x1a, 0x60, 0x8f, 0xfa, 0xa6, 0x31, 0x22, 0x56, 0xdf,
+	0xa3, 0xc4, 0x8d, 0x0a, 0xcd, 0xcb, 0xa8, 0x92, 0xad, 0xed, 0x2f, 0xe6, 0x65, 0x41, 0x8f, 0x77,
+	0x75, 0x4a, 0x5c, 0x56, 0x8a, 0xe0, 0x6d, 0xac, 0x28, 0x3f, 0x24, 0x8d, 0x77, 0xc0, 0x37, 0x1e,
+	0x6b, 0x96, 0x95, 0xa2, 0x7c, 0xdb, 0x3d, 0x82, 0x5c, 0x5d, 0x57, 0x4f, 0xba, 0x6a, 0xd2, 0x78,
+	0xeb, 0x58, 0xdd, 0xa3, 0x24, 0xa0, 0x21, 0xd5, 0xeb, 0x34, 0x42, 0x2a, 0x75, 0x1b, 0xd5, 0x73,
+	0x8d, 0x98, 0x6a, 0xa8, 0x2d, 0xb5, 0xab, 0x0a, 0xe9, 0xdb, 0xa8, 0x06, 0xb5, 0x68, 0xb0, 0xd9,
+	0x9e, 0xbf, 0x21, 0xd8, 0xab, 0x8d, 0xac, 0xab, 0xd3, 0x89, 0x7d, 0x91, 0x5c, 0x3e, 0x6f, 0xd1,
+	0xcf, 0x32, 0xec, 0x8c, 0x6c, 0xdf, 0xb1, 0xcc, 0x0b, 0x33, 0xa0, 0x06, 0x73, 0x4d, 0x5e, 0xe7,
+	0x97, 0xde, 0xec, 0x03, 0x89, 0x6b, 0x87, 0x8c, 0x9c, 0x66, 0x7b, 0x89, 0xeb, 0x45, 0xd8, 0x76,
+	0xc9, 0xc4, 0x72, 0x88, 0xc1, 0x5e, 0x79, 0x51, 0x4f, 0xa6, 0xca, 0xb7, 0x08, 0xf6, 0xea, 0xce,
+	0xd0, 0x75, 0x46, 0xb6, 0x91, 0xd4, 0xd4, 0x80, 0xfc, 0x30, 0x1a, 0xfa, 0x22, 0x62, 0x8d, 0x55,
+	0xe1, 0xdc, 0xbe, 0x41, 0x57, 0x4f, 0xcd, 0xa1, 0x6b, 0xd1, 0x78, 0xa6, 0x2f, 0x7f, 0x29, 0x3d,
+	0x81, 0xdd, 0xb5, 0xad, 0x30, 0x89, 0x4e, 0x9c, 0x04, 0x8a, 0x92, 0x88, 0xa7, 0x87, 0x3f, 0xa7,
+	0x60, 0x87, 0xbb, 0xab, 0xf1, 0x87, 0xbc, 0x21, 0xd8, 0xf5, 0xc4, 0xed, 0x26, 0x6e, 0xa8, 0xc2,
+	0xae, 0xa6, 0x76, 0x3f, 0x6f, 0xeb, 0xcf, 0xfb, 0xea, 0x99, 0xaa, 0x75, 0x05, 0x14, 0x1d, 0xda,
+	0x1c, 0xba, 0x76, 0x5f, 0x1d, 0xc2, 0x4e, 0xf7, 0xa4, 0xd6, 0x52, 0x63, 0x3a, 0x3e, 0x96, 0x39,
+	0x9a, 0xeb, 0xf5, 0x03, 0x28, 0x74, 0x7a, 0xa7, 0x9f, 0xf5, 0x3b, 0xbd, 0x56, 0x4b, 0x48, 0x4b,
+	0xf7, 0xa7, 0x33, 0xf9, 0x0e, 0x47, 0x2e, 0x4f, 0xb3, 0x03, 0x28, 0xd4, 0x7a, 0xad, 0xe7, 0xfd,
+	0xd3, 0x2f, 0xb4, 0xba, 0x90, 0xb9, 0xc1, 0x25, 0x66, 0xc1, 0x8f, 0x21, 0x5f, 0x6f, 0xbf, 0xe8,
+	0xb4, 0x7b, 0x5a, 0x43, 0xc8, 0xde, 0xc0, 0x12, 0x45, 0x71, 0x05, 0x40, 0x6b, 0x37, 0x92, 0x0c,
+	0x73, 0x91, 0x31, 0xf9, 0x7a, 0x92, 0x4b, 0x5a, 0xba, 0x13, 0x1b, 0x93, 0x97, 0xad, 0x26, 0xfe,
+	0x7e, 0x5d, 0xda, 0xfa, 0xeb, 0xba, 0x84, 0xbe, 0x59, 0x94, 0xd0, 0xeb, 0x45, 0x09, 0xfd, 0xba,
+	0x28, 0xa1, 0x3f, 0x17, 0x25, 0x74, 0x9e, 0x63, 0x7f, 0x9d, 0x9e, 0xfe, 0x1d, 0x00, 0x00, 0xff,
+	0xff, 0x92, 0x82, 0xdb, 0x1a, 0x6e, 0x09, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/libnetwork/networkdb/networkdb.proto b/vendor/github.com/docker/libnetwork/networkdb/networkdb.proto
index 7df1b42..0b8490b 100644
--- a/vendor/github.com/docker/libnetwork/networkdb/networkdb.proto
+++ b/vendor/github.com/docker/libnetwork/networkdb/networkdb.proto
@@ -109,7 +109,7 @@
 	// network event was recorded.
 	uint64 l_time = 2 [(gogoproto.customtype) = "github.com/hashicorp/serf/serf.LamportTime", (gogoproto.nullable) = false];
 	// Source node name where this network attachment happened.
-	string node_name = 3;
+	string node_name = 3 [(gogoproto.customname) = "NodeName"];
 	// Indicates if a leave from this network is in progress.
 	bool leaving = 4;
 }
@@ -119,6 +119,8 @@
 	// Lamport time when this push pull was initiated.
 	uint64 l_time = 1 [(gogoproto.customtype) = "github.com/hashicorp/serf/serf.LamportTime", (gogoproto.nullable) = false];
 	repeated NetworkEntry networks = 2;
+	// Name of the node sending this push pull payload.
+	string node_name = 3 [(gogoproto.customname) = "NodeName"];
 }
 
 // TableEvent message payload definition.
@@ -152,6 +154,8 @@
 	string key = 6;
 	// Entry value.
 	bytes value = 7;
+	// Residual reap time for the entry before getting deleted in seconds
+	int32 residual_reap_time = 8 [(gogoproto.customname) = "ResidualReapTime"];;
 }
 
 // BulkSync message payload definition.
@@ -180,4 +184,4 @@
 
 	// A list of simple messages.
 	repeated SimpleMessage messages = 1;
-}
\ No newline at end of file
+}
diff --git a/vendor/github.com/docker/libnetwork/networkdb/networkdbdiagnose.go b/vendor/github.com/docker/libnetwork/networkdb/networkdbdiagnose.go
new file mode 100644
index 0000000..d70cec7
--- /dev/null
+++ b/vendor/github.com/docker/libnetwork/networkdb/networkdbdiagnose.go
@@ -0,0 +1,242 @@
+package networkdb
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/docker/libnetwork/diagnose"
+)
+
+const (
+	missingParameter = "missing parameter"
+)
+
+// NetDbPaths2Func TODO
+var NetDbPaths2Func = map[string]diagnose.HTTPHandlerFunc{
+	"/join":         dbJoin,
+	"/networkpeers": dbPeers,
+	"/clusterpeers": dbClusterPeers,
+	"/joinnetwork":  dbJoinNetwork,
+	"/leavenetwork": dbLeaveNetwork,
+	"/createentry":  dbCreateEntry,
+	"/updateentry":  dbUpdateEntry,
+	"/deleteentry":  dbDeleteEntry,
+	"/getentry":     dbGetEntry,
+	"/gettable":     dbGetTable,
+}
+
+func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["members"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?members=ip1,ip2,...", r.URL.Path))
+		return
+	}
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		err := nDB.Join(strings.Split(r.Form["members"][0], ","))
+		if err != nil {
+			fmt.Fprintf(w, "%s error in the DB join %s\n", r.URL.Path, err)
+			return
+		}
+
+		fmt.Fprintf(w, "OK\n")
+	}
+}
+
+func dbPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["nid"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?nid=test", r.URL.Path))
+		return
+	}
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		peers := nDB.Peers(r.Form["nid"][0])
+		fmt.Fprintf(w, "Network:%s Total peers: %d\n", r.Form["nid"], len(peers))
+		for i, peerInfo := range peers {
+			fmt.Fprintf(w, "%d) %s -> %s\n", i, peerInfo.Name, peerInfo.IP)
+		}
+	}
+}
+
+func dbClusterPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		peers := nDB.ClusterPeers()
+		fmt.Fprintf(w, "Total peers: %d\n", len(peers))
+		for i, peerInfo := range peers {
+			fmt.Fprintf(w, "%d) %s -> %s\n", i, peerInfo.Name, peerInfo.IP)
+		}
+	}
+}
+
+func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["tname"]) < 1 ||
+		len(r.Form["nid"]) < 1 ||
+		len(r.Form["key"]) < 1 ||
+		len(r.Form["value"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
+		return
+	}
+
+	tname := r.Form["tname"][0]
+	nid := r.Form["nid"][0]
+	key := r.Form["key"][0]
+	value := r.Form["value"][0]
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		if err := nDB.CreateEntry(tname, nid, key, []byte(value)); err != nil {
+			diagnose.HTTPReplyError(w, err.Error(), "")
+			return
+		}
+		fmt.Fprintf(w, "OK\n")
+	}
+}
+
+func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["tname"]) < 1 ||
+		len(r.Form["nid"]) < 1 ||
+		len(r.Form["key"]) < 1 ||
+		len(r.Form["value"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k&value=v", r.URL.Path))
+		return
+	}
+
+	tname := r.Form["tname"][0]
+	nid := r.Form["nid"][0]
+	key := r.Form["key"][0]
+	value := r.Form["value"][0]
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		if err := nDB.UpdateEntry(tname, nid, key, []byte(value)); err != nil {
+			diagnose.HTTPReplyError(w, err.Error(), "")
+			return
+		}
+		fmt.Fprintf(w, "OK\n")
+	}
+}
+
+func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["tname"]) < 1 ||
+		len(r.Form["nid"]) < 1 ||
+		len(r.Form["key"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
+		return
+	}
+
+	tname := r.Form["tname"][0]
+	nid := r.Form["nid"][0]
+	key := r.Form["key"][0]
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		err := nDB.DeleteEntry(tname, nid, key)
+		if err != nil {
+			diagnose.HTTPReplyError(w, err.Error(), "")
+			return
+		}
+		fmt.Fprintf(w, "OK\n")
+	}
+}
+
+func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["tname"]) < 1 ||
+		len(r.Form["nid"]) < 1 ||
+		len(r.Form["key"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id&key=k", r.URL.Path))
+		return
+	}
+
+	tname := r.Form["tname"][0]
+	nid := r.Form["nid"][0]
+	key := r.Form["key"][0]
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		value, err := nDB.GetEntry(tname, nid, key)
+		if err != nil {
+			diagnose.HTTPReplyError(w, err.Error(), "")
+			return
+		}
+		fmt.Fprintf(w, "key:`%s` value:`%s`\n", key, string(value))
+	}
+}
+
+func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["nid"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
+		return
+	}
+
+	nid := r.Form["nid"][0]
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		if err := nDB.JoinNetwork(nid); err != nil {
+			diagnose.HTTPReplyError(w, err.Error(), "")
+			return
+		}
+		fmt.Fprintf(w, "OK\n")
+	}
+}
+
+func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["nid"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?nid=network_id", r.URL.Path))
+		return
+	}
+
+	nid := r.Form["nid"][0]
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		if err := nDB.LeaveNetwork(nid); err != nil {
+			diagnose.HTTPReplyError(w, err.Error(), "")
+			return
+		}
+		fmt.Fprintf(w, "OK\n")
+	}
+}
+
+func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	diagnose.DebugHTTPForm(r)
+	if len(r.Form["tname"]) < 1 ||
+		len(r.Form["nid"]) < 1 {
+		diagnose.HTTPReplyError(w, missingParameter, fmt.Sprintf("%s?tname=table_name&nid=network_id", r.URL.Path))
+		return
+	}
+
+	tname := r.Form["tname"][0]
+	nid := r.Form["nid"][0]
+
+	nDB, ok := ctx.(*NetworkDB)
+	if ok {
+		table := nDB.GetTableByNetwork(tname, nid)
+		fmt.Fprintf(w, "total elements: %d\n", len(table))
+		i := 0
+		for k, v := range table {
+			fmt.Fprintf(w, "%d) k:`%s` -> v:`%s`\n", i, k, string(v.([]byte)))
+			i++
+		}
+	}
+}
diff --git a/vendor/github.com/docker/libnetwork/ns/init_linux.go b/vendor/github.com/docker/libnetwork/ns/init_linux.go
index 84d4950..567a624 100644
--- a/vendor/github.com/docker/libnetwork/ns/init_linux.go
+++ b/vendor/github.com/docker/libnetwork/ns/init_linux.go
@@ -9,7 +9,7 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netns"
 )
diff --git a/vendor/github.com/docker/libnetwork/osl/interface_linux.go b/vendor/github.com/docker/libnetwork/osl/interface_linux.go
index 8e8a830..0ecda09 100644
--- a/vendor/github.com/docker/libnetwork/osl/interface_linux.go
+++ b/vendor/github.com/docker/libnetwork/osl/interface_linux.go
@@ -8,9 +8,9 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netns"
 )
@@ -26,7 +26,6 @@
 	mac         net.HardwareAddr
 	address     *net.IPNet
 	addressIPv6 *net.IPNet
-	ipAliases   []*net.IPNet
 	llAddrs     []*net.IPNet
 	routes      []*net.IPNet
 	bridge      bool
@@ -97,13 +96,6 @@
 	return i.llAddrs
 }
 
-func (i *nwIface) IPAliases() []*net.IPNet {
-	i.Lock()
-	defer i.Unlock()
-
-	return i.ipAliases
-}
-
 func (i *nwIface) Routes() []*net.IPNet {
 	i.Lock()
 	defer i.Unlock()
@@ -337,7 +329,6 @@
 		{setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %v", ifaceName, i.AddressIPv6())},
 		{setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())},
 		{setInterfaceLinkLocalIPs, fmt.Sprintf("error setting interface %q link local IPs to %v", ifaceName, i.LinkLocalAddresses())},
-		{setInterfaceIPAliases, fmt.Sprintf("error setting interface %q IP Aliases to %v", ifaceName, i.IPAliases())},
 	}
 
 	for _, config := range ifaceConfigurators {
@@ -399,16 +390,6 @@
 	return nil
 }
 
-func setInterfaceIPAliases(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
-	for _, si := range i.IPAliases() {
-		ipAddr := &netlink.Addr{IPNet: si}
-		if err := nlh.AddrAdd(iface, ipAddr); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
 func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
 	return nlh.LinkSetName(iface, i.DstName())
 }
diff --git a/vendor/github.com/docker/libnetwork/osl/namespace_linux.go b/vendor/github.com/docker/libnetwork/osl/namespace_linux.go
index d6b9d78..6ddf7f1 100644
--- a/vendor/github.com/docker/libnetwork/osl/namespace_linux.go
+++ b/vendor/github.com/docker/libnetwork/osl/namespace_linux.go
@@ -14,10 +14,10 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/libnetwork/ns"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netns"
 )
@@ -356,6 +356,22 @@
 	return n.nlHandle.LinkSetUp(iface)
 }
 
+func (n *networkNamespace) AddLoopbackAliasIP(ip *net.IPNet) error {
+	iface, err := n.nlHandle.LinkByName("lo")
+	if err != nil {
+		return err
+	}
+	return n.nlHandle.AddrAdd(iface, &netlink.Addr{IPNet: ip})
+}
+
+func (n *networkNamespace) RemoveLoopbackAliasIP(ip *net.IPNet) error {
+	iface, err := n.nlHandle.LinkByName("lo")
+	if err != nil {
+		return err
+	}
+	return n.nlHandle.AddrDel(iface, &netlink.Addr{IPNet: ip})
+}
+
 func (n *networkNamespace) InvokeFunc(f func()) error {
 	return nsInvoke(n.nsPath(), func(nsFD int) error { return nil }, func(callerFD int) error {
 		f()
diff --git a/vendor/github.com/docker/libnetwork/osl/neigh_linux.go b/vendor/github.com/docker/libnetwork/osl/neigh_linux.go
index 161ffa7..4e47948 100644
--- a/vendor/github.com/docker/libnetwork/osl/neigh_linux.go
+++ b/vendor/github.com/docker/libnetwork/osl/neigh_linux.go
@@ -5,7 +5,7 @@
 	"fmt"
 	"net"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink"
 )
 
@@ -91,9 +91,7 @@
 			if nh.linkDst != "" {
 				nlnh.LinkIndex = iface.Attrs().Index
 			}
-			if err := nlh.NeighDel(nlnh); err != nil {
-				logrus.Warnf("Deleting bridge mac mac %s failed, %v", dstMac, err)
-			}
+			nlh.NeighDel(nlnh)
 		}
 	}
 
diff --git a/vendor/github.com/docker/libnetwork/osl/options_linux.go b/vendor/github.com/docker/libnetwork/osl/options_linux.go
index 64309d0..8186696 100644
--- a/vendor/github.com/docker/libnetwork/osl/options_linux.go
+++ b/vendor/github.com/docker/libnetwork/osl/options_linux.go
@@ -66,12 +66,6 @@
 	}
 }
 
-func (n *networkNamespace) IPAliases(list []*net.IPNet) IfaceOption {
-	return func(i *nwIface) {
-		i.ipAliases = list
-	}
-}
-
 func (n *networkNamespace) Routes(routes []*net.IPNet) IfaceOption {
 	return func(i *nwIface) {
 		i.routes = routes
diff --git a/vendor/github.com/docker/libnetwork/osl/sandbox.go b/vendor/github.com/docker/libnetwork/osl/sandbox.go
index 64288f9..6ffc467 100644
--- a/vendor/github.com/docker/libnetwork/osl/sandbox.go
+++ b/vendor/github.com/docker/libnetwork/osl/sandbox.go
@@ -32,6 +32,12 @@
 	// Unset the previously set default IPv6 gateway in the sandbox
 	UnsetGatewayIPv6() error
 
+	// AddLoopbackAliasIP adds the passed IP address to the sandbox loopback interface
+	AddLoopbackAliasIP(ip *net.IPNet) error
+
+	// RemoveLoopbackAliasIP removes the passed IP address from the sandbox loopback interface
+	RemoveLoopbackAliasIP(ip *net.IPNet) error
+
 	// Add a static route to the sandbox.
 	AddStaticRoute(*types.StaticRoute) error
 
@@ -91,9 +97,6 @@
 	// LinkLocalAddresses returns an option setter to set the link-local IP addresses.
 	LinkLocalAddresses([]*net.IPNet) IfaceOption
 
-	// IPAliases returns an option setter to set IP address Aliases
-	IPAliases([]*net.IPNet) IfaceOption
-
 	// Master returns an option setter to set the master interface if any for this
 	// interface. The master interface name should refer to the srcname of a
 	// previously added interface of type bridge.
@@ -150,9 +153,6 @@
 	// LinkLocalAddresses returns the link-local IP addresses assigned to the interface.
 	LinkLocalAddresses() []*net.IPNet
 
-	// IPAliases returns the IP address aliases assigned to the interface.
-	IPAliases() []*net.IPNet
-
 	// IP routes for the interface.
 	Routes() []*net.IPNet
 
diff --git a/vendor/github.com/docker/libnetwork/portallocator/portallocator_freebsd.go b/vendor/github.com/docker/libnetwork/portallocator/portallocator_freebsd.go
new file mode 100644
index 0000000..97d7fbb
--- /dev/null
+++ b/vendor/github.com/docker/libnetwork/portallocator/portallocator_freebsd.go
@@ -0,0 +1,42 @@
+package portallocator
+
+import (
+	"bytes"
+	"fmt"
+	"os/exec"
+)
+
+func getDynamicPortRange() (start int, end int, err error) {
+	portRangeKernelSysctl := []string{"net.inet.ip.portrange.hifirst", "net.ip.portrange.hilast"}
+	portRangeFallback := fmt.Sprintf("using fallback port range %d-%d", DefaultPortRangeStart, DefaultPortRangeEnd)
+	portRangeLowCmd := exec.Command("/sbin/sysctl", portRangeKernelSysctl[0])
+	var portRangeLowOut bytes.Buffer
+	portRangeLowCmd.Stdout = &portRangeLowOut
+	cmdErr := portRangeLowCmd.Run()
+	if cmdErr != nil {
+		return 0, 0, fmt.Errorf("port allocator - sysctl net.inet.ip.portrange.hifirst failed - %s: %v", portRangeFallback, err)
+	}
+	n, err := fmt.Sscanf(portRangeLowOut.String(), "%d", &start)
+	if n != 1 || err != nil {
+		if err == nil {
+			err = fmt.Errorf("unexpected count of parsed numbers (%d)", n)
+		}
+		return 0, 0, fmt.Errorf("port allocator - failed to parse system ephemeral port range start from %s - %s: %v", portRangeLowOut.String(), portRangeFallback, err)
+	}
+
+	portRangeHighCmd := exec.Command("/sbin/sysctl", portRangeKernelSysctl[1])
+	var portRangeHighOut bytes.Buffer
+	portRangeHighCmd.Stdout = &portRangeHighOut
+	cmdErr = portRangeHighCmd.Run()
+	if cmdErr != nil {
+		return 0, 0, fmt.Errorf("port allocator - sysctl net.inet.ip.portrange.hilast failed - %s: %v", portRangeFallback, err)
+	}
+	n, err = fmt.Sscanf(portRangeHighOut.String(), "%d", &end)
+	if n != 1 || err != nil {
+		if err == nil {
+			err = fmt.Errorf("unexpected count of parsed numbers (%d)", n)
+		}
+		return 0, 0, fmt.Errorf("port allocator - failed to parse system ephemeral port range end from %s - %s: %v", portRangeHighOut.String(), portRangeFallback, err)
+	}
+	return start, end, nil
+}
diff --git a/vendor/github.com/docker/libnetwork/portmapper/mapper.go b/vendor/github.com/docker/libnetwork/portmapper/mapper.go
index 7f2a67c..f480eda 100644
--- a/vendor/github.com/docker/libnetwork/portmapper/mapper.go
+++ b/vendor/github.com/docker/libnetwork/portmapper/mapper.go
@@ -6,9 +6,9 @@
 	"net"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/iptables"
 	"github.com/docker/libnetwork/portallocator"
+	"github.com/sirupsen/logrus"
 )
 
 type mapping struct {
diff --git a/vendor/github.com/docker/libnetwork/resolvconf/resolvconf.go b/vendor/github.com/docker/libnetwork/resolvconf/resolvconf.go
index 9da6922..5cb251b 100644
--- a/vendor/github.com/docker/libnetwork/resolvconf/resolvconf.go
+++ b/vendor/github.com/docker/libnetwork/resolvconf/resolvconf.go
@@ -8,10 +8,10 @@
 	"strings"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/libnetwork/resolvconf/dns"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/vendor/github.com/docker/libnetwork/resolver.go b/vendor/github.com/docker/libnetwork/resolver.go
index ff472d0..83382b6 100644
--- a/vendor/github.com/docker/libnetwork/resolver.go
+++ b/vendor/github.com/docker/libnetwork/resolver.go
@@ -8,9 +8,9 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
 	"github.com/miekg/dns"
+	"github.com/sirupsen/logrus"
 )
 
 // Resolver represents the embedded DNS server in Docker. It operates
@@ -231,7 +231,7 @@
 
 	if addr == nil && ipv6Miss {
 		// Send a reply without any Answer sections
-		logrus.Debugf("Lookup name %s present without IPv6 address", name)
+		logrus.Debugf("[resolver] lookup name %s present without IPv6 address", name)
 		resp := createRespMsg(query)
 		return resp, nil
 	}
@@ -239,7 +239,7 @@
 		return nil, nil
 	}
 
-	logrus.Debugf("Lookup for %s: IP %v", name, addr)
+	logrus.Debugf("[resolver] lookup for %s: IP %v", name, addr)
 
 	resp := createRespMsg(query)
 	if len(addr) > 1 {
@@ -280,7 +280,7 @@
 		return nil, nil
 	}
 
-	logrus.Debugf("Lookup for IP %s: name %s", parts[0], host)
+	logrus.Debugf("[resolver] lookup for IP %s: name %s", parts[0], host)
 	fqdn := dns.Fqdn(host)
 
 	resp := new(dns.Msg)
@@ -431,10 +431,12 @@
 				}
 			}
 			if err != nil {
-				logrus.Warnf("Connect failed: %s", err)
+				logrus.Warnf("[resolver] connect failed: %s", err)
 				continue
 			}
-			logrus.Debugf("Query %s[%d] from %s, forwarding to %s:%s", name, query.Question[0].Qtype,
+
+			queryType := dns.TypeToString[query.Question[0].Qtype]
+			logrus.Debugf("[resolver] query %s (%s) from %s, forwarding to %s:%s", name, queryType,
 				extConn.LocalAddr().String(), proto, extDNS.IPStr)
 
 			// Timeout has to be set for every IO operation.
@@ -450,7 +452,7 @@
 				old := r.tStamp
 				r.tStamp = time.Now()
 				if r.tStamp.Sub(old) > logInterval {
-					logrus.Errorf("More than %v concurrent queries from %s", maxConcurrent, extConn.LocalAddr().String())
+					logrus.Errorf("[resolver] more than %v concurrent queries from %s", maxConcurrent, extConn.LocalAddr().String())
 				}
 				continue
 			}
@@ -458,7 +460,7 @@
 			err = co.WriteMsg(query)
 			if err != nil {
 				r.forwardQueryEnd()
-				logrus.Debugf("Send to DNS server failed, %s", err)
+				logrus.Debugf("[resolver] send to DNS server failed, %s", err)
 				continue
 			}
 
@@ -467,22 +469,32 @@
 			// client can retry over TCP
 			if err != nil && err != dns.ErrTruncated {
 				r.forwardQueryEnd()
-				logrus.Debugf("Read from DNS server failed, %s", err)
+				logrus.Debugf("[resolver] read from DNS server failed, %s", err)
 				continue
 			}
 			r.forwardQueryEnd()
 			if resp != nil {
+				answers := 0
 				for _, rr := range resp.Answer {
 					h := rr.Header()
 					switch h.Rrtype {
 					case dns.TypeA:
+						answers++
 						ip := rr.(*dns.A).A
+						logrus.Debugf("[resolver] received A record %q for %q from %s:%s", ip, h.Name, proto, extDNS.IPStr)
 						r.backend.HandleQueryResp(h.Name, ip)
 					case dns.TypeAAAA:
+						answers++
 						ip := rr.(*dns.AAAA).AAAA
+						logrus.Debugf("[resolver] received AAAA record %q for %q from %s:%s", ip, h.Name, proto, extDNS.IPStr)
 						r.backend.HandleQueryResp(h.Name, ip)
 					}
 				}
+				if resp.Answer == nil || answers == 0 {
+					logrus.Debugf("[resolver] external DNS %s:%s did not return any %s records for %q", proto, extDNS.IPStr, queryType, name)
+				}
+			} else {
+				logrus.Debugf("[resolver] external DNS %s:%s returned empty response for %q", proto, extDNS.IPStr, name)
 			}
 			resp.Compress = true
 			break
@@ -493,7 +505,7 @@
 	}
 
 	if err = w.WriteMsg(resp); err != nil {
-		logrus.Errorf("error writing resolver resp, %s", err)
+		logrus.Errorf("[resolver] error writing resolver resp, %s", err)
 	}
 }
 
@@ -514,7 +526,7 @@
 	defer r.queryLock.Unlock()
 
 	if r.count == 0 {
-		logrus.Error("Invalid concurrent query count")
+		logrus.Error("[resolver] invalid concurrent query count")
 	} else {
 		r.count--
 	}
diff --git a/vendor/github.com/docker/libnetwork/resolver_unix.go b/vendor/github.com/docker/libnetwork/resolver_unix.go
index 5fcc6b9..b35009e 100644
--- a/vendor/github.com/docker/libnetwork/resolver_unix.go
+++ b/vendor/github.com/docker/libnetwork/resolver_unix.go
@@ -9,9 +9,9 @@
 	"os/exec"
 	"runtime"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/libnetwork/iptables"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netns"
 )
 
diff --git a/vendor/github.com/docker/libnetwork/sandbox.go b/vendor/github.com/docker/libnetwork/sandbox.go
index 4667406..315195e 100644
--- a/vendor/github.com/docker/libnetwork/sandbox.go
+++ b/vendor/github.com/docker/libnetwork/sandbox.go
@@ -9,11 +9,11 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/etchosts"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/osl"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 // Sandbox provides the control over the network container entity. It is a one to one mapping with the container.
@@ -709,8 +709,15 @@
 
 	ep.Lock()
 	joinInfo := ep.joinInfo
+	vip := ep.virtualIP
 	ep.Unlock()
 
+	if len(vip) != 0 {
+		if err := osSbox.RemoveLoopbackAliasIP(&net.IPNet{IP: vip, Mask: net.CIDRMask(32, 32)}); err != nil {
+			logrus.Warnf("Remove virtual IP %v failed: %v", vip, err)
+		}
+	}
+
 	if joinInfo == nil {
 		return
 	}
@@ -767,10 +774,6 @@
 		if len(i.llAddrs) != 0 {
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
 		}
-		if len(ep.virtualIP) != 0 {
-			vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)}
-			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias}))
-		}
 		Ifaces[fmt.Sprintf("%s+%s", i.srcName, i.dstPrefix)] = ifaceOptions
 		if joinInfo != nil {
 			routes = append(routes, joinInfo.StaticRoutes...)
@@ -818,10 +821,6 @@
 		if len(i.llAddrs) != 0 {
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
 		}
-		if len(ep.virtualIP) != 0 {
-			vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)}
-			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias}))
-		}
 		if i.mac != nil {
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
 		}
@@ -831,6 +830,13 @@
 		}
 	}
 
+	if len(ep.virtualIP) != 0 {
+		err := sb.osSbox.AddLoopbackAliasIP(&net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)})
+		if err != nil {
+			return fmt.Errorf("failed to add virtual IP %v: %v", ep.virtualIP, err)
+		}
+	}
+
 	if joinInfo != nil {
 		// Set up non-interface routes.
 		for _, r := range joinInfo.StaticRoutes {
@@ -910,6 +916,13 @@
 			break
 		}
 	}
+
+	if index == -1 {
+		logrus.Warnf("Endpoint %s has already been deleted", ep.Name())
+		sb.Unlock()
+		return nil
+	}
+
 	heap.Remove(&sb.endpoints, index)
 	for _, e := range sb.endpoints {
 		if len(e.Gateway()) > 0 {
diff --git a/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go b/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go
index 867cc8a..afa3e79 100644
--- a/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go
+++ b/vendor/github.com/docker/libnetwork/sandbox_dns_unix.go
@@ -11,11 +11,11 @@
 	"strconv"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/etchosts"
 	"github.com/docker/libnetwork/resolvconf"
 	"github.com/docker/libnetwork/resolvconf/dns"
 	"github.com/docker/libnetwork/types"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -67,11 +67,7 @@
 		return err
 	}
 
-	if err := sb.setupDNS(); err != nil {
-		return err
-	}
-
-	return nil
+	return sb.setupDNS()
 }
 
 func (sb *sandbox) buildHostsFile() error {
@@ -197,14 +193,26 @@
 	// This is for the host mode networking
 	if sb.config.originResolvConfPath != "" {
 		if err := copyFile(sb.config.originResolvConfPath, sb.config.resolvConfPath); err != nil {
-			return fmt.Errorf("could not copy source resolv.conf file %s to %s: %v", sb.config.originResolvConfPath, sb.config.resolvConfPath, err)
+			if !os.IsNotExist(err) {
+				return fmt.Errorf("could not copy source resolv.conf file %s to %s: %v", sb.config.originResolvConfPath, sb.config.resolvConfPath, err)
+			}
+			logrus.Infof("%s does not exist, we create an empty resolv.conf for container", sb.config.originResolvConfPath)
+			if err := createFile(sb.config.resolvConfPath); err != nil {
+				return err
+			}
 		}
 		return nil
 	}
 
 	currRC, err := resolvconf.Get()
 	if err != nil {
-		return err
+		if !os.IsNotExist(err) {
+			return err
+		}
+		// it's ok to continue if /etc/resolv.conf doesn't exist, default resolvers (Google's Public DNS)
+		// will be used
+		currRC = &resolvconf.File{}
+		logrus.Infof("/etc/resolv.conf does not exist")
 	}
 
 	if len(sb.config.dnsList) > 0 || len(sb.config.dnsSearchList) > 0 || len(sb.config.dnsOptionsList) > 0 {
diff --git a/vendor/github.com/docker/libnetwork/sandbox_externalkey_unix.go b/vendor/github.com/docker/libnetwork/sandbox_externalkey_unix.go
index c33398f..f4c4276 100644
--- a/vendor/github.com/docker/libnetwork/sandbox_externalkey_unix.go
+++ b/vendor/github.com/docker/libnetwork/sandbox_externalkey_unix.go
@@ -10,9 +10,9 @@
 	"net"
 	"os"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/types"
 	"github.com/opencontainers/runc/libcontainer/configs"
+	"github.com/sirupsen/logrus"
 )
 
 const udsBase = "/run/docker/libnetwork/"
diff --git a/vendor/github.com/docker/libnetwork/sandbox_store.go b/vendor/github.com/docker/libnetwork/sandbox_store.go
index b92a544..a083644 100644
--- a/vendor/github.com/docker/libnetwork/sandbox_store.go
+++ b/vendor/github.com/docker/libnetwork/sandbox_store.go
@@ -5,9 +5,9 @@
 	"encoding/json"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/datastore"
 	"github.com/docker/libnetwork/osl"
+	"github.com/sirupsen/logrus"
 )
 
 const (
diff --git a/vendor/github.com/docker/libnetwork/service.go b/vendor/github.com/docker/libnetwork/service.go
index 5a0d7e0..63095f3 100644
--- a/vendor/github.com/docker/libnetwork/service.go
+++ b/vendor/github.com/docker/libnetwork/service.go
@@ -89,4 +89,5 @@
 
 	// Back pointer to service to which the loadbalancer belongs.
 	service *service
+	sync.Mutex
 }
diff --git a/vendor/github.com/docker/libnetwork/service_common.go b/vendor/github.com/docker/libnetwork/service_common.go
index 7e3367c..fe54ea3 100644
--- a/vendor/github.com/docker/libnetwork/service_common.go
+++ b/vendor/github.com/docker/libnetwork/service_common.go
@@ -5,8 +5,8 @@
 import (
 	"net"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libnetwork/common"
+	"github.com/sirupsen/logrus"
 )
 
 func (c *controller) addEndpointNameResolution(svcName, svcID, nID, eID, containerName string, vip net.IP, serviceAliases, taskAliases []string, ip net.IP, addService bool, method string) error {
@@ -287,7 +287,7 @@
 	// Add loadbalancer service and backend in all sandboxes in
 	// the network only if vip is valid.
 	if len(vip) != 0 {
-		n.(*network).addLBBackend(ip, vip, lb.fwMark, ingressPorts)
+		n.(*network).addLBBackend(ip, vip, lb, ingressPorts)
 	}
 
 	// Add the appropriate name resolutions
@@ -355,7 +355,7 @@
 	// Remove loadbalancer service(if needed) and backend in all
 	// sandboxes in the network only if the vip is valid.
 	if len(vip) != 0 && entries == 0 {
-		n.(*network).rmLBBackend(ip, vip, lb.fwMark, ingressPorts, rmService)
+		n.(*network).rmLBBackend(ip, vip, lb, ingressPorts, rmService)
 	}
 
 	// Delete the name resolutions
diff --git a/vendor/github.com/docker/libnetwork/service_linux.go b/vendor/github.com/docker/libnetwork/service_linux.go
index 784c178..d8a95b2 100644
--- a/vendor/github.com/docker/libnetwork/service_linux.go
+++ b/vendor/github.com/docker/libnetwork/service_linux.go
@@ -14,12 +14,12 @@
 	"sync"
 	"syscall"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/libnetwork/iptables"
 	"github.com/docker/libnetwork/ipvs"
 	"github.com/docker/libnetwork/ns"
 	"github.com/gogo/protobuf/proto"
+	"github.com/sirupsen/logrus"
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
 )
@@ -111,7 +111,7 @@
 
 // Add loadbalancer backend to all sandboxes which has a connection to
 // this network. If needed add the service as well.
-func (n *network) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig) {
+func (n *network) addLBBackend(ip, vip net.IP, lb *loadBalancer, ingressPorts []*PortConfig) {
 	n.WalkEndpoints(func(e Endpoint) bool {
 		ep := e.(*endpoint)
 		if sb, ok := ep.getSandbox(); ok {
@@ -124,7 +124,7 @@
 				gwIP = ep.Iface().Address().IP
 			}
 
-			sb.addLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, n.ingress)
+			sb.addLBBackend(ip, vip, lb.fwMark, ingressPorts, ep.Iface().Address(), gwIP, n.ingress)
 		}
 
 		return false
@@ -134,7 +134,7 @@
 // Remove loadbalancer backend from all sandboxes which has a
 // connection to this network. If needed remove the service entry as
 // well, as specified by the rmService bool.
-func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, rmService bool) {
+func (n *network) rmLBBackend(ip, vip net.IP, lb *loadBalancer, ingressPorts []*PortConfig, rmService bool) {
 	n.WalkEndpoints(func(e Endpoint) bool {
 		ep := e.(*endpoint)
 		if sb, ok := ep.getSandbox(); ok {
@@ -147,7 +147,7 @@
 				gwIP = ep.Iface().Address().IP
 			}
 
-			sb.rmLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService, n.ingress)
+			sb.rmLBBackend(ip, vip, lb.fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService, n.ingress)
 		}
 
 		return false
diff --git a/vendor/github.com/docker/libnetwork/service_windows.go b/vendor/github.com/docker/libnetwork/service_windows.go
index 6fe521e..9ed3e06 100644
--- a/vendor/github.com/docker/libnetwork/service_windows.go
+++ b/vendor/github.com/docker/libnetwork/service_windows.go
@@ -1,11 +1,146 @@
 package libnetwork
 
-import "net"
+import (
+	"net"
 
-func (n *network) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig) {
+	"github.com/Microsoft/hcsshim"
+	"github.com/docker/docker/pkg/system"
+	"github.com/sirupsen/logrus"
+)
+
+type policyLists struct {
+	ilb *hcsshim.PolicyList
+	elb *hcsshim.PolicyList
 }
 
-func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, rmService bool) {
+var lbPolicylistMap map[*loadBalancer]*policyLists
+
+func init() {
+	lbPolicylistMap = make(map[*loadBalancer]*policyLists)
+}
+
+func (n *network) addLBBackend(ip, vip net.IP, lb *loadBalancer, ingressPorts []*PortConfig) {
+
+	if system.GetOSVersion().Build > 16236 {
+		lb.Lock()
+		defer lb.Unlock()
+		//find the load balancer IP for the network.
+		var sourceVIP string
+		for _, e := range n.Endpoints() {
+			epInfo := e.Info()
+			if epInfo == nil {
+				continue
+			}
+			if epInfo.LoadBalancer() {
+				sourceVIP = epInfo.Iface().Address().IP.String()
+				break
+			}
+		}
+
+		if sourceVIP == "" {
+			logrus.Errorf("Failed to find load balancer IP for network %s", n.Name())
+			return
+		}
+
+		var endpoints []hcsshim.HNSEndpoint
+
+		for eid := range lb.backEnds {
+			//Call HNS to get back ID (GUID) corresponding to the endpoint.
+			hnsEndpoint, err := hcsshim.GetHNSEndpointByName(eid)
+			if err != nil {
+				logrus.Errorf("Failed to find HNS ID for endpoint %v: %v", eid, err)
+				return
+			}
+
+			endpoints = append(endpoints, *hnsEndpoint)
+		}
+
+		if policies, ok := lbPolicylistMap[lb]; ok {
+
+			if policies.ilb != nil {
+				policies.ilb.Delete()
+				policies.ilb = nil
+			}
+
+			if policies.elb != nil {
+				policies.elb.Delete()
+				policies.elb = nil
+			}
+			delete(lbPolicylistMap, lb)
+		}
+
+		ilbPolicy, err := hcsshim.AddLoadBalancer(endpoints, true, sourceVIP, vip.String(), 0, 0, 0)
+		if err != nil {
+			logrus.Errorf("Failed to add ILB policy for service %s (%s) with endpoints %v using load balancer IP %s on network %s: %v",
+				lb.service.name, vip.String(), endpoints, sourceVIP, n.Name(), err)
+			return
+		}
+
+		lbPolicylistMap[lb] = &policyLists{
+			ilb: ilbPolicy,
+		}
+
+		publishedPorts := make(map[uint32]uint32)
+
+		for i, port := range ingressPorts {
+			protocol := uint16(6)
+
+			// Skip already published port
+			if publishedPorts[port.PublishedPort] == port.TargetPort {
+				continue
+			}
+
+			if port.Protocol == ProtocolUDP {
+				protocol = 17
+			}
+
+			// check if already has udp matching to add wild card publishing
+			for j := i + 1; j < len(ingressPorts); j++ {
+				if ingressPorts[j].TargetPort == port.TargetPort &&
+					ingressPorts[j].PublishedPort == port.PublishedPort {
+					protocol = 0
+				}
+			}
+
+			publishedPorts[port.PublishedPort] = port.TargetPort
+
+			lbPolicylistMap[lb].elb, err = hcsshim.AddLoadBalancer(endpoints, false, sourceVIP, "", protocol, uint16(port.TargetPort), uint16(port.PublishedPort))
+			if err != nil {
+				logrus.Errorf("Failed to add ELB policy for service %s (ip:%s target port:%v published port:%v) with endpoints %v using load balancer IP %s on network %s: %v",
+					lb.service.name, vip.String(), uint16(port.TargetPort), uint16(port.PublishedPort), endpoints, sourceVIP, n.Name(), err)
+				return
+			}
+		}
+	}
+}
+
+func (n *network) rmLBBackend(ip, vip net.IP, lb *loadBalancer, ingressPorts []*PortConfig, rmService bool) {
+	if system.GetOSVersion().Build > 16236 {
+		if len(lb.backEnds) > 0 {
+			//Reprogram HNS (actually VFP) with the existing backends.
+			n.addLBBackend(ip, vip, lb, ingressPorts)
+		} else {
+			lb.Lock()
+			defer lb.Unlock()
+			logrus.Debugf("No more backends for service %s (ip:%s).  Removing all policies", lb.service.name, lb.vip.String())
+
+			if policyLists, ok := lbPolicylistMap[lb]; ok {
+				if policyLists.ilb != nil {
+					policyLists.ilb.Delete()
+					policyLists.ilb = nil
+				}
+
+				if policyLists.elb != nil {
+					policyLists.elb.Delete()
+					policyLists.elb = nil
+				}
+				delete(lbPolicylistMap, lb)
+
+			} else {
+				logrus.Errorf("Failed to find policies for service %s (%s)", lb.service.name, lb.vip.String())
+			}
+		}
+	}
 }
 
 func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
diff --git a/vendor/github.com/docker/libnetwork/store.go b/vendor/github.com/docker/libnetwork/store.go
index 398794b..1a897bf 100644
--- a/vendor/github.com/docker/libnetwork/store.go
+++ b/vendor/github.com/docker/libnetwork/store.go
@@ -4,12 +4,12 @@
 	"fmt"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/libkv/store/boltdb"
 	"github.com/docker/libkv/store/consul"
 	"github.com/docker/libkv/store/etcd"
 	"github.com/docker/libkv/store/zookeeper"
 	"github.com/docker/libnetwork/datastore"
+	"github.com/sirupsen/logrus"
 )
 
 func registerKVStores() {
diff --git a/vendor/github.com/docker/libnetwork/types/types.go b/vendor/github.com/docker/libnetwork/types/types.go
index da113e2..164b180 100644
--- a/vendor/github.com/docker/libnetwork/types/types.go
+++ b/vendor/github.com/docker/libnetwork/types/types.go
@@ -129,11 +129,11 @@
 func (p *PortBinding) String() string {
 	ret := fmt.Sprintf("%s/", p.Proto)
 	if p.IP != nil {
-		ret = fmt.Sprintf("%s%s", ret, p.IP.String())
+		ret += p.IP.String()
 	}
 	ret = fmt.Sprintf("%s:%d/", ret, p.Port)
 	if p.HostIP != nil {
-		ret = fmt.Sprintf("%s%s", ret, p.HostIP.String())
+		ret += p.HostIP.String()
 	}
 	ret = fmt.Sprintf("%s:%d", ret, p.HostPort)
 	return ret
diff --git a/vendor/github.com/docker/libnetwork/vendor.conf b/vendor/github.com/docker/libnetwork/vendor.conf
index 203e1ce..c97f551 100644
--- a/vendor/github.com/docker/libnetwork/vendor.conf
+++ b/vendor/github.com/docker/libnetwork/vendor.conf
@@ -1,8 +1,7 @@
-github.com/Azure/go-ansiterm 04b7f292a41fcb5da32dda536c0807fc13e8351c
+github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e
 github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060
 github.com/Microsoft/go-winio ce2922f643c8fd76b46cadc7f404a06282678b34
-github.com/Microsoft/hcsshim e439b7d2b63f036d3a50c93a9e0b154a0d50e788
-github.com/Sirupsen/logrus 4b6ea7319e214d98c938f12692336f7ca9348d6b
+github.com/Microsoft/hcsshim v0.6.3
 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
 github.com/boltdb/bolt c6ba97b89e0454fec9aa92e1d33a4e2c5fc1f631
@@ -11,9 +10,9 @@
 github.com/coreos/go-systemd b4a58d95188dd092ae20072bac14cece0e67c388
 github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d
 
-github.com/docker/docker 9c96768eae4b3a65147b47a55c850c103ab8972d
-github.com/docker/go-connections 34b5052da6b11e27f5f2e357b38b571ddddd3928
-github.com/docker/go-events 2e7d352816128aa84f4d29b2a21d400133701a0d
+github.com/docker/docker 2cac43e3573893cf8fd816e0ad5615426acb87f4 https://github.com/dmcgowan/docker.git
+github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
+github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
 github.com/docker/go-units 8e2d4523730c73120e10d4652f36ad6010998f4e
 github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef
 
@@ -31,9 +30,10 @@
 github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
 github.com/mattn/go-shellwords 525bedee691b5a8df547cb5cf9f86b7fb1883e24
 github.com/miekg/dns d27455715200c7d3e321a1e5cadb27c9ee0b0f02
-github.com/opencontainers/runc ba1568de399395774ad84c2ace65937814c542ed
+github.com/opencontainers/runc 8694d576ea3ce3c9e2c804b7f91b4e1e9a575d1c https://github.com/dmcgowan/runc.git
 github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374
 github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1
+github.com/sirupsen/logrus v1.0.1
 github.com/stretchr/testify dab07ac62d4905d3e48d17dc549c684ac3b7c15a
 github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852
 github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065
diff --git a/vendor/github.com/docker/swarmkit/README.md b/vendor/github.com/docker/swarmkit/README.md
index 4900fe3..ffc744c 100644
--- a/vendor/github.com/docker/swarmkit/README.md
+++ b/vendor/github.com/docker/swarmkit/README.md
@@ -153,6 +153,12 @@
 $ swarmd -d /tmp/node-3 --hostname node-3 --join-addr 127.0.0.1:4242 --join-token <Worker Token>
 ```
 
+If joining as a manager, also specify the listen-control-api.
+
+```sh
+$ swarmd -d /tmp/node-4 --hostname node-4 --join-addr 127.0.0.1:4242 --join-token <Manager Token> --listen-control-api /tmp/node-4/swarm.sock --listen-remote-api 127.0.0.1:4245
+```
+
 In a fourth terminal, use `swarmctl` to explore and control the cluster. Before
 running `swarmctl`, set the `SWARM_SOCKET` environment variable to the path of the
 manager socket that was specified in `--listen-control-api` when starting the
@@ -168,6 +174,7 @@
 3x12fpoi36eujbdkgdnbvbi6r  node-2  ACCEPTED    READY   ACTIVE
 4spl3tyipofoa2iwqgabsdcve  node-1  ACCEPTED    READY   ACTIVE        REACHABLE *
 dknwk1uqxhnyyujq66ho0h54t  node-3  ACCEPTED    READY   ACTIVE
+zw3rwfawdasdewfq66ho34eaw  node-4  ACCEPTED    READY   ACTIVE        REACHABLE
 
 
 ```
diff --git a/vendor/github.com/docker/swarmkit/agent/exec/controller.go b/vendor/github.com/docker/swarmkit/agent/exec/controller.go
index 1cafb47..85110ba 100644
--- a/vendor/github.com/docker/swarmkit/agent/exec/controller.go
+++ b/vendor/github.com/docker/swarmkit/agent/exec/controller.go
@@ -4,12 +4,12 @@
 	"fmt"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/equality"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/protobuf/ptypes"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/vendor/github.com/docker/swarmkit/agent/session.go b/vendor/github.com/docker/swarmkit/agent/session.go
index faa1fa8..0c00c4f 100644
--- a/vendor/github.com/docker/swarmkit/agent/session.go
+++ b/vendor/github.com/docker/swarmkit/agent/session.go
@@ -5,10 +5,10 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/connectionbroker"
 	"github.com/docker/swarmkit/log"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
diff --git a/vendor/github.com/docker/swarmkit/agent/worker.go b/vendor/github.com/docker/swarmkit/agent/worker.go
index ff138c2..6b50005 100644
--- a/vendor/github.com/docker/swarmkit/agent/worker.go
+++ b/vendor/github.com/docker/swarmkit/agent/worker.go
@@ -3,12 +3,12 @@
 import (
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/boltdb/bolt"
 	"github.com/docker/swarmkit/agent/exec"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/watch"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/vendor/github.com/docker/swarmkit/api/README.md b/vendor/github.com/docker/swarmkit/api/README.md
index 78eee22..a7ec3fc 100644
--- a/vendor/github.com/docker/swarmkit/api/README.md
+++ b/vendor/github.com/docker/swarmkit/api/README.md
@@ -6,3 +6,19 @@
 ```
 
 Click [here](https://github.com/google/protobuf) for more information about protobuf.
+
+The `api.pb.txt` file contains merged descriptors of all defined services and messages.
+Definitions present here are considered frozen after the release.
+
+At release time, the current `api.pb.txt` file will be moved into place to
+freeze the API changes for the minor version. For example, when 1.0.0 is
+released, `api.pb.txt` should be moved to `1.0.txt`. Notice that we leave off
+the patch number, since the API will be completely locked down for a given
+patch series.
+
+We may find that by default, protobuf descriptors are too noisy to lock down
+API changes. In that case, we may filter out certain fields in the descriptors,
+possibly regenerating for old versions.
+
+This process is similar to the [process used to ensure backwards compatibility
+in Go](https://github.com/golang/go/tree/master/api).
diff --git a/vendor/github.com/docker/swarmkit/api/ca.pb.go b/vendor/github.com/docker/swarmkit/api/ca.pb.go
index 679e4a8..caaa06c 100644
--- a/vendor/github.com/docker/swarmkit/api/ca.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/ca.pb.go
@@ -1,7 +1,223 @@
 // Code generated by protoc-gen-gogo.
-// source: ca.proto
+// source: github.com/docker/swarmkit/api/ca.proto
 // DO NOT EDIT!
 
+/*
+	Package api is a generated protocol buffer package.
+
+	It is generated from these files:
+		github.com/docker/swarmkit/api/ca.proto
+		github.com/docker/swarmkit/api/control.proto
+		github.com/docker/swarmkit/api/dispatcher.proto
+		github.com/docker/swarmkit/api/health.proto
+		github.com/docker/swarmkit/api/logbroker.proto
+		github.com/docker/swarmkit/api/objects.proto
+		github.com/docker/swarmkit/api/raft.proto
+		github.com/docker/swarmkit/api/resource.proto
+		github.com/docker/swarmkit/api/snapshot.proto
+		github.com/docker/swarmkit/api/specs.proto
+		github.com/docker/swarmkit/api/types.proto
+		github.com/docker/swarmkit/api/watch.proto
+
+	It has these top-level messages:
+		NodeCertificateStatusRequest
+		NodeCertificateStatusResponse
+		IssueNodeCertificateRequest
+		IssueNodeCertificateResponse
+		GetRootCACertificateRequest
+		GetRootCACertificateResponse
+		GetUnlockKeyRequest
+		GetUnlockKeyResponse
+		GetNodeRequest
+		GetNodeResponse
+		ListNodesRequest
+		ListNodesResponse
+		UpdateNodeRequest
+		UpdateNodeResponse
+		RemoveNodeRequest
+		RemoveNodeResponse
+		GetTaskRequest
+		GetTaskResponse
+		RemoveTaskRequest
+		RemoveTaskResponse
+		ListTasksRequest
+		ListTasksResponse
+		CreateServiceRequest
+		CreateServiceResponse
+		GetServiceRequest
+		GetServiceResponse
+		UpdateServiceRequest
+		UpdateServiceResponse
+		RemoveServiceRequest
+		RemoveServiceResponse
+		ListServicesRequest
+		ListServicesResponse
+		CreateNetworkRequest
+		CreateNetworkResponse
+		GetNetworkRequest
+		GetNetworkResponse
+		RemoveNetworkRequest
+		RemoveNetworkResponse
+		ListNetworksRequest
+		ListNetworksResponse
+		GetClusterRequest
+		GetClusterResponse
+		ListClustersRequest
+		ListClustersResponse
+		KeyRotation
+		UpdateClusterRequest
+		UpdateClusterResponse
+		GetSecretRequest
+		GetSecretResponse
+		UpdateSecretRequest
+		UpdateSecretResponse
+		ListSecretsRequest
+		ListSecretsResponse
+		CreateSecretRequest
+		CreateSecretResponse
+		RemoveSecretRequest
+		RemoveSecretResponse
+		GetConfigRequest
+		GetConfigResponse
+		UpdateConfigRequest
+		UpdateConfigResponse
+		ListConfigsRequest
+		ListConfigsResponse
+		CreateConfigRequest
+		CreateConfigResponse
+		RemoveConfigRequest
+		RemoveConfigResponse
+		SessionRequest
+		SessionMessage
+		HeartbeatRequest
+		HeartbeatResponse
+		UpdateTaskStatusRequest
+		UpdateTaskStatusResponse
+		TasksRequest
+		TasksMessage
+		AssignmentsRequest
+		Assignment
+		AssignmentChange
+		AssignmentsMessage
+		HealthCheckRequest
+		HealthCheckResponse
+		LogSubscriptionOptions
+		LogSelector
+		LogContext
+		LogAttr
+		LogMessage
+		SubscribeLogsRequest
+		SubscribeLogsMessage
+		ListenSubscriptionsRequest
+		SubscriptionMessage
+		PublishLogsMessage
+		PublishLogsResponse
+		Meta
+		Node
+		Service
+		Endpoint
+		Task
+		NetworkAttachment
+		Network
+		Cluster
+		Secret
+		Config
+		Resource
+		Extension
+		RaftMember
+		JoinRequest
+		JoinResponse
+		LeaveRequest
+		LeaveResponse
+		ProcessRaftMessageRequest
+		ProcessRaftMessageResponse
+		ResolveAddressRequest
+		ResolveAddressResponse
+		InternalRaftRequest
+		StoreAction
+		AttachNetworkRequest
+		AttachNetworkResponse
+		DetachNetworkRequest
+		DetachNetworkResponse
+		StoreSnapshot
+		ClusterSnapshot
+		Snapshot
+		NodeSpec
+		ServiceSpec
+		ReplicatedService
+		GlobalService
+		TaskSpec
+		ResourceReference
+		GenericRuntimeSpec
+		NetworkAttachmentSpec
+		ContainerSpec
+		EndpointSpec
+		NetworkSpec
+		ClusterSpec
+		SecretSpec
+		ConfigSpec
+		Version
+		IndexEntry
+		Annotations
+		NamedGenericResource
+		DiscreteGenericResource
+		GenericResource
+		Resources
+		ResourceRequirements
+		Platform
+		PluginDescription
+		EngineDescription
+		NodeDescription
+		NodeTLSInfo
+		RaftMemberStatus
+		NodeStatus
+		Image
+		Mount
+		RestartPolicy
+		UpdateConfig
+		UpdateStatus
+		ContainerStatus
+		PortStatus
+		TaskStatus
+		NetworkAttachmentConfig
+		IPAMConfig
+		PortConfig
+		Driver
+		IPAMOptions
+		Peer
+		WeightedPeer
+		IssuanceStatus
+		AcceptancePolicy
+		ExternalCA
+		CAConfig
+		OrchestrationConfig
+		TaskDefaults
+		DispatcherConfig
+		RaftConfig
+		EncryptionConfig
+		SpreadOver
+		PlacementPreference
+		Placement
+		JoinTokens
+		RootCA
+		Certificate
+		EncryptionKey
+		ManagerStatus
+		FileTarget
+		SecretReference
+		ConfigReference
+		BlacklistedCertificate
+		HealthConfig
+		MaybeEncryptedRecord
+		RootRotation
+		Privileges
+		Object
+		SelectBySlot
+		SelectByCustom
+		SelectBy
+		WatchRequest
+		WatchMessage
+*/
 package api
 
 import proto "github.com/gogo/protobuf/proto"
@@ -33,6 +249,12 @@
 var _ = fmt.Errorf
 var _ = math.Inf
 
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+
 type NodeCertificateStatusRequest struct {
 	NodeID string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
 }
@@ -401,7 +623,7 @@
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "ca.proto",
+	Metadata: "github.com/docker/swarmkit/api/ca.proto",
 }
 
 // Client API for NodeCA service
@@ -498,7 +720,7 @@
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "ca.proto",
+	Metadata: "github.com/docker/swarmkit/api/ca.proto",
 }
 
 func (m *NodeCertificateStatusRequest) Marshal() (dAtA []byte, err error) {
@@ -2070,47 +2292,48 @@
 	ErrIntOverflowCa   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("ca.proto", fileDescriptorCa) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/ca.proto", fileDescriptorCa) }
 
 var fileDescriptorCa = []byte{
-	// 610 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
-	0x10, 0xee, 0xba, 0x25, 0x6d, 0x27, 0xa1, 0x45, 0xdb, 0x56, 0x32, 0x69, 0xea, 0x54, 0xe6, 0xd0,
-	0x72, 0xc0, 0x6d, 0x03, 0x27, 0xb8, 0x90, 0x04, 0xa9, 0x8a, 0x50, 0x11, 0xda, 0x08, 0xae, 0x95,
-	0xe3, 0x2c, 0xc1, 0x8a, 0xe3, 0x35, 0xde, 0x75, 0x20, 0x37, 0x24, 0x10, 0x6f, 0x80, 0xe0, 0xc4,
-	0x23, 0xf0, 0x1c, 0x11, 0x27, 0x24, 0x2e, 0x9c, 0x22, 0xea, 0x07, 0xe0, 0x19, 0x90, 0xd7, 0x36,
-	0xcd, 0x8f, 0x13, 0xca, 0xc9, 0xbb, 0xb3, 0xdf, 0xf7, 0xcd, 0xcc, 0xb7, 0xe3, 0x85, 0x35, 0xcb,
-	0x34, 0x3c, 0x9f, 0x09, 0x86, 0x71, 0x9b, 0x59, 0x5d, 0xea, 0x1b, 0xfc, 0xb5, 0xe9, 0xf7, 0xba,
-	0xb6, 0x30, 0xfa, 0x27, 0xc5, 0xbc, 0x18, 0x78, 0x94, 0xc7, 0x80, 0x62, 0x9e, 0x7b, 0xd4, 0x4a,
-	0x37, 0xdb, 0x1d, 0xd6, 0x61, 0x72, 0x79, 0x14, 0xad, 0x92, 0xe8, 0x96, 0xe7, 0x04, 0x1d, 0xdb,
-	0x3d, 0x8a, 0x3f, 0x71, 0x50, 0xaf, 0x43, 0xe9, 0x09, 0x6b, 0xd3, 0x3a, 0xf5, 0x85, 0xfd, 0xc2,
-	0xb6, 0x4c, 0x41, 0x9b, 0xc2, 0x14, 0x01, 0x27, 0xf4, 0x55, 0x40, 0xb9, 0xc0, 0xb7, 0x60, 0xd5,
-	0x65, 0x6d, 0x7a, 0x6e, 0xb7, 0x55, 0xb4, 0x8f, 0x0e, 0xd7, 0x6b, 0x10, 0x8e, 0xca, 0xb9, 0x88,
-	0xd2, 0x78, 0x44, 0x72, 0xd1, 0x51, 0xa3, 0xad, 0x7f, 0x41, 0xb0, 0x37, 0x47, 0x85, 0x7b, 0xcc,
-	0xe5, 0x14, 0xdf, 0x87, 0x1c, 0x97, 0x11, 0xa9, 0x92, 0xaf, 0xe8, 0xc6, 0x6c, 0x43, 0x46, 0x83,
-	0xf3, 0xc0, 0x74, 0xad, 0x94, 0x9b, 0x30, 0x70, 0x15, 0xf2, 0xd6, 0xa5, 0xb0, 0xaa, 0x48, 0x81,
-	0x72, 0x96, 0xc0, 0x58, 0x7e, 0x32, 0xce, 0xd1, 0x7f, 0x20, 0xd8, 0x8d, 0xd4, 0xe9, 0x54, 0x95,
-	0x69, 0x97, 0xf7, 0x60, 0xc5, 0x67, 0x0e, 0x95, 0xc5, 0x6d, 0x54, 0x4a, 0x59, 0xda, 0x11, 0x93,
-	0x30, 0x87, 0xd6, 0x14, 0x15, 0x11, 0x89, 0xc6, 0x37, 0x61, 0xd9, 0xe2, 0xbe, 0x2c, 0xa8, 0x50,
-	0x5b, 0x0d, 0x47, 0xe5, 0xe5, 0x7a, 0x93, 0x90, 0x28, 0x86, 0xb7, 0xe1, 0x9a, 0x60, 0x5d, 0xea,
-	0xaa, 0xcb, 0x91, 0x69, 0x24, 0xde, 0xe0, 0x33, 0x28, 0x98, 0x7d, 0xd3, 0x76, 0xcc, 0x96, 0xed,
-	0xd8, 0x62, 0xa0, 0xae, 0xc8, 0x74, 0xb7, 0xe7, 0xa5, 0x6b, 0x7a, 0xd4, 0x32, 0xaa, 0x63, 0x04,
-	0x32, 0x41, 0xd7, 0x3f, 0x22, 0x28, 0x65, 0x77, 0x95, 0xb8, 0x7e, 0x95, 0xcb, 0xc3, 0x4f, 0x61,
-	0x53, 0x82, 0x7a, 0xb4, 0xd7, 0xa2, 0x3e, 0x7f, 0x69, 0x7b, 0xb2, 0xa3, 0x8d, 0xca, 0xc1, 0xc2,
-	0xba, 0xce, 0xfe, 0xc2, 0xc9, 0x46, 0xc4, 0xbf, 0xdc, 0xeb, 0x7b, 0xb0, 0x7b, 0x4a, 0x05, 0x61,
-	0x4c, 0xd4, 0xab, 0xb3, 0x66, 0xeb, 0x0f, 0xa1, 0x94, 0x7d, 0x9c, 0x54, 0xbd, 0x3f, 0x79, 0xdf,
-	0x51, 0xe5, 0x85, 0xc9, 0xeb, 0xdc, 0x81, 0xad, 0x53, 0x2a, 0x9e, 0xb9, 0x0e, 0xb3, 0xba, 0x8f,
-	0xe9, 0x20, 0x15, 0xf6, 0x61, 0x7b, 0x32, 0x9c, 0x08, 0xee, 0x01, 0x04, 0x32, 0x78, 0xde, 0xa5,
-	0x83, 0x44, 0x6f, 0x3d, 0x48, 0x61, 0xf8, 0x01, 0xac, 0xf6, 0xa9, 0xcf, 0x6d, 0xe6, 0x26, 0xb3,
-	0xb5, 0x9b, 0xd5, 0xf8, 0xf3, 0x18, 0x52, 0x5b, 0x19, 0x8e, 0xca, 0x4b, 0x24, 0x65, 0x54, 0xde,
-	0x2b, 0xa0, 0xd4, 0xab, 0xf8, 0x1d, 0x92, 0xb9, 0x67, 0x9a, 0xc2, 0x47, 0x59, 0x5a, 0x0b, 0xdc,
-	0x29, 0x1e, 0x5f, 0x9d, 0x10, 0xb7, 0xa7, 0xaf, 0x7d, 0xfb, 0xfa, 0xfb, 0xb3, 0xa2, 0xdc, 0x40,
-	0xf8, 0x0d, 0x14, 0xc6, 0x0d, 0xc0, 0x07, 0x73, 0xb4, 0xa6, 0x9d, 0x2b, 0x1e, 0xfe, 0x1b, 0x98,
-	0x24, 0xdb, 0x91, 0xc9, 0x36, 0xe1, 0xba, 0x44, 0xde, 0xe9, 0x99, 0xae, 0xd9, 0xa1, 0x7e, 0xe5,
-	0x93, 0x02, 0x72, 0xae, 0x12, 0x2b, 0xb2, 0xa6, 0x32, 0xdb, 0x8a, 0x05, 0x7f, 0x65, 0xb6, 0x15,
-	0x8b, 0x06, 0x7e, 0xcc, 0x8a, 0x0f, 0x08, 0x76, 0x32, 0x9f, 0x24, 0x7c, 0x3c, 0x6f, 0xac, 0xe7,
-	0xbd, 0x81, 0xc5, 0x93, 0xff, 0x60, 0x4c, 0x17, 0x52, 0x53, 0x87, 0x17, 0xda, 0xd2, 0xcf, 0x0b,
-	0x6d, 0xe9, 0x6d, 0xa8, 0xa1, 0x61, 0xa8, 0xa1, 0xef, 0xa1, 0x86, 0x7e, 0x85, 0x1a, 0x6a, 0xe5,
-	0xe4, 0x0b, 0x7c, 0xf7, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x69, 0xad, 0xed, 0x8f, 0xe6, 0x05,
-	0x00, 0x00,
+	// 638 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xc1, 0x6e, 0xd3, 0x4c,
+	0x10, 0xee, 0xba, 0xfd, 0xd3, 0xbf, 0xd3, 0xd0, 0xa2, 0xa5, 0x95, 0x4c, 0x9a, 0x3a, 0x95, 0x39,
+	0xb4, 0x20, 0x61, 0xb7, 0x01, 0x09, 0x09, 0x2e, 0x24, 0x41, 0xaa, 0x2a, 0x54, 0x84, 0xb6, 0x82,
+	0x6b, 0xe5, 0x38, 0xdb, 0x74, 0x15, 0xc7, 0x6b, 0xbc, 0xeb, 0x42, 0x6e, 0x48, 0x20, 0xde, 0x00,
+	0xc1, 0x89, 0x47, 0xe0, 0x39, 0x2a, 0x4e, 0x48, 0x5c, 0x38, 0x55, 0xd4, 0x0f, 0xc0, 0x33, 0x20,
+	0xaf, 0x6d, 0x9a, 0xb4, 0x4e, 0x5a, 0x4e, 0xf1, 0xce, 0x7c, 0xdf, 0x37, 0x33, 0xdf, 0x4e, 0x16,
+	0xd6, 0xbb, 0x4c, 0x1e, 0x46, 0x6d, 0xcb, 0xe5, 0x7d, 0xbb, 0xc3, 0xdd, 0x1e, 0x0d, 0x6d, 0xf1,
+	0xda, 0x09, 0xfb, 0x3d, 0x26, 0x6d, 0x27, 0x60, 0xb6, 0xeb, 0x58, 0x41, 0xc8, 0x25, 0xc7, 0x38,
+	0xcd, 0x5a, 0x79, 0xd6, 0x3a, 0xda, 0xaa, 0xdc, 0xb9, 0x84, 0x2c, 0x07, 0x01, 0x15, 0x29, 0xff,
+	0x52, 0xac, 0x08, 0xa8, 0x9b, 0x63, 0x97, 0xba, 0xbc, 0xcb, 0xd5, 0xa7, 0x9d, 0x7c, 0x65, 0xd1,
+	0x07, 0x13, 0x14, 0x14, 0xa2, 0x1d, 0x1d, 0xd8, 0x81, 0x17, 0x75, 0x99, 0x9f, 0xfd, 0xa4, 0x44,
+	0xb3, 0x05, 0xd5, 0x67, 0xbc, 0x43, 0x5b, 0x34, 0x94, 0xec, 0x80, 0xb9, 0x8e, 0xa4, 0x7b, 0xd2,
+	0x91, 0x91, 0x20, 0xf4, 0x55, 0x44, 0x85, 0xc4, 0xb7, 0x60, 0xd6, 0xe7, 0x1d, 0xba, 0xcf, 0x3a,
+	0x3a, 0x5a, 0x43, 0x1b, 0x73, 0x4d, 0x88, 0x4f, 0x6a, 0xa5, 0x84, 0xb2, 0xf3, 0x84, 0x94, 0x92,
+	0xd4, 0x4e, 0xc7, 0xfc, 0x82, 0x60, 0x75, 0x8c, 0x8a, 0x08, 0xb8, 0x2f, 0x28, 0x7e, 0x08, 0x25,
+	0xa1, 0x22, 0x4a, 0x65, 0xbe, 0x6e, 0x5a, 0x17, 0x2d, 0xb3, 0x76, 0x84, 0x88, 0x1c, 0xdf, 0xcd,
+	0xb9, 0x19, 0x03, 0x37, 0x60, 0xde, 0x3d, 0x13, 0xd6, 0x35, 0x25, 0x50, 0x2b, 0x12, 0x18, 0xaa,
+	0x4f, 0x86, 0x39, 0xe6, 0x0f, 0x04, 0x2b, 0x89, 0x3a, 0x3d, 0xd7, 0x65, 0x3e, 0xe5, 0x7d, 0x98,
+	0x09, 0xb9, 0x47, 0x55, 0x73, 0x0b, 0xf5, 0x6a, 0x91, 0x76, 0xc2, 0x24, 0xdc, 0xa3, 0x4d, 0x4d,
+	0x47, 0x44, 0xa1, 0xf1, 0x4d, 0x98, 0x76, 0x45, 0xa8, 0x1a, 0x2a, 0x37, 0x67, 0xe3, 0x93, 0xda,
+	0x74, 0x6b, 0x8f, 0x90, 0x24, 0x86, 0x97, 0xe0, 0x3f, 0xc9, 0x7b, 0xd4, 0xd7, 0xa7, 0x13, 0xd3,
+	0x48, 0x7a, 0xc0, 0xbb, 0x50, 0x76, 0x8e, 0x1c, 0xe6, 0x39, 0x6d, 0xe6, 0x31, 0x39, 0xd0, 0x67,
+	0x54, 0xb9, 0xdb, 0xe3, 0xca, 0xed, 0x05, 0xd4, 0xb5, 0x1a, 0x43, 0x04, 0x32, 0x42, 0x37, 0x3f,
+	0x22, 0xa8, 0x16, 0x4f, 0x95, 0xb9, 0x7e, 0x95, 0xcb, 0xc3, 0xcf, 0x61, 0x51, 0x81, 0xfa, 0xb4,
+	0xdf, 0xa6, 0xa1, 0x38, 0x64, 0x81, 0x9a, 0x68, 0xa1, 0xbe, 0x3e, 0xb1, 0xaf, 0xdd, 0xbf, 0x70,
+	0xb2, 0x90, 0xf0, 0xcf, 0xce, 0xe6, 0x2a, 0xac, 0x6c, 0x53, 0x49, 0x38, 0x97, 0xad, 0xc6, 0x45,
+	0xb3, 0xcd, 0xc7, 0x50, 0x2d, 0x4e, 0x67, 0x5d, 0xaf, 0x8d, 0xde, 0x77, 0xd2, 0x79, 0x79, 0xf4,
+	0x3a, 0x97, 0xe1, 0xc6, 0x36, 0x95, 0x2f, 0x7c, 0x8f, 0xbb, 0xbd, 0xa7, 0x74, 0x90, 0x0b, 0x87,
+	0xb0, 0x34, 0x1a, 0xce, 0x04, 0x57, 0x01, 0x22, 0x15, 0xdc, 0xef, 0xd1, 0x41, 0xa6, 0x37, 0x17,
+	0xe5, 0x30, 0xfc, 0x08, 0x66, 0x8f, 0x68, 0x28, 0x18, 0xf7, 0xb3, 0xdd, 0x5a, 0x29, 0x1a, 0xfc,
+	0x65, 0x0a, 0x69, 0xce, 0x1c, 0x9f, 0xd4, 0xa6, 0x48, 0xce, 0xa8, 0xbf, 0xd7, 0x40, 0x6b, 0x35,
+	0xf0, 0x3b, 0xa4, 0x6a, 0x5f, 0x18, 0x0a, 0xdb, 0x45, 0x5a, 0x13, 0xdc, 0xa9, 0x6c, 0x5e, 0x9d,
+	0x90, 0x8e, 0x67, 0xfe, 0xff, 0xed, 0xeb, 0xef, 0xcf, 0x9a, 0x76, 0x1d, 0xe1, 0x37, 0x50, 0x1e,
+	0x36, 0x00, 0xaf, 0x8f, 0xd1, 0x3a, 0xef, 0x5c, 0x65, 0xe3, 0x72, 0x60, 0x56, 0x6c, 0x59, 0x15,
+	0x5b, 0x84, 0x6b, 0x0a, 0x79, 0xb7, 0xef, 0xf8, 0x4e, 0x97, 0x86, 0xf5, 0x4f, 0x1a, 0xa8, 0xbd,
+	0xca, 0xac, 0x28, 0xda, 0xca, 0x62, 0x2b, 0x26, 0xfc, 0x2b, 0x8b, 0xad, 0x98, 0xb4, 0xf0, 0x43,
+	0x56, 0x7c, 0x40, 0xb0, 0x5c, 0xf8, 0x24, 0xe1, 0xcd, 0x71, 0x6b, 0x3d, 0xee, 0x0d, 0xac, 0x6c,
+	0xfd, 0x03, 0xe3, 0x7c, 0x23, 0x4d, 0xfd, 0xf8, 0xd4, 0x98, 0xfa, 0x79, 0x6a, 0x4c, 0xbd, 0x8d,
+	0x0d, 0x74, 0x1c, 0x1b, 0xe8, 0x7b, 0x6c, 0xa0, 0x5f, 0xb1, 0x81, 0xda, 0x25, 0xf5, 0x02, 0xdf,
+	0xfb, 0x13, 0x00, 0x00, 0xff, 0xff, 0xe1, 0xda, 0xca, 0xba, 0x67, 0x06, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/ca.proto b/vendor/github.com/docker/swarmkit/api/ca.proto
index 84ec7d3..e26c8f3 100644
--- a/vendor/github.com/docker/swarmkit/api/ca.proto
+++ b/vendor/github.com/docker/swarmkit/api/ca.proto
@@ -2,10 +2,10 @@
 
 package docker.swarmkit.v1;
 
-import "types.proto";
-import "specs.proto";
+import "github.com/docker/swarmkit/api/types.proto";
+import "github.com/docker/swarmkit/api/specs.proto";
 import "gogoproto/gogo.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 // CA defines the RPC methods for requesting certificates from a CA.
 
diff --git a/vendor/github.com/docker/swarmkit/api/control.pb.go b/vendor/github.com/docker/swarmkit/api/control.pb.go
index 096228e..13ef482 100644
--- a/vendor/github.com/docker/swarmkit/api/control.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/control.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: control.proto
+// source: github.com/docker/swarmkit/api/control.proto
 // DO NOT EDIT!
 
 package api
@@ -3468,7 +3468,7 @@
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "control.proto",
+	Metadata: "github.com/docker/swarmkit/api/control.proto",
 }
 
 func (m *GetNodeRequest) Marshal() (dAtA []byte, err error) {
@@ -15953,140 +15953,142 @@
 	ErrIntOverflowControl   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("control.proto", fileDescriptorControl) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/control.proto", fileDescriptorControl) }
 
 var fileDescriptorControl = []byte{
-	// 2106 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0x1b, 0x49,
-	0x15, 0xb7, 0x3e, 0x6c, 0xc9, 0x4f, 0xb6, 0x6c, 0xb7, 0x1d, 0x50, 0x29, 0xc1, 0x4e, 0x4d, 0x48,
-	0xa2, 0x50, 0x41, 0x66, 0x15, 0x16, 0xc2, 0x52, 0x7c, 0xac, 0xed, 0x6c, 0x56, 0xeb, 0x8d, 0x93,
-	0x1a, 0xc7, 0x5b, 0xdc, 0x54, 0xb2, 0xd4, 0x36, 0x13, 0xc9, 0x1a, 0x31, 0x33, 0xf2, 0xae, 0x8b,
-	0x0b, 0x50, 0xcb, 0x81, 0x3f, 0x80, 0x2a, 0xae, 0x5c, 0x39, 0x70, 0xe0, 0xc4, 0x81, 0x3f, 0x20,
-	0xc5, 0x89, 0x23, 0x27, 0xc3, 0xaa, 0x0a, 0x8a, 0x13, 0x7f, 0xc3, 0x56, 0x77, 0xbf, 0x9e, 0x2f,
-	0xf5, 0xcc, 0xe8, 0xab, 0xca, 0x7b, 0xb2, 0xa6, 0xe7, 0xf7, 0xfa, 0xbd, 0xee, 0xf7, 0xeb, 0xdf,
-	0x74, 0xbf, 0x36, 0xac, 0xb6, 0xcc, 0x9e, 0x63, 0x99, 0xdd, 0x6a, 0xdf, 0x32, 0x1d, 0x93, 0x90,
-	0xb6, 0xd9, 0xea, 0x50, 0xab, 0x6a, 0x7f, 0xda, 0xb4, 0x2e, 0x3a, 0x86, 0x53, 0xbd, 0x7c, 0xa7,
-	0x5c, 0xb0, 0xfb, 0xb4, 0x65, 0x0b, 0x40, 0x79, 0xd5, 0x3c, 0x7d, 0x43, 0x5b, 0x8e, 0x7c, 0x2c,
-	0x38, 0x57, 0x7d, 0x2a, 0x1f, 0xb6, 0xce, 0xcd, 0x73, 0x93, 0xff, 0xdc, 0x65, 0xbf, 0xb0, 0x75,
-	0xb3, 0xdf, 0x1d, 0x9c, 0x1b, 0xbd, 0x5d, 0xf1, 0x47, 0x34, 0x6a, 0xef, 0x42, 0xf1, 0x39, 0x75,
-	0x8e, 0xcc, 0x36, 0xd5, 0xe9, 0x2f, 0x06, 0xd4, 0x76, 0xc8, 0x3d, 0xc8, 0xf5, 0xcc, 0x36, 0x6d,
-	0x18, 0xed, 0x52, 0xea, 0x6e, 0xaa, 0xb2, 0xbc, 0x07, 0xc3, 0xeb, 0x9d, 0x25, 0x86, 0xa8, 0x1f,
-	0xe8, 0x4b, 0xec, 0x55, 0xbd, 0xad, 0xfd, 0x04, 0xd6, 0x5c, 0x33, 0xbb, 0x6f, 0xf6, 0x6c, 0x4a,
-	0x1e, 0x43, 0x96, 0xbd, 0xe4, 0x46, 0x85, 0x5a, 0xa9, 0x3a, 0x3a, 0x80, 0x2a, 0xc7, 0x73, 0x94,
-	0xf6, 0xdf, 0x0c, 0xac, 0x7f, 0x6c, 0xd8, 0xbc, 0x0b, 0x5b, 0xba, 0xfe, 0x00, 0x72, 0x67, 0x46,
-	0xd7, 0xa1, 0x96, 0x8d, 0xbd, 0x3c, 0x56, 0xf5, 0x12, 0x36, 0xab, 0x7e, 0x20, 0x6c, 0x74, 0x69,
-	0x5c, 0xfe, 0x5d, 0x06, 0x72, 0xd8, 0x48, 0xb6, 0x60, 0xb1, 0xd7, 0xbc, 0xa0, 0xac, 0xc7, 0x4c,
-	0x65, 0x59, 0x17, 0x0f, 0x64, 0x17, 0x0a, 0x46, 0xbb, 0xd1, 0xb7, 0xe8, 0x99, 0xf1, 0x19, 0xb5,
-	0x4b, 0x69, 0xf6, 0x6e, 0xaf, 0x38, 0xbc, 0xde, 0x81, 0xfa, 0xc1, 0x2b, 0x6c, 0xd5, 0xc1, 0x68,
-	0xcb, 0xdf, 0xe4, 0x15, 0x2c, 0x75, 0x9b, 0xa7, 0xb4, 0x6b, 0x97, 0x32, 0x77, 0x33, 0x95, 0x42,
-	0xed, 0xe9, 0x24, 0x91, 0x55, 0x3f, 0xe6, 0xa6, 0xcf, 0x7a, 0x8e, 0x75, 0xa5, 0x63, 0x3f, 0xe4,
-	0x05, 0x14, 0x2e, 0xe8, 0xc5, 0x29, 0xb5, 0xec, 0x9f, 0x1b, 0x7d, 0xbb, 0x94, 0xbd, 0x9b, 0xa9,
-	0x14, 0x6b, 0x0f, 0xa3, 0xa6, 0xed, 0xb8, 0x4f, 0x5b, 0xd5, 0x17, 0x2e, 0x7e, 0x2f, 0xbd, 0xbe,
-	0xa0, 0xfb, 0xed, 0xc9, 0xf7, 0x60, 0xd1, 0x32, 0xbb, 0xd4, 0x2e, 0x2d, 0xf2, 0x8e, 0xee, 0x44,
-	0xce, 0xbf, 0xd9, 0xa5, 0xdc, 0x5a, 0xc0, 0xc9, 0x3d, 0x58, 0x65, 0x53, 0xe2, 0xcd, 0xc5, 0x12,
-	0x9f, 0xa7, 0x15, 0xd6, 0x28, 0x47, 0x5f, 0xfe, 0x01, 0x14, 0x7c, 0x43, 0x20, 0xeb, 0x90, 0xe9,
-	0xd0, 0x2b, 0x41, 0x0f, 0x9d, 0xfd, 0x64, 0xb3, 0x7c, 0xd9, 0xec, 0x0e, 0x68, 0x29, 0xcd, 0xdb,
-	0xc4, 0xc3, 0x7b, 0xe9, 0xa7, 0x29, 0x6d, 0x1f, 0x36, 0x7c, 0xd3, 0x82, 0x5c, 0xa9, 0xc2, 0x22,
-	0x63, 0x81, 0x48, 0x4a, 0x1c, 0x59, 0x04, 0x4c, 0xfb, 0x53, 0x0a, 0x36, 0x4e, 0xfa, 0xed, 0xa6,
-	0x43, 0x27, 0x65, 0x2a, 0xf9, 0x31, 0xac, 0x70, 0xd0, 0x25, 0xb5, 0x6c, 0xc3, 0xec, 0xf1, 0x00,
-	0x0b, 0xb5, 0xdb, 0x2a, 0x8f, 0x9f, 0x08, 0x88, 0x5e, 0x60, 0x06, 0xf8, 0x40, 0xbe, 0x03, 0x59,
-	0xb6, 0xec, 0x4a, 0x19, 0x6e, 0x77, 0x27, 0x2e, 0x3f, 0x3a, 0x47, 0x6a, 0x7b, 0x40, 0xfc, 0xb1,
-	0x4e, 0xb5, 0x3c, 0x8e, 0x60, 0x43, 0xa7, 0x17, 0xe6, 0xe5, 0xe4, 0xe3, 0xdd, 0x82, 0xc5, 0x33,
-	0xd3, 0x6a, 0x89, 0x4c, 0xe4, 0x75, 0xf1, 0xa0, 0x6d, 0x01, 0xf1, 0xf7, 0x27, 0x62, 0xc2, 0xc5,
-	0xff, 0xba, 0x69, 0x77, 0x7c, 0x2e, 0x9c, 0xa6, 0xdd, 0x09, 0xb9, 0x60, 0x08, 0xe6, 0x82, 0xbd,
-	0x72, 0x17, 0xbf, 0x30, 0xf3, 0x46, 0xc7, 0x5e, 0xc6, 0x8d, 0x8e, 0xe3, 0x39, 0x4a, 0x7b, 0x2a,
-	0x47, 0x37, 0xb1, 0x6b, 0x77, 0x1c, 0x7e, 0xef, 0xda, 0xdf, 0xb2, 0x42, 0x4c, 0x58, 0xe3, 0x14,
-	0x62, 0xe2, 0x37, 0x1b, 0x15, 0x93, 0x7f, 0xdd, 0xa0, 0x98, 0xa8, 0x22, 0x53, 0x8a, 0xc9, 0x2e,
-	0x14, 0x6c, 0x6a, 0x5d, 0x1a, 0x2d, 0xc6, 0x0e, 0x21, 0x26, 0x18, 0xc2, 0xb1, 0x68, 0xae, 0x1f,
-	0xd8, 0x3a, 0x20, 0xa4, 0xde, 0xb6, 0xc9, 0x03, 0xc8, 0x23, 0x97, 0x84, 0x62, 0x2c, 0xef, 0x15,
-	0x86, 0xd7, 0x3b, 0x39, 0x41, 0x26, 0x5b, 0xcf, 0x09, 0x36, 0xd9, 0xe4, 0x43, 0x28, 0xb6, 0xa9,
-	0x6d, 0x58, 0xb4, 0xdd, 0xb0, 0x9d, 0xa6, 0x83, 0xfa, 0x50, 0xac, 0x7d, 0x23, 0x2a, 0xc5, 0xc7,
-	0x0c, 0xc5, 0x05, 0x66, 0x15, 0x0d, 0x79, 0x8b, 0x42, 0x68, 0x72, 0xa3, 0x42, 0x43, 0xee, 0x00,
-	0x0c, 0xfa, 0x0d, 0xc7, 0x6c, 0xb0, 0xf5, 0x53, 0xca, 0x73, 0x0a, 0xe7, 0x07, 0xfd, 0xd7, 0xe6,
-	0x41, 0xd3, 0xa1, 0xa4, 0x0c, 0x79, 0x6b, 0xd0, 0x73, 0x0c, 0x96, 0x81, 0x65, 0x6e, 0xed, 0x3e,
-	0xcf, 0x41, 0xa2, 0x70, 0xb2, 0x3d, 0x89, 0x62, 0x9c, 0x8b, 0x95, 0x28, 0x4e, 0x42, 0x01, 0xd3,
-	0x0e, 0x61, 0x6b, 0xdf, 0xa2, 0x4d, 0x87, 0xe2, 0x84, 0x4b, 0x1a, 0x3e, 0x41, 0xfd, 0x10, 0x1c,
-	0xdc, 0x51, 0x75, 0x83, 0x16, 0x3e, 0x09, 0x39, 0x82, 0x5b, 0xa1, 0xce, 0x30, 0xaa, 0x77, 0x21,
-	0x87, 0x49, 0xc4, 0x0e, 0x6f, 0xc7, 0x74, 0xa8, 0x4b, 0xac, 0xf6, 0x06, 0x36, 0x9e, 0x53, 0x27,
-	0x14, 0xd9, 0x63, 0x00, 0x8f, 0x33, 0xb8, 0xe6, 0x56, 0x87, 0xd7, 0x3b, 0xcb, 0x2e, 0x65, 0xf4,
-	0x65, 0x97, 0x31, 0xe4, 0x21, 0xac, 0x19, 0x3d, 0x9b, 0x5a, 0x4e, 0xa3, 0x4d, 0xcf, 0x9a, 0x83,
-	0xae, 0x63, 0xa3, 0xc2, 0x14, 0x45, 0xf3, 0x01, 0xb6, 0x6a, 0x87, 0x40, 0xfc, 0xbe, 0x66, 0x0b,
-	0xfc, 0x2f, 0x69, 0xd8, 0x12, 0x62, 0x3a, 0x53, 0xf0, 0x07, 0xb0, 0x26, 0xd1, 0x13, 0x7c, 0x07,
-	0x8a, 0x68, 0x23, 0x3f, 0x05, 0x4f, 0x02, 0x9f, 0x82, 0xf1, 0x52, 0x49, 0x5e, 0x40, 0xde, 0x32,
-	0xbb, 0xdd, 0xd3, 0x66, 0xab, 0x53, 0xca, 0xde, 0x4d, 0x55, 0x8a, 0xb5, 0x77, 0x54, 0x86, 0xaa,
-	0x41, 0x56, 0x75, 0x34, 0xd4, 0xdd, 0x2e, 0x34, 0x0d, 0xf2, 0xb2, 0x95, 0xe4, 0x21, 0x7b, 0xf4,
-	0xf2, 0xe8, 0xd9, 0xfa, 0x02, 0x59, 0x81, 0xfc, 0x2b, 0xfd, 0xd9, 0x27, 0xf5, 0x97, 0x27, 0xc7,
-	0xeb, 0x29, 0xc6, 0x9e, 0x50, 0x77, 0xb3, 0x25, 0xe1, 0x00, 0xb6, 0x84, 0xe8, 0xce, 0x92, 0x03,
-	0xed, 0xeb, 0x70, 0x2b, 0xd4, 0x0b, 0xaa, 0xf7, 0xe7, 0x19, 0xd8, 0x64, 0xeb, 0x0f, 0xdb, 0x5d,
-	0x01, 0xaf, 0x87, 0x05, 0x7c, 0x37, 0x4a, 0x26, 0x43, 0x96, 0xa3, 0x1a, 0xfe, 0xc7, 0xf4, 0xdc,
-	0x35, 0xfc, 0x38, 0xa4, 0xe1, 0x3f, 0x9c, 0x30, 0x38, 0xa5, 0x8c, 0x8f, 0x68, 0x64, 0x56, 0xa1,
-	0x91, 0x7e, 0x15, 0x5c, 0x9c, 0x9f, 0x0a, 0xbe, 0x84, 0xad, 0x60, 0xb8, 0x48, 0x9a, 0xef, 0x43,
-	0x1e, 0x93, 0x28, 0xb5, 0x30, 0x96, 0x35, 0x2e, 0xd8, 0x53, 0xc4, 0x23, 0xea, 0x7c, 0x6a, 0x5a,
-	0x9d, 0x09, 0x14, 0x11, 0x2d, 0x54, 0x8a, 0xe8, 0x76, 0xe6, 0x71, 0xba, 0x27, 0x9a, 0xe2, 0x38,
-	0x2d, 0xad, 0x24, 0x56, 0x3b, 0xe1, 0x8a, 0x18, 0x8a, 0x8c, 0x40, 0x96, 0xcd, 0x34, 0xce, 0x17,
-	0xff, 0xcd, 0x48, 0x8e, 0x36, 0x8c, 0xe4, 0x69, 0x8f, 0xe4, 0x68, 0xcb, 0x48, 0x8e, 0x80, 0x7a,
-	0x1b, 0xc5, 0x6f, 0x4e, 0x31, 0xfe, 0x4c, 0xae, 0xbb, 0xb9, 0x87, 0xe9, 0xae, 0xc5, 0x50, 0xa4,
-	0xda, 0xff, 0xd2, 0x62, 0x2d, 0x62, 0xfb, 0x14, 0x6b, 0x31, 0x64, 0x39, 0xba, 0x16, 0x7f, 0x7b,
-	0x83, 0x6b, 0x31, 0x22, 0xb8, 0xa9, 0xd7, 0xe2, 0x1c, 0xd6, 0x9b, 0x17, 0x92, 0xb7, 0xde, 0x30,
-	0x51, 0xb1, 0xeb, 0x4d, 0x66, 0xce, 0x05, 0x6b, 0xef, 0x73, 0x4a, 0xef, 0x77, 0x07, 0xb6, 0x43,
-	0x2d, 0x9f, 0x46, 0xb7, 0x44, 0x4b, 0x48, 0xa3, 0x11, 0xc7, 0x78, 0x81, 0x00, 0x97, 0xbe, 0x6e,
-	0x17, 0x1e, 0x7d, 0x11, 0x12, 0x47, 0x5f, 0x69, 0x25, 0xb1, 0x2e, 0x97, 0xf0, 0xc5, 0x14, 0x5c,
-	0x0a, 0x59, 0x7e, 0xb5, 0xb8, 0x14, 0x11, 0xdc, 0x4d, 0x72, 0xc9, 0x0b, 0xc9, 0xe3, 0x12, 0x66,
-	0x23, 0x96, 0x4b, 0x32, 0x75, 0x2e, 0x58, 0xfb, 0x7d, 0x0a, 0x0a, 0x87, 0xf4, 0x4a, 0x37, 0x9d,
-	0xa6, 0xc3, 0xb6, 0x3e, 0xdf, 0x82, 0x0d, 0x46, 0x32, 0x6a, 0x35, 0xde, 0x98, 0x46, 0xaf, 0xe1,
-	0x98, 0x1d, 0xda, 0xe3, 0xa1, 0xe5, 0xf5, 0x35, 0xf1, 0xe2, 0x23, 0xd3, 0xe8, 0xbd, 0x66, 0xcd,
-	0xe4, 0x31, 0x90, 0x8b, 0x66, 0xaf, 0x79, 0x1e, 0x04, 0x8b, 0xcd, 0xe2, 0x3a, 0xbe, 0x51, 0xa2,
-	0x07, 0xbd, 0xae, 0xd9, 0xea, 0x34, 0xd8, 0xa8, 0x33, 0x01, 0xf4, 0x09, 0x7f, 0x71, 0x48, 0xaf,
-	0xb4, 0xdf, 0xb8, 0xfb, 0xc1, 0x59, 0x78, 0xce, 0xf6, 0x83, 0x12, 0x3d, 0xc9, 0x7e, 0x10, 0x6d,
-	0x26, 0xd8, 0x0f, 0xa2, 0x77, 0xdf, 0x7e, 0xf0, 0x7d, 0xb6, 0x1f, 0x14, 0xb3, 0xca, 0xf7, 0x83,
-	0x11, 0x86, 0xbe, 0xc9, 0xdf, 0xcb, 0xbe, 0xbd, 0xde, 0x59, 0xd0, 0x5d, 0x33, 0x6f, 0x7f, 0x37,
-	0xa7, 0x85, 0xfa, 0x23, 0x58, 0xe7, 0x3b, 0xf6, 0x96, 0x45, 0x1d, 0x39, 0x9f, 0x8f, 0x60, 0xd9,
-	0xe6, 0x0d, 0xde, 0x74, 0xae, 0x0c, 0xaf, 0x77, 0xf2, 0x02, 0x55, 0x3f, 0x60, 0xdf, 0x79, 0xfe,
-	0xab, 0xad, 0x3d, 0xc7, 0xc3, 0x85, 0x30, 0xc7, 0x50, 0x6a, 0xb0, 0x24, 0x00, 0x18, 0x49, 0x59,
-	0xbd, 0x67, 0xe0, 0x36, 0x88, 0xd4, 0xfe, 0x9a, 0x82, 0x4d, 0xb9, 0x71, 0x9d, 0x2e, 0x16, 0xb2,
-	0x07, 0x45, 0x84, 0x4e, 0x90, 0xd7, 0x55, 0x61, 0x22, 0xd3, 0x5a, 0x0b, 0xa4, 0x75, 0x3b, 0x3a,
-	0x70, 0xdf, 0xf6, 0xe4, 0x23, 0xef, 0x98, 0x32, 0xf3, 0x34, 0xfc, 0x27, 0x0d, 0x44, 0xec, 0xc4,
-	0xd8, 0xa3, 0x2b, 0x9b, 0x1f, 0x86, 0x65, 0xb3, 0x1a, 0xbd, 0xe3, 0xf4, 0x1b, 0x8e, 0xaa, 0xe6,
-	0xe7, 0xf3, 0x57, 0x4d, 0x3d, 0xa4, 0x9a, 0xef, 0x4d, 0x16, 0xdb, 0x8d, 0x88, 0xe6, 0xa1, 0x3c,
-	0x76, 0x60, 0x44, 0x98, 0xb2, 0xef, 0xb2, 0x43, 0x12, 0x6f, 0x42, 0xc9, 0x8c, 0xcb, 0x99, 0x84,
-	0x6a, 0x75, 0xd8, 0x94, 0x27, 0x76, 0x3f, 0x75, 0x6b, 0x81, 0xbd, 0xee, 0xd8, 0x5c, 0x0a, 0x76,
-	0x35, 0x03, 0x97, 0x7e, 0x0a, 0x9b, 0xf2, 0xd0, 0x35, 0xe5, 0xea, 0xfe, 0x9a, 0x77, 0xf8, 0xf3,
-	0x47, 0x83, 0xa2, 0xb1, 0x6f, 0xf6, 0xce, 0x8c, 0x73, 0x5f, 0xb7, 0x2d, 0xde, 0x10, 0xea, 0x56,
-	0xa0, 0x58, 0xb7, 0xe2, 0xb5, 0x2b, 0x1a, 0xd2, 0xdc, 0x1b, 0xa1, 0x00, 0xc4, 0x8d, 0x10, 0x6d,
-	0x10, 0xe9, 0x13, 0x8d, 0x69, 0x63, 0x61, 0xa2, 0x81, 0xd0, 0x49, 0x44, 0x43, 0x98, 0x4c, 0x20,
-	0x1a, 0xc2, 0xb3, 0x4a, 0x34, 0xe6, 0x30, 0x0d, 0x52, 0x34, 0x44, 0xf3, 0x14, 0xa2, 0x11, 0x34,
-	0xfc, 0x6a, 0x89, 0x86, 0x3a, 0xb6, 0x9b, 0x14, 0x0d, 0x37, 0x22, 0x4f, 0x34, 0x44, 0x22, 0x62,
-	0x45, 0x03, 0x73, 0x26, 0xa1, 0x9e, 0x68, 0x04, 0xa9, 0x3b, 0x86, 0x68, 0xa8, 0xb8, 0x14, 0xec,
-	0x6a, 0x06, 0x2e, 0xb9, 0xa2, 0x31, 0xf5, 0xea, 0x76, 0x45, 0x23, 0x18, 0x4d, 0xed, 0xd7, 0xb7,
-	0x21, 0xb7, 0x2f, 0xee, 0x39, 0x89, 0x01, 0x39, 0xbc, 0x42, 0x24, 0x9a, 0x2a, 0xa8, 0xe0, 0xb5,
-	0x64, 0xf9, 0x5e, 0x2c, 0x06, 0x45, 0xe9, 0xd6, 0xdf, 0xff, 0xfc, 0xff, 0x3f, 0xa4, 0xd7, 0x60,
-	0x95, 0x83, 0xbe, 0x8d, 0xdb, 0x47, 0x62, 0xc2, 0xb2, 0x7b, 0x07, 0x45, 0xbe, 0x39, 0xce, 0xcd,
-	0x5d, 0xf9, 0x7e, 0x02, 0x2a, 0xde, 0xa1, 0x05, 0xe0, 0x5d, 0x01, 0x91, 0xfb, 0xd1, 0x05, 0x3f,
-	0xff, 0x08, 0x1f, 0x24, 0xc1, 0x12, 0x7d, 0x7a, 0x57, 0x3c, 0x6a, 0x9f, 0x23, 0x57, 0x4a, 0x6a,
-	0x9f, 0x8a, 0x9b, 0xa2, 0x08, 0x9f, 0x22, 0x87, 0xaf, 0x9b, 0x76, 0x27, 0x32, 0x87, 0xbe, 0x2b,
-	0x9e, 0xc8, 0x1c, 0x06, 0x2e, 0x73, 0xe2, 0x73, 0xc8, 0x8b, 0xf4, 0xd1, 0x39, 0xf4, 0x5f, 0x98,
-	0x44, 0xe7, 0x30, 0x50, 0xe9, 0x4f, 0x9c, 0x4f, 0x3e, 0xbc, 0x98, 0xf9, 0xf4, 0x8f, 0xf0, 0x41,
-	0x12, 0x2c, 0xd1, 0xa7, 0x57, 0x3b, 0x57, 0xfb, 0x1c, 0xa9, 0xe3, 0xab, 0x7d, 0x8e, 0x96, 0xe0,
-	0xa3, 0x7c, 0x7e, 0x06, 0x2b, 0xfe, 0xba, 0x1f, 0x79, 0x38, 0x66, 0x21, 0xb3, 0x5c, 0x49, 0x06,
-	0xc6, 0x7b, 0xfe, 0x25, 0xac, 0x06, 0x6e, 0x39, 0x88, 0xb2, 0x47, 0xd5, 0xad, 0x4a, 0xf9, 0xd1,
-	0x18, 0xc8, 0x44, 0xe7, 0x81, 0x22, 0xb9, 0xda, 0xb9, 0xaa, 0x2c, 0xaf, 0x76, 0xae, 0xac, 0xb8,
-	0xc7, 0x38, 0x0f, 0xd4, 0xc2, 0xd5, 0xce, 0x55, 0x45, 0x77, 0xb5, 0x73, 0x75, 0x61, 0x3d, 0x96,
-	0x64, 0x58, 0x3f, 0x8a, 0x24, 0x59, 0xb0, 0xe6, 0x18, 0x49, 0xb2, 0x70, 0x01, 0x31, 0x9e, 0x64,
-	0xb2, 0xd8, 0x15, 0x4d, 0xb2, 0x50, 0x85, 0x2e, 0x9a, 0x64, 0xe1, 0xba, 0x59, 0x22, 0xc9, 0xe4,
-	0x80, 0x63, 0x48, 0x16, 0x1a, 0xf3, 0xa3, 0x31, 0x90, 0x63, 0xe6, 0x39, 0xd6, 0xb9, 0xaa, 0xc8,
-	0x1b, 0x97, 0xe7, 0x31, 0x9d, 0x8b, 0x3c, 0xe3, 0x69, 0x3f, 0x32, 0xcf, 0xc1, 0x3a, 0x4a, 0x64,
-	0x9e, 0x43, 0xa5, 0x86, 0x84, 0x3c, 0xcb, 0x42, 0x54, 0x74, 0x9e, 0x43, 0xd5, 0xb3, 0xe8, 0x3c,
-	0x87, 0x6b, 0x5a, 0x89, 0xeb, 0x59, 0x0e, 0x38, 0x66, 0x3d, 0x87, 0xc6, 0xfc, 0x68, 0x0c, 0x64,
-	0xe2, 0xc7, 0xc9, 0x2d, 0x81, 0xa8, 0x3f, 0x4e, 0xe1, 0x02, 0x4b, 0xf9, 0x7e, 0x02, 0x2a, 0x71,
-	0x9e, 0xfd, 0xf5, 0x06, 0xf5, 0x3c, 0x2b, 0x6a, 0x29, 0xe5, 0x4a, 0x32, 0x30, 0xde, 0xf3, 0x00,
-	0x0a, 0xbe, 0x53, 0x33, 0x79, 0x30, 0xde, 0x41, 0xbf, 0xfc, 0x30, 0x11, 0x97, 0x38, 0x60, 0xff,
-	0xa1, 0x58, 0x3d, 0x60, 0xc5, 0x09, 0xbc, 0x5c, 0x49, 0x06, 0x26, 0x7a, 0xf6, 0x1f, 0x80, 0xd5,
-	0x9e, 0x15, 0x87, 0xec, 0x72, 0x25, 0x19, 0x38, 0x0e, 0xab, 0xc4, 0x16, 0x3a, 0x92, 0x55, 0x81,
-	0x3d, 0x7a, 0x24, 0xab, 0x82, 0xfb, 0xf0, 0x44, 0x56, 0xa1, 0xcf, 0x18, 0x56, 0x05, 0xdd, 0x56,
-	0x92, 0x81, 0x63, 0xb1, 0x0a, 0x8f, 0x55, 0xd1, 0xac, 0x0a, 0x9e, 0x04, 0xa3, 0x59, 0x15, 0x3a,
-	0x9f, 0x25, 0xb2, 0x2a, 0x6e, 0xc0, 0x8a, 0x23, 0x5a, 0x1c, 0xab, 0xc6, 0x9e, 0x6a, 0xff, 0x09,
-	0x29, 0x8e, 0x55, 0x63, 0x78, 0x56, 0x1d, 0xb6, 0x22, 0x3c, 0xef, 0x95, 0xde, 0x7e, 0xb1, 0xbd,
-	0xf0, 0xcf, 0x2f, 0xb6, 0x17, 0x7e, 0x35, 0xdc, 0x4e, 0xbd, 0x1d, 0x6e, 0xa7, 0xfe, 0x31, 0xdc,
-	0x4e, 0xfd, 0x7b, 0xb8, 0x9d, 0x3a, 0x5d, 0xe2, 0xff, 0x12, 0xfa, 0xe4, 0xcb, 0x00, 0x00, 0x00,
-	0xff, 0xff, 0x69, 0xfa, 0x48, 0xde, 0x8b, 0x2a, 0x00, 0x00,
+	// 2137 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4f, 0x73, 0x1b, 0x49,
+	0x15, 0xb7, 0xfe, 0xd8, 0x92, 0x9f, 0x6c, 0xd9, 0xee, 0x38, 0xa0, 0x52, 0x82, 0x9d, 0x9a, 0x90,
+	0x44, 0xd9, 0x32, 0x12, 0xab, 0xb0, 0x6c, 0x58, 0x8a, 0x3f, 0x6b, 0x3b, 0x9b, 0xd5, 0x7a, 0xe3,
+	0xa4, 0xc6, 0xc9, 0x16, 0x37, 0x95, 0x2c, 0xb5, 0xbd, 0x13, 0xc9, 0x1a, 0x31, 0x33, 0xf2, 0xae,
+	0x8b, 0x0b, 0x50, 0xcb, 0x81, 0x0f, 0x40, 0x15, 0x57, 0xae, 0x1c, 0x38, 0x70, 0xe2, 0xc0, 0x07,
+	0x48, 0x71, 0xe2, 0xc8, 0xc9, 0xb0, 0xaa, 0x82, 0xe2, 0xc4, 0x67, 0xa0, 0xba, 0xfb, 0xf5, 0xfc,
+	0x53, 0xcf, 0x8c, 0x24, 0xab, 0xca, 0x39, 0x59, 0xd3, 0xf3, 0x7b, 0xfd, 0x5e, 0xf7, 0xfb, 0xf5,
+	0x6f, 0xba, 0x5f, 0x1b, 0x76, 0x4e, 0x0d, 0xe7, 0xf3, 0xe1, 0x71, 0xb5, 0x6d, 0x9e, 0xd5, 0x3a,
+	0x66, 0xbb, 0x4b, 0xad, 0x9a, 0xfd, 0x45, 0xcb, 0x3a, 0xeb, 0x1a, 0x4e, 0xad, 0x35, 0x30, 0x6a,
+	0x6d, 0xb3, 0xef, 0x58, 0x66, 0xaf, 0x3a, 0xb0, 0x4c, 0xc7, 0x24, 0x44, 0x40, 0xaa, 0x12, 0x52,
+	0x3d, 0x7f, 0xb7, 0xfc, 0x4e, 0x42, 0x0f, 0xf6, 0x80, 0xb6, 0x6d, 0x61, 0x5f, 0x4e, 0xf2, 0x66,
+	0x1e, 0xbf, 0xa6, 0x6d, 0x47, 0xa2, 0x93, 0x7a, 0x76, 0x2e, 0x06, 0x54, 0x62, 0x37, 0x4f, 0xcd,
+	0x53, 0x93, 0xff, 0xac, 0xb1, 0x5f, 0xd8, 0xfa, 0x7e, 0x4c, 0x0f, 0x1c, 0x71, 0x3c, 0x3c, 0xa9,
+	0x0d, 0x7a, 0xc3, 0x53, 0xa3, 0x8f, 0x7f, 0x84, 0xa1, 0xf6, 0x1e, 0x14, 0x9f, 0x52, 0xe7, 0xd0,
+	0xec, 0x50, 0x9d, 0xfe, 0x7c, 0x48, 0x6d, 0x87, 0xdc, 0x85, 0x5c, 0xdf, 0xec, 0xd0, 0xa6, 0xd1,
+	0x29, 0xa5, 0xee, 0xa4, 0x2a, 0xcb, 0xbb, 0x30, 0xba, 0xdc, 0x5e, 0x62, 0x88, 0xc6, 0xbe, 0xbe,
+	0xc4, 0x5e, 0x35, 0x3a, 0xda, 0x4f, 0x60, 0xcd, 0x35, 0xb3, 0x07, 0x66, 0xdf, 0xa6, 0x64, 0x07,
+	0xb2, 0xec, 0x25, 0x37, 0x2a, 0xd4, 0x4b, 0xd5, 0xf1, 0x19, 0xac, 0x72, 0x3c, 0x47, 0x69, 0xff,
+	0xc9, 0xc0, 0xfa, 0xa7, 0x86, 0xcd, 0xbb, 0xb0, 0xa5, 0xeb, 0x8f, 0x20, 0x77, 0x62, 0xf4, 0x1c,
+	0x6a, 0xd9, 0xd8, 0xcb, 0x8e, 0xaa, 0x97, 0xb0, 0x59, 0xf5, 0x23, 0x61, 0xa3, 0x4b, 0xe3, 0xf2,
+	0x6f, 0x33, 0x90, 0xc3, 0x46, 0xb2, 0x09, 0x8b, 0xfd, 0xd6, 0x19, 0x65, 0x3d, 0x66, 0x2a, 0xcb,
+	0xba, 0x78, 0x20, 0x35, 0x28, 0x18, 0x9d, 0xe6, 0xc0, 0xa2, 0x27, 0xc6, 0x97, 0xd4, 0x2e, 0xa5,
+	0xd9, 0xbb, 0xdd, 0xe2, 0xe8, 0x72, 0x1b, 0x1a, 0xfb, 0x2f, 0xb0, 0x55, 0x07, 0xa3, 0x23, 0x7f,
+	0x93, 0x17, 0xb0, 0xd4, 0x6b, 0x1d, 0xd3, 0x9e, 0x5d, 0xca, 0xdc, 0xc9, 0x54, 0x0a, 0xf5, 0xc7,
+	0xd3, 0x44, 0x56, 0xfd, 0x94, 0x9b, 0x3e, 0xe9, 0x3b, 0xd6, 0x85, 0x8e, 0xfd, 0x90, 0x67, 0x50,
+	0x38, 0xa3, 0x67, 0xc7, 0xd4, 0xb2, 0x3f, 0x37, 0x06, 0x76, 0x29, 0x7b, 0x27, 0x53, 0x29, 0xd6,
+	0x1f, 0x44, 0x4d, 0xdb, 0xd1, 0x80, 0xb6, 0xab, 0xcf, 0x5c, 0xfc, 0x6e, 0x7a, 0x7d, 0x41, 0xf7,
+	0xdb, 0x93, 0xef, 0xc3, 0xa2, 0x65, 0xf6, 0xa8, 0x5d, 0x5a, 0xe4, 0x1d, 0xdd, 0x8e, 0x9c, 0x7f,
+	0xb3, 0x47, 0xb9, 0xb5, 0x80, 0x93, 0xbb, 0xb0, 0xca, 0xa6, 0xc4, 0x9b, 0x8b, 0x25, 0x3e, 0x4f,
+	0x2b, 0xac, 0x51, 0x8e, 0xbe, 0xfc, 0x03, 0x28, 0xf8, 0x86, 0x40, 0xd6, 0x21, 0xd3, 0xa5, 0x17,
+	0x82, 0x1e, 0x3a, 0xfb, 0xc9, 0x66, 0xf9, 0xbc, 0xd5, 0x1b, 0xd2, 0x52, 0x9a, 0xb7, 0x89, 0x87,
+	0x0f, 0xd2, 0x8f, 0x53, 0xda, 0x1e, 0x6c, 0xf8, 0xa6, 0x05, 0xb9, 0x52, 0x85, 0x45, 0xc6, 0x02,
+	0x91, 0x94, 0x38, 0xb2, 0x08, 0x98, 0xf6, 0xc7, 0x14, 0x6c, 0xbc, 0x1a, 0x74, 0x5a, 0x0e, 0x9d,
+	0x96, 0xa9, 0xe4, 0xc7, 0xb0, 0xc2, 0x41, 0xe7, 0xd4, 0xb2, 0x0d, 0xb3, 0xcf, 0x03, 0x2c, 0xd4,
+	0x6f, 0xa9, 0x3c, 0x7e, 0x26, 0x20, 0x7a, 0x81, 0x19, 0xe0, 0x03, 0xf9, 0x2e, 0x64, 0xd9, 0xc2,
+	0x2e, 0x65, 0xb8, 0xdd, 0xed, 0xb8, 0xfc, 0xe8, 0x1c, 0xa9, 0xed, 0x02, 0xf1, 0xc7, 0x3a, 0xd3,
+	0xf2, 0x38, 0x84, 0x0d, 0x9d, 0x9e, 0x99, 0xe7, 0xd3, 0x8f, 0x77, 0x13, 0x16, 0x4f, 0x4c, 0xab,
+	0x2d, 0x32, 0x91, 0xd7, 0xc5, 0x83, 0xb6, 0x09, 0xc4, 0xdf, 0x9f, 0x88, 0x09, 0x17, 0xff, 0xcb,
+	0x96, 0xdd, 0xf5, 0xb9, 0x70, 0x5a, 0x76, 0x37, 0xe4, 0x82, 0x21, 0x98, 0x0b, 0xf6, 0xca, 0x5d,
+	0xfc, 0xc2, 0xcc, 0x1b, 0x1d, 0x7b, 0x19, 0x37, 0x3a, 0x8e, 0xe7, 0x28, 0xed, 0xb1, 0x1c, 0xdd,
+	0xd4, 0xae, 0xdd, 0x71, 0xf8, 0xbd, 0x6b, 0x7f, 0xcd, 0x0a, 0x31, 0x61, 0x8d, 0x33, 0x88, 0x89,
+	0xdf, 0x6c, 0x5c, 0x4c, 0xfe, 0x79, 0x8d, 0x62, 0xa2, 0x8a, 0x4c, 0x29, 0x26, 0x35, 0x28, 0xd8,
+	0xd4, 0x3a, 0x37, 0xda, 0x8c, 0x1d, 0x42, 0x4c, 0x30, 0x84, 0x23, 0xd1, 0xdc, 0xd8, 0xb7, 0x75,
+	0x40, 0x48, 0xa3, 0x63, 0x93, 0xfb, 0x90, 0x47, 0x2e, 0x09, 0xc5, 0x58, 0xde, 0x2d, 0x8c, 0x2e,
+	0xb7, 0x73, 0x82, 0x4c, 0xb6, 0x9e, 0x13, 0x6c, 0xb2, 0xc9, 0xc7, 0x50, 0xec, 0x50, 0xdb, 0xb0,
+	0x68, 0xa7, 0x69, 0x3b, 0x2d, 0x07, 0xf5, 0xa1, 0x58, 0xff, 0x56, 0x54, 0x8a, 0x8f, 0x18, 0x8a,
+	0x0b, 0xcc, 0x2a, 0x1a, 0xf2, 0x16, 0x85, 0xd0, 0xe4, 0xc6, 0x85, 0x86, 0xdc, 0x06, 0x18, 0x0e,
+	0x9a, 0x8e, 0xd9, 0x64, 0xeb, 0xa7, 0x94, 0xe7, 0x14, 0xce, 0x0f, 0x07, 0x2f, 0xcd, 0xfd, 0x96,
+	0x43, 0x49, 0x19, 0xf2, 0xd6, 0xb0, 0xef, 0x18, 0x2c, 0x03, 0xcb, 0xdc, 0xda, 0x7d, 0x9e, 0x83,
+	0x44, 0xe1, 0x64, 0x7b, 0x12, 0xc5, 0x38, 0x17, 0x2b, 0x51, 0x9c, 0x84, 0x02, 0xa6, 0x1d, 0xc0,
+	0xe6, 0x9e, 0x45, 0x5b, 0x0e, 0xc5, 0x09, 0x97, 0x34, 0x7c, 0x84, 0xfa, 0x21, 0x38, 0xb8, 0xad,
+	0xea, 0x06, 0x2d, 0x7c, 0x12, 0x72, 0x08, 0x37, 0x43, 0x9d, 0x61, 0x54, 0xef, 0x41, 0x0e, 0x93,
+	0x88, 0x1d, 0xde, 0x8a, 0xe9, 0x50, 0x97, 0x58, 0xed, 0x35, 0x6c, 0x3c, 0xa5, 0x4e, 0x28, 0xb2,
+	0x1d, 0x00, 0x8f, 0x33, 0xb8, 0xe6, 0x56, 0x47, 0x97, 0xdb, 0xcb, 0x2e, 0x65, 0xf4, 0x65, 0x97,
+	0x31, 0xe4, 0x01, 0xac, 0x19, 0x7d, 0x9b, 0x5a, 0x4e, 0xb3, 0x43, 0x4f, 0x5a, 0xc3, 0x9e, 0x63,
+	0xa3, 0xc2, 0x14, 0x45, 0xf3, 0x3e, 0xb6, 0x6a, 0x07, 0x40, 0xfc, 0xbe, 0xae, 0x16, 0xf8, 0x9f,
+	0xd3, 0xb0, 0x29, 0xc4, 0xf4, 0x4a, 0xc1, 0xef, 0xc3, 0x9a, 0x44, 0x4f, 0xf1, 0x1d, 0x28, 0xa2,
+	0x8d, 0xfc, 0x14, 0x3c, 0x0a, 0x7c, 0x0a, 0x26, 0x4b, 0x25, 0x79, 0x06, 0x79, 0xcb, 0xec, 0xf5,
+	0x8e, 0x5b, 0xed, 0x6e, 0x29, 0x7b, 0x27, 0x55, 0x29, 0xd6, 0xdf, 0x55, 0x19, 0xaa, 0x06, 0x59,
+	0xd5, 0xd1, 0x50, 0x77, 0xbb, 0xd0, 0x34, 0xc8, 0xcb, 0x56, 0x92, 0x87, 0xec, 0xe1, 0xf3, 0xc3,
+	0x27, 0xeb, 0x0b, 0x64, 0x05, 0xf2, 0x2f, 0xf4, 0x27, 0x9f, 0x35, 0x9e, 0xbf, 0x3a, 0x5a, 0x4f,
+	0x31, 0xf6, 0x84, 0xba, 0xbb, 0x5a, 0x12, 0xf6, 0x61, 0x53, 0x88, 0xee, 0x55, 0x72, 0xa0, 0x7d,
+	0x13, 0x6e, 0x86, 0x7a, 0x41, 0xf5, 0xfe, 0x2a, 0x03, 0x37, 0xd8, 0xfa, 0xc3, 0x76, 0x57, 0xc0,
+	0x1b, 0x61, 0x01, 0xaf, 0x45, 0xc9, 0x64, 0xc8, 0x72, 0x5c, 0xc3, 0xff, 0x90, 0x9e, 0xbb, 0x86,
+	0x1f, 0x85, 0x34, 0xfc, 0x87, 0x53, 0x06, 0xa7, 0x94, 0xf1, 0x31, 0x8d, 0xcc, 0x2a, 0x34, 0xd2,
+	0xaf, 0x82, 0x8b, 0xf3, 0x53, 0xc1, 0xe7, 0xb0, 0x19, 0x0c, 0x17, 0x49, 0xf3, 0x3e, 0xe4, 0x31,
+	0x89, 0x52, 0x0b, 0x63, 0x59, 0xe3, 0x82, 0x3d, 0x45, 0x3c, 0xa4, 0xce, 0x17, 0xa6, 0xd5, 0x9d,
+	0x42, 0x11, 0xd1, 0x42, 0xa5, 0x88, 0x6e, 0x67, 0x1e, 0xa7, 0xfb, 0xa2, 0x29, 0x8e, 0xd3, 0xd2,
+	0x4a, 0x62, 0xb5, 0x57, 0x5c, 0x11, 0x43, 0x91, 0x11, 0xc8, 0xb2, 0x99, 0xc6, 0xf9, 0xe2, 0xbf,
+	0x19, 0xc9, 0xd1, 0x86, 0x91, 0x3c, 0xed, 0x91, 0x1c, 0x6d, 0x19, 0xc9, 0x11, 0xd0, 0xe8, 0xa0,
+	0xf8, 0xcd, 0x29, 0xc6, 0x9f, 0xc9, 0x75, 0x37, 0xf7, 0x30, 0xdd, 0xb5, 0x18, 0x8a, 0x54, 0xfb,
+	0x6f, 0x5a, 0xac, 0x45, 0x6c, 0x9f, 0x61, 0x2d, 0x86, 0x2c, 0xc7, 0xd7, 0xe2, 0x6f, 0xae, 0x71,
+	0x2d, 0x46, 0x04, 0x37, 0xf3, 0x5a, 0x9c, 0xc3, 0x7a, 0xf3, 0x42, 0xf2, 0xd6, 0x1b, 0x26, 0x2a,
+	0x76, 0xbd, 0xc9, 0xcc, 0xb9, 0x60, 0xed, 0x43, 0x4e, 0xe9, 0xbd, 0xde, 0xd0, 0x76, 0xa8, 0xe5,
+	0xd3, 0xe8, 0xb6, 0x68, 0x09, 0x69, 0x34, 0xe2, 0x18, 0x2f, 0x10, 0xe0, 0xd2, 0xd7, 0xed, 0xc2,
+	0xa3, 0x2f, 0x42, 0xe2, 0xe8, 0x2b, 0xad, 0x24, 0xd6, 0xe5, 0x12, 0xbe, 0x98, 0x81, 0x4b, 0x21,
+	0xcb, 0xb7, 0x8b, 0x4b, 0x11, 0xc1, 0x5d, 0x27, 0x97, 0xbc, 0x90, 0x3c, 0x2e, 0x61, 0x36, 0x62,
+	0xb9, 0x24, 0x53, 0xe7, 0x82, 0xb5, 0xdf, 0xa5, 0xa0, 0x70, 0x40, 0x2f, 0x74, 0xd3, 0x69, 0x39,
+	0x6c, 0xeb, 0xf3, 0x0e, 0x6c, 0x30, 0x92, 0x51, 0xab, 0xf9, 0xda, 0x34, 0xfa, 0x4d, 0xc7, 0xec,
+	0xd2, 0x3e, 0x0f, 0x2d, 0xaf, 0xaf, 0x89, 0x17, 0x9f, 0x98, 0x46, 0xff, 0x25, 0x6b, 0x26, 0x3b,
+	0x40, 0xce, 0x5a, 0xfd, 0xd6, 0x69, 0x10, 0x2c, 0x36, 0x8b, 0xeb, 0xf8, 0x46, 0x89, 0x1e, 0xf6,
+	0x7b, 0x66, 0xbb, 0xdb, 0x64, 0xa3, 0xce, 0x04, 0xd0, 0xaf, 0xf8, 0x8b, 0x03, 0x7a, 0xa1, 0xfd,
+	0xda, 0xdd, 0x0f, 0x5e, 0x85, 0xe7, 0x6c, 0x3f, 0x28, 0xd1, 0xd3, 0xec, 0x07, 0xd1, 0x66, 0x8a,
+	0xfd, 0x20, 0x7a, 0xf7, 0xed, 0x07, 0x3f, 0x64, 0xfb, 0x41, 0x31, 0xab, 0x7c, 0x3f, 0x18, 0x61,
+	0xe8, 0x9b, 0xfc, 0xdd, 0xec, 0x9b, 0xcb, 0xed, 0x05, 0xdd, 0x35, 0xf3, 0xf6, 0x77, 0x73, 0x5a,
+	0xa8, 0x3f, 0x82, 0x75, 0xbe, 0x63, 0x6f, 0x5b, 0xd4, 0x91, 0xf3, 0xf9, 0x10, 0x96, 0x6d, 0xde,
+	0xe0, 0x4d, 0xe7, 0xca, 0xe8, 0x72, 0x3b, 0x2f, 0x50, 0x8d, 0x7d, 0xf6, 0x9d, 0xe7, 0xbf, 0x3a,
+	0xda, 0x53, 0x3c, 0x5c, 0x08, 0x73, 0x0c, 0xa5, 0x0e, 0x4b, 0x02, 0x80, 0x91, 0x94, 0xd5, 0x7b,
+	0x06, 0x6e, 0x83, 0x48, 0xed, 0x2f, 0x29, 0xb8, 0x21, 0x37, 0xae, 0xb3, 0xc5, 0x42, 0x76, 0xa1,
+	0x88, 0xd0, 0x29, 0xf2, 0xba, 0x2a, 0x4c, 0x64, 0x5a, 0xeb, 0x81, 0xb4, 0x6e, 0x45, 0x07, 0xee,
+	0xdb, 0x9e, 0x7c, 0xe2, 0x1d, 0x53, 0xae, 0x3c, 0x0d, 0xff, 0x4e, 0x03, 0x11, 0x3b, 0x31, 0xf6,
+	0xe8, 0xca, 0xe6, 0xc7, 0x61, 0xd9, 0xac, 0x46, 0xef, 0x38, 0xfd, 0x86, 0xe3, 0xaa, 0xf9, 0xd5,
+	0xfc, 0x55, 0x53, 0x0f, 0xa9, 0xe6, 0x07, 0xd3, 0xc5, 0x76, 0x2d, 0xa2, 0x79, 0x20, 0x8f, 0x1d,
+	0x18, 0x11, 0xa6, 0xec, 0x7b, 0xec, 0x90, 0xc4, 0x9b, 0x50, 0x32, 0xe3, 0x72, 0x26, 0xa1, 0x5a,
+	0x03, 0x6e, 0xc8, 0x13, 0xbb, 0x9f, 0xba, 0xf5, 0xc0, 0x5e, 0x77, 0x62, 0x2e, 0x05, 0xbb, 0xba,
+	0x02, 0x97, 0x7e, 0x0a, 0x37, 0xe4, 0xa1, 0x6b, 0xc6, 0xd5, 0xfd, 0x0d, 0xef, 0xf0, 0xe7, 0x8f,
+	0x06, 0x45, 0x63, 0xcf, 0xec, 0x9f, 0x18, 0xa7, 0xbe, 0x6e, 0xdb, 0xbc, 0x21, 0xd4, 0xad, 0x40,
+	0xb1, 0x6e, 0xc5, 0x6b, 0x57, 0x34, 0xa4, 0xb9, 0x37, 0x42, 0x01, 0x88, 0x1b, 0x21, 0xda, 0x20,
+	0xd2, 0x27, 0x1a, 0xb3, 0xc6, 0xc2, 0x44, 0x03, 0xa1, 0xd3, 0x88, 0x86, 0x30, 0x99, 0x42, 0x34,
+	0x84, 0x67, 0x95, 0x68, 0xcc, 0x61, 0x1a, 0xa4, 0x68, 0x88, 0xe6, 0x19, 0x44, 0x23, 0x68, 0xf8,
+	0x76, 0x89, 0x86, 0x3a, 0xb6, 0xeb, 0x14, 0x0d, 0x37, 0x22, 0x4f, 0x34, 0x44, 0x22, 0x62, 0x45,
+	0x03, 0x73, 0x26, 0xa1, 0x9e, 0x68, 0x04, 0xa9, 0x3b, 0x81, 0x68, 0xa8, 0xb8, 0x14, 0xec, 0xea,
+	0x0a, 0x5c, 0x72, 0x45, 0x63, 0xe6, 0xd5, 0xed, 0x8a, 0x46, 0x30, 0x9a, 0xfa, 0xaf, 0x6e, 0x41,
+	0x6e, 0x4f, 0x5c, 0xb4, 0x12, 0x03, 0x72, 0x78, 0x85, 0x48, 0x34, 0x55, 0x50, 0xc1, 0x6b, 0xc9,
+	0xf2, 0xdd, 0x58, 0x0c, 0x8a, 0xd2, 0xcd, 0xbf, 0xfd, 0xe9, 0x7f, 0xbf, 0x4f, 0xaf, 0xc1, 0x2a,
+	0x07, 0x7d, 0x07, 0xb7, 0x8f, 0xc4, 0x84, 0x65, 0xf7, 0x0e, 0x8a, 0x7c, 0x7b, 0x92, 0x9b, 0xbb,
+	0xf2, 0xbd, 0x04, 0x54, 0xbc, 0x43, 0x0b, 0xc0, 0xbb, 0x02, 0x22, 0xf7, 0xa2, 0x0b, 0x7e, 0xfe,
+	0x11, 0xde, 0x4f, 0x82, 0x25, 0xfa, 0xf4, 0xae, 0x78, 0xd4, 0x3e, 0xc7, 0xae, 0x94, 0xd4, 0x3e,
+	0x15, 0x37, 0x45, 0x11, 0x3e, 0x45, 0x0e, 0x5f, 0xb6, 0xec, 0x6e, 0x64, 0x0e, 0x7d, 0x57, 0x3c,
+	0x91, 0x39, 0x0c, 0x5c, 0xe6, 0xc4, 0xe7, 0x90, 0x17, 0xe9, 0xa3, 0x73, 0xe8, 0xbf, 0x30, 0x89,
+	0xce, 0x61, 0xa0, 0xd2, 0x9f, 0x38, 0x9f, 0x7c, 0x78, 0x31, 0xf3, 0xe9, 0x1f, 0xe1, 0xfd, 0x24,
+	0x58, 0xa2, 0x4f, 0xaf, 0x76, 0xae, 0xf6, 0x39, 0x56, 0xc7, 0x57, 0xfb, 0x1c, 0x2f, 0xc1, 0x47,
+	0xf9, 0xfc, 0x12, 0x56, 0xfc, 0x75, 0x3f, 0xf2, 0x60, 0xc2, 0x42, 0x66, 0xb9, 0x92, 0x0c, 0x8c,
+	0xf7, 0xfc, 0x0b, 0x58, 0x0d, 0xdc, 0x72, 0x10, 0x65, 0x8f, 0xaa, 0x5b, 0x95, 0xf2, 0xc3, 0x09,
+	0x90, 0x89, 0xce, 0x03, 0x45, 0x72, 0xb5, 0x73, 0x55, 0x59, 0x5e, 0xed, 0x5c, 0x59, 0x71, 0x8f,
+	0x71, 0x1e, 0xa8, 0x85, 0xab, 0x9d, 0xab, 0x8a, 0xee, 0x6a, 0xe7, 0xea, 0xc2, 0x7a, 0x2c, 0xc9,
+	0xb0, 0x7e, 0x14, 0x49, 0xb2, 0x60, 0xcd, 0x31, 0x92, 0x64, 0xe1, 0x02, 0x62, 0x3c, 0xc9, 0x64,
+	0xb1, 0x2b, 0x9a, 0x64, 0xa1, 0x0a, 0x5d, 0x34, 0xc9, 0xc2, 0x75, 0xb3, 0x44, 0x92, 0xc9, 0x01,
+	0xc7, 0x90, 0x2c, 0x34, 0xe6, 0x87, 0x13, 0x20, 0x27, 0xcc, 0x73, 0xac, 0x73, 0x55, 0x91, 0x37,
+	0x2e, 0xcf, 0x13, 0x3a, 0x17, 0x79, 0xc6, 0xd3, 0x7e, 0x64, 0x9e, 0x83, 0x75, 0x94, 0xc8, 0x3c,
+	0x87, 0x4a, 0x0d, 0x09, 0x79, 0x96, 0x85, 0xa8, 0xe8, 0x3c, 0x87, 0xaa, 0x67, 0xd1, 0x79, 0x0e,
+	0xd7, 0xb4, 0x12, 0xd7, 0xb3, 0x1c, 0x70, 0xcc, 0x7a, 0x0e, 0x8d, 0xf9, 0xe1, 0x04, 0xc8, 0xc4,
+	0x8f, 0x93, 0x5b, 0x02, 0x51, 0x7f, 0x9c, 0xc2, 0x05, 0x96, 0xf2, 0xbd, 0x04, 0x54, 0xe2, 0x3c,
+	0xfb, 0xeb, 0x0d, 0xea, 0x79, 0x56, 0xd4, 0x52, 0xca, 0x95, 0x64, 0x60, 0xbc, 0xe7, 0x21, 0x14,
+	0x7c, 0xa7, 0x66, 0x72, 0x7f, 0xb2, 0x83, 0x7e, 0xf9, 0x41, 0x22, 0x2e, 0x71, 0xc0, 0xfe, 0x43,
+	0xb1, 0x7a, 0xc0, 0x8a, 0x13, 0x78, 0xb9, 0x92, 0x0c, 0x4c, 0xf4, 0xec, 0x3f, 0x00, 0xab, 0x3d,
+	0x2b, 0x0e, 0xd9, 0xe5, 0x4a, 0x32, 0x70, 0x12, 0x56, 0x89, 0x2d, 0x74, 0x24, 0xab, 0x02, 0x7b,
+	0xf4, 0x48, 0x56, 0x05, 0xf7, 0xe1, 0x89, 0xac, 0x42, 0x9f, 0x31, 0xac, 0x0a, 0xba, 0xad, 0x24,
+	0x03, 0x27, 0x62, 0x15, 0x1e, 0xab, 0xa2, 0x59, 0x15, 0x3c, 0x09, 0x46, 0xb3, 0x2a, 0x74, 0x3e,
+	0x4b, 0x64, 0x55, 0xdc, 0x80, 0x15, 0x47, 0xb4, 0x38, 0x56, 0x4d, 0x3c, 0xd5, 0xfe, 0x13, 0x52,
+	0x1c, 0xab, 0x26, 0xf0, 0xac, 0x3a, 0x6c, 0x45, 0x78, 0xde, 0x2d, 0xbd, 0xf9, 0x7a, 0x6b, 0xe1,
+	0x1f, 0x5f, 0x6f, 0x2d, 0xfc, 0x72, 0xb4, 0x95, 0x7a, 0x33, 0xda, 0x4a, 0xfd, 0x7d, 0xb4, 0x95,
+	0xfa, 0xd7, 0x68, 0x2b, 0x75, 0xbc, 0xc4, 0xff, 0x25, 0xf4, 0xd1, 0xff, 0x03, 0x00, 0x00, 0xff,
+	0xff, 0x47, 0x18, 0x50, 0x6c, 0x2b, 0x2b, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/control.proto b/vendor/github.com/docker/swarmkit/api/control.proto
index c8254ca..0ca5970 100644
--- a/vendor/github.com/docker/swarmkit/api/control.proto
+++ b/vendor/github.com/docker/swarmkit/api/control.proto
@@ -2,11 +2,11 @@
 
 package docker.swarmkit.v1;
 
-import "specs.proto";
-import "objects.proto";
-import "types.proto";
+import "github.com/docker/swarmkit/api/specs.proto";
+import "github.com/docker/swarmkit/api/objects.proto";
+import "github.com/docker/swarmkit/api/types.proto";
 import "gogoproto/gogo.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 // Control defines the RPC methods for controlling a cluster.
 service Control {
diff --git a/vendor/github.com/docker/swarmkit/api/dispatcher.pb.go b/vendor/github.com/docker/swarmkit/api/dispatcher.pb.go
index 825a607..8e9b038 100644
--- a/vendor/github.com/docker/swarmkit/api/dispatcher.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/dispatcher.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: dispatcher.proto
+// source: github.com/docker/swarmkit/api/dispatcher.proto
 // DO NOT EDIT!
 
 package api
@@ -1100,7 +1100,7 @@
 			ServerStreams: true,
 		},
 	},
-	Metadata: "dispatcher.proto",
+	Metadata: "github.com/docker/swarmkit/api/dispatcher.proto",
 }
 
 func (m *SessionRequest) Marshal() (dAtA []byte, err error) {
@@ -3778,70 +3778,73 @@
 	ErrIntOverflowDispatcher   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("dispatcher.proto", fileDescriptorDispatcher) }
+func init() {
+	proto.RegisterFile("github.com/docker/swarmkit/api/dispatcher.proto", fileDescriptorDispatcher)
+}
 
 var fileDescriptorDispatcher = []byte{
-	// 983 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x4f, 0x6f, 0x1b, 0x45,
-	0x14, 0xf7, 0x38, 0xce, 0x26, 0x7e, 0x4e, 0x82, 0x19, 0xaa, 0xb0, 0xac, 0x54, 0xc7, 0x6c, 0x68,
-	0x14, 0xa9, 0x61, 0x53, 0xcc, 0x9f, 0x0b, 0x51, 0x20, 0x8e, 0x2d, 0xc5, 0x6a, 0x93, 0x46, 0x13,
-	0xb7, 0x3d, 0x5a, 0x6b, 0xef, 0x74, 0xb3, 0x38, 0xde, 0x59, 0x76, 0xc6, 0x2d, 0x3e, 0x20, 0x71,
-	0xa0, 0x12, 0xe2, 0x84, 0x38, 0x45, 0x42, 0x7c, 0x05, 0xc4, 0xc7, 0x88, 0x38, 0x71, 0xe4, 0x14,
-	0xa8, 0x3f, 0x00, 0x1f, 0x80, 0x13, 0xda, 0xd9, 0x59, 0xdb, 0x75, 0xed, 0xd4, 0xc9, 0xc9, 0x9e,
-	0x37, 0xbf, 0xdf, 0x9b, 0xdf, 0xbc, 0xf7, 0xdb, 0x37, 0x90, 0x77, 0x3c, 0x1e, 0xd8, 0xa2, 0x75,
-	0x4a, 0x43, 0x2b, 0x08, 0x99, 0x60, 0x18, 0x3b, 0xac, 0xd5, 0xa6, 0xa1, 0xc5, 0x9f, 0xdb, 0x61,
-	0xa7, 0xed, 0x09, 0xeb, 0xd9, 0x47, 0x46, 0x4e, 0xf4, 0x02, 0xca, 0x63, 0x80, 0xb1, 0xcc, 0x9a,
-	0x5f, 0xd1, 0x96, 0x48, 0x96, 0xb7, 0x5c, 0xe6, 0x32, 0xf9, 0x77, 0x3b, 0xfa, 0xa7, 0xa2, 0xef,
-	0x04, 0x67, 0x5d, 0xd7, 0xf3, 0xb7, 0xe3, 0x1f, 0x15, 0x2c, 0xb8, 0x8c, 0xb9, 0x67, 0x74, 0x5b,
-	0xae, 0x9a, 0xdd, 0xa7, 0xdb, 0x4e, 0x37, 0xb4, 0x85, 0xc7, 0xd4, 0xbe, 0xf9, 0x02, 0xc1, 0xca,
-	0x09, 0xe5, 0xdc, 0x63, 0x3e, 0xa1, 0x5f, 0x77, 0x29, 0x17, 0xb8, 0x0a, 0x39, 0x87, 0xf2, 0x56,
-	0xe8, 0x05, 0x11, 0x4e, 0x47, 0x45, 0xb4, 0x99, 0x2b, 0xad, 0x5b, 0xaf, 0x6b, 0xb4, 0x8e, 0x98,
-	0x43, 0x2b, 0x43, 0x28, 0x19, 0xe5, 0xe1, 0x2d, 0x00, 0x1e, 0x27, 0x6e, 0x78, 0x8e, 0x9e, 0x2e,
-	0xa2, 0xcd, 0x6c, 0x79, 0xb9, 0x7f, 0xb9, 0x96, 0x55, 0xc7, 0xd5, 0x2a, 0x24, 0xab, 0x00, 0x35,
-	0xc7, 0xfc, 0x25, 0x3d, 0xd0, 0x71, 0x48, 0x39, 0xb7, 0x5d, 0x3a, 0x96, 0x00, 0x5d, 0x9d, 0x00,
-	0x6f, 0x41, 0xc6, 0x67, 0x0e, 0x95, 0x07, 0xe5, 0x4a, 0xfa, 0x34, 0xb9, 0x44, 0xa2, 0xf0, 0x0e,
-	0x2c, 0x76, 0x6c, 0xdf, 0x76, 0x69, 0xc8, 0xf5, 0xb9, 0xe2, 0xdc, 0x66, 0xae, 0x54, 0x9c, 0xc4,
-	0x78, 0x42, 0x3d, 0xf7, 0x54, 0x50, 0xe7, 0x98, 0xd2, 0x90, 0x0c, 0x18, 0xf8, 0x09, 0xac, 0xfa,
-	0x54, 0x3c, 0x67, 0x61, 0xbb, 0xd1, 0x64, 0x4c, 0x70, 0x11, 0xda, 0x41, 0xa3, 0x4d, 0x7b, 0x5c,
-	0xcf, 0xc8, 0x5c, 0xef, 0x4f, 0xca, 0x55, 0xf5, 0x5b, 0x61, 0x4f, 0x96, 0xe6, 0x3e, 0xed, 0x91,
-	0x5b, 0x2a, 0x41, 0x39, 0xe1, 0xdf, 0xa7, 0x3d, 0x8e, 0x57, 0x41, 0x23, 0x8c, 0x89, 0xfd, 0x3d,
-	0x7d, 0xbe, 0x88, 0x36, 0x97, 0x88, 0x5a, 0x99, 0x5f, 0x42, 0xfe, 0x80, 0xda, 0xa1, 0x68, 0x52,
-	0x5b, 0x24, 0x6d, 0xba, 0x56, 0x79, 0xcc, 0x63, 0x78, 0x7b, 0x24, 0x03, 0x0f, 0x98, 0xcf, 0x29,
-	0xfe, 0x1c, 0xb4, 0x80, 0x86, 0x1e, 0x73, 0x54, 0x93, 0xdf, 0xb3, 0x62, 0xb7, 0x58, 0x89, 0x5b,
-	0xac, 0x8a, 0x72, 0x4b, 0x79, 0xf1, 0xe2, 0x72, 0x2d, 0x75, 0xfe, 0xf7, 0x1a, 0x22, 0x8a, 0x62,
-	0xfe, 0x94, 0x86, 0x77, 0x1f, 0x05, 0x8e, 0x2d, 0x68, 0xdd, 0xe6, 0xed, 0x13, 0x61, 0x8b, 0x2e,
-	0xbf, 0x91, 0x36, 0xfc, 0x18, 0x16, 0xba, 0x32, 0x51, 0xd2, 0x8b, 0x9d, 0x49, 0xf5, 0x9b, 0x72,
-	0x96, 0x35, 0x8c, 0xc4, 0x08, 0x92, 0x24, 0x33, 0x18, 0xe4, 0xc7, 0x37, 0xf1, 0x3a, 0x2c, 0x08,
-	0x9b, 0xb7, 0x87, 0xb2, 0xa0, 0x7f, 0xb9, 0xa6, 0x45, 0xb0, 0x5a, 0x85, 0x68, 0xd1, 0x56, 0xcd,
-	0xc1, 0x9f, 0x81, 0xc6, 0x25, 0x49, 0xb9, 0xa9, 0x30, 0x49, 0xcf, 0x88, 0x12, 0x85, 0x36, 0x0d,
-	0xd0, 0x5f, 0x57, 0x19, 0xd7, 0xda, 0xdc, 0x81, 0xa5, 0x28, 0x7a, 0xb3, 0x12, 0x99, 0xbb, 0x8a,
-	0x9d, 0x7c, 0x1b, 0x16, 0xcc, 0x47, 0x5a, 0xb9, 0x8e, 0x64, 0xc1, 0xf4, 0x69, 0x02, 0x49, 0x0c,
-	0x33, 0xcb, 0x80, 0xf7, 0x38, 0xf7, 0x5c, 0xbf, 0x43, 0x7d, 0x71, 0x43, 0x0d, 0xbf, 0x23, 0x80,
-	0x61, 0x12, 0x6c, 0x41, 0x26, 0xca, 0xad, 0xac, 0x33, 0x55, 0xc1, 0x41, 0x8a, 0x48, 0x1c, 0xfe,
-	0x04, 0x34, 0x4e, 0x5b, 0x21, 0x15, 0xaa, 0xa8, 0xc6, 0x24, 0xc6, 0x89, 0x44, 0x1c, 0xa4, 0x88,
-	0xc2, 0x46, 0xac, 0x16, 0xf3, 0x9f, 0x7a, 0xae, 0x3e, 0x37, 0x9d, 0xb5, 0x2f, 0x11, 0x11, 0x2b,
-	0xc6, 0x96, 0x35, 0xc8, 0x78, 0x82, 0x76, 0xcc, 0x17, 0x69, 0xc8, 0x0f, 0x25, 0xef, 0x9f, 0xda,
-	0xbe, 0x4b, 0xf1, 0x2e, 0x80, 0x3d, 0x88, 0x29, 0xf9, 0x13, 0x3b, 0x3c, 0x64, 0x92, 0x11, 0x06,
-	0x3e, 0x04, 0xcd, 0x6e, 0xc9, 0xd1, 0x18, 0x5d, 0x64, 0xa5, 0xf4, 0xe9, 0xd5, 0xdc, 0xf8, 0xd4,
-	0x91, 0xc0, 0x9e, 0x24, 0x13, 0x95, 0xc4, 0x6c, 0x8e, 0x4a, 0x8c, 0xf7, 0xf0, 0x06, 0x68, 0x8f,
-	0x8e, 0x2b, 0x7b, 0xf5, 0x6a, 0x3e, 0x65, 0x18, 0x3f, 0xfe, 0x5a, 0x5c, 0x1d, 0x47, 0x28, 0x37,
-	0x6f, 0x80, 0x46, 0xaa, 0x87, 0x0f, 0x1f, 0x57, 0xf3, 0x68, 0x32, 0x8e, 0xd0, 0x0e, 0x7b, 0x46,
-	0xcd, 0xff, 0xd0, 0x2b, 0xfd, 0x4f, 0x5c, 0xf4, 0x05, 0x64, 0xa2, 0x57, 0x46, 0xd6, 0x60, 0xa5,
-	0x74, 0xf7, 0xea, 0x7b, 0x24, 0x2c, 0xab, 0xde, 0x0b, 0x28, 0x91, 0x44, 0x7c, 0x1b, 0xc0, 0x0e,
-	0x82, 0x33, 0x8f, 0xf2, 0x86, 0x60, 0xf1, 0x8c, 0x27, 0x59, 0x15, 0xa9, 0xb3, 0x68, 0x3b, 0xa4,
-	0xbc, 0x7b, 0x26, 0x78, 0xc3, 0xf3, 0x65, 0x03, 0xb3, 0x24, 0xab, 0x22, 0x35, 0x1f, 0xef, 0xc2,
-	0x42, 0x4b, 0x16, 0x27, 0x99, 0x9b, 0x1f, 0xcc, 0x52, 0x49, 0x92, 0x90, 0xcc, 0x3b, 0x90, 0x89,
-	0xb4, 0xe0, 0x25, 0x58, 0xdc, 0x7f, 0x78, 0x78, 0xfc, 0xa0, 0x1a, 0xd5, 0x0b, 0xbf, 0x05, 0xb9,
-	0xda, 0xd1, 0x3e, 0xa9, 0x1e, 0x56, 0x8f, 0xea, 0x7b, 0x0f, 0xf2, 0xa8, 0x74, 0x3e, 0x0f, 0x50,
-	0x19, 0x3c, 0xb9, 0xf8, 0x1b, 0x58, 0x50, 0xf6, 0xc6, 0xe6, 0x64, 0x0b, 0x8e, 0xbe, 0x86, 0xc6,
-	0x55, 0x18, 0x55, 0x11, 0x73, 0xfd, 0x8f, 0xdf, 0xfe, 0x3d, 0x4f, 0xdf, 0x86, 0x25, 0x89, 0xf9,
-	0x30, 0x9a, 0xeb, 0x34, 0x84, 0xe5, 0x78, 0xa5, 0x5e, 0x8d, 0x7b, 0x08, 0x7f, 0x0b, 0xd9, 0xc1,
-	0x0c, 0xc6, 0x13, 0xef, 0x3a, 0x3e, 0xe4, 0x8d, 0x3b, 0x6f, 0x40, 0xa9, 0xe1, 0x32, 0x8b, 0x00,
-	0xfc, 0x33, 0x82, 0xfc, 0xf8, 0x78, 0xc2, 0x77, 0xaf, 0x31, 0x6a, 0x8d, 0xad, 0xd9, 0xc0, 0xd7,
-	0x11, 0xd5, 0x85, 0x79, 0x39, 0xd8, 0x70, 0x71, 0xda, 0x00, 0x19, 0x9c, 0x3e, 0x1d, 0x91, 0xf4,
-	0x61, 0x63, 0x86, 0x13, 0x7f, 0x48, 0xa3, 0x7b, 0x08, 0x7f, 0x8f, 0x20, 0x37, 0x62, 0x6d, 0xbc,
-	0xf1, 0x06, 0xef, 0x27, 0x1a, 0x36, 0x66, 0xfb, 0x46, 0x66, 0x74, 0x44, 0x59, 0xbf, 0x78, 0x59,
-	0x48, 0xfd, 0xf5, 0xb2, 0x90, 0xfa, 0xae, 0x5f, 0x40, 0x17, 0xfd, 0x02, 0xfa, 0xb3, 0x5f, 0x40,
-	0xff, 0xf4, 0x0b, 0xa8, 0xa9, 0xc9, 0x27, 0xf8, 0xe3, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x6c,
-	0xba, 0x38, 0xbd, 0x2d, 0x0a, 0x00, 0x00,
+	// 1007 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x4f, 0x6f, 0xe3, 0x44,
+	0x1c, 0xcd, 0xa4, 0xa9, 0xdb, 0xfc, 0xd2, 0x2d, 0x61, 0xb4, 0x2a, 0xc6, 0xd2, 0xa6, 0xc1, 0x65,
+	0xab, 0x8a, 0x2d, 0xce, 0x12, 0xfe, 0x1d, 0xa8, 0x0a, 0x4d, 0x13, 0xa9, 0xd1, 0x6e, 0xbb, 0xd5,
+	0xb4, 0xbb, 0x7b, 0xac, 0x1c, 0x7b, 0xd6, 0x35, 0x69, 0x3c, 0xc6, 0x33, 0xd9, 0x25, 0x07, 0x24,
+	0x0e, 0xac, 0x84, 0x38, 0x21, 0x4e, 0x95, 0x10, 0x5f, 0x01, 0xf1, 0x31, 0x2a, 0x4e, 0x1c, 0x39,
+	0x15, 0x36, 0x1f, 0x80, 0x0f, 0xc0, 0x09, 0x79, 0x3c, 0x4e, 0x42, 0x37, 0x69, 0xd3, 0x9e, 0x12,
+	0xcf, 0xbc, 0xf7, 0xe6, 0xf9, 0xfd, 0x7e, 0xfe, 0x0d, 0x54, 0x3c, 0x5f, 0x1c, 0x77, 0x5b, 0x96,
+	0xc3, 0x3a, 0x15, 0x97, 0x39, 0x6d, 0x1a, 0x55, 0xf8, 0x0b, 0x3b, 0xea, 0xb4, 0x7d, 0x51, 0xb1,
+	0x43, 0xbf, 0xe2, 0xfa, 0x3c, 0xb4, 0x85, 0x73, 0x4c, 0x23, 0x2b, 0x8c, 0x98, 0x60, 0x18, 0x27,
+	0x28, 0x2b, 0x45, 0x59, 0xcf, 0x3f, 0x30, 0xde, 0xbb, 0x42, 0x44, 0xf4, 0x42, 0xca, 0x13, 0xbe,
+	0xb1, 0x7e, 0x05, 0x96, 0xb5, 0xbe, 0xa4, 0x8e, 0x48, 0xd1, 0xb7, 0x3d, 0xe6, 0x31, 0xf9, 0xb7,
+	0x12, 0xff, 0x53, 0xab, 0x9f, 0x5e, 0xa2, 0x21, 0x11, 0xad, 0xee, 0xb3, 0x4a, 0x78, 0xd2, 0xf5,
+	0xfc, 0x40, 0xfd, 0x28, 0x62, 0xc9, 0x63, 0xcc, 0x3b, 0xa1, 0x43, 0x90, 0xdb, 0x8d, 0x6c, 0xe1,
+	0x33, 0xb5, 0x6f, 0xbe, 0x44, 0xb0, 0x78, 0x40, 0x39, 0xf7, 0x59, 0x40, 0xe8, 0x57, 0x5d, 0xca,
+	0x05, 0x6e, 0x40, 0xc1, 0xa5, 0xdc, 0x89, 0xfc, 0x30, 0xc6, 0xe9, 0xa8, 0x8c, 0xd6, 0x0a, 0xd5,
+	0x15, 0xeb, 0xf5, 0x14, 0xac, 0x3d, 0xe6, 0xd2, 0xfa, 0x10, 0x4a, 0x46, 0x79, 0x78, 0x1d, 0x80,
+	0x27, 0xc2, 0x47, 0xbe, 0xab, 0x67, 0xcb, 0x68, 0x2d, 0x5f, 0xbb, 0xd5, 0x3f, 0x5f, 0xce, 0xab,
+	0xe3, 0x9a, 0x75, 0x92, 0x57, 0x80, 0xa6, 0x6b, 0xfe, 0x9c, 0x1d, 0xf8, 0xd8, 0xa5, 0x9c, 0xdb,
+	0x1e, 0xbd, 0x20, 0x80, 0x2e, 0x17, 0xc0, 0xeb, 0x90, 0x0b, 0x98, 0x4b, 0xe5, 0x41, 0x85, 0xaa,
+	0x3e, 0xc9, 0x2e, 0x91, 0x28, 0xbc, 0x01, 0xf3, 0x1d, 0x3b, 0xb0, 0x3d, 0x1a, 0x71, 0x7d, 0xa6,
+	0x3c, 0xb3, 0x56, 0xa8, 0x96, 0xc7, 0x31, 0x9e, 0x52, 0xdf, 0x3b, 0x16, 0xd4, 0xdd, 0xa7, 0x34,
+	0x22, 0x03, 0x06, 0x7e, 0x0a, 0x4b, 0x01, 0x15, 0x2f, 0x58, 0xd4, 0x3e, 0x6a, 0x31, 0x26, 0xb8,
+	0x88, 0xec, 0xf0, 0xa8, 0x4d, 0x7b, 0x5c, 0xcf, 0x49, 0xad, 0x77, 0xc6, 0x69, 0x35, 0x02, 0x27,
+	0xea, 0xc9, 0x68, 0x1e, 0xd0, 0x1e, 0xb9, 0xad, 0x04, 0x6a, 0x29, 0xff, 0x01, 0xed, 0x71, 0xbc,
+	0x04, 0x1a, 0x61, 0x4c, 0x6c, 0x6f, 0xe9, 0xb3, 0x65, 0xb4, 0xb6, 0x40, 0xd4, 0x93, 0xf9, 0x05,
+	0x14, 0x77, 0xa8, 0x1d, 0x89, 0x16, 0xb5, 0x45, 0x5a, 0xa6, 0x6b, 0xc5, 0x63, 0xee, 0xc3, 0x9b,
+	0x23, 0x0a, 0x3c, 0x64, 0x01, 0xa7, 0xf8, 0x33, 0xd0, 0x42, 0x1a, 0xf9, 0xcc, 0x55, 0x45, 0x7e,
+	0xdb, 0x4a, 0xba, 0xc5, 0x4a, 0xbb, 0xc5, 0xaa, 0xab, 0x6e, 0xa9, 0xcd, 0x9f, 0x9d, 0x2f, 0x67,
+	0x4e, 0xff, 0x5a, 0x46, 0x44, 0x51, 0xcc, 0x1f, 0xb3, 0xf0, 0xd6, 0xe3, 0xd0, 0xb5, 0x05, 0x3d,
+	0xb4, 0x79, 0xfb, 0x40, 0xd8, 0xa2, 0xcb, 0x6f, 0xe4, 0x0d, 0x3f, 0x81, 0xb9, 0xae, 0x14, 0x4a,
+	0x6b, 0xb1, 0x31, 0x2e, 0xbf, 0x09, 0x67, 0x59, 0xc3, 0x95, 0x04, 0x41, 0x52, 0x31, 0x83, 0x41,
+	0xf1, 0xe2, 0x26, 0x5e, 0x81, 0x39, 0x61, 0xf3, 0xf6, 0xd0, 0x16, 0xf4, 0xcf, 0x97, 0xb5, 0x18,
+	0xd6, 0xac, 0x13, 0x2d, 0xde, 0x6a, 0xba, 0xf8, 0x13, 0xd0, 0xb8, 0x24, 0xa9, 0x6e, 0x2a, 0x8d,
+	0xf3, 0x33, 0xe2, 0x44, 0xa1, 0x4d, 0x03, 0xf4, 0xd7, 0x5d, 0x26, 0x59, 0x9b, 0x1b, 0xb0, 0x10,
+	0xaf, 0xde, 0x2c, 0x22, 0x73, 0x53, 0xb1, 0xd3, 0x6f, 0xc3, 0x82, 0xd9, 0xd8, 0x2b, 0xd7, 0x91,
+	0x0c, 0x4c, 0x9f, 0x64, 0x90, 0x24, 0x30, 0xb3, 0x06, 0x78, 0x8b, 0x73, 0xdf, 0x0b, 0x3a, 0x34,
+	0x10, 0x37, 0xf4, 0xf0, 0x1b, 0x02, 0x18, 0x8a, 0x60, 0x0b, 0x72, 0xb1, 0xb6, 0x6a, 0x9d, 0x89,
+	0x0e, 0x76, 0x32, 0x44, 0xe2, 0xf0, 0x47, 0xa0, 0x71, 0xea, 0x44, 0x54, 0xa8, 0x50, 0x8d, 0x71,
+	0x8c, 0x03, 0x89, 0xd8, 0xc9, 0x10, 0x85, 0x8d, 0x59, 0x0e, 0x0b, 0x9e, 0xf9, 0x9e, 0x3e, 0x33,
+	0x99, 0xb5, 0x2d, 0x11, 0x31, 0x2b, 0xc1, 0xd6, 0x34, 0xc8, 0xf9, 0x82, 0x76, 0xcc, 0x97, 0x59,
+	0x28, 0x0e, 0x2d, 0x6f, 0x1f, 0xdb, 0x81, 0x47, 0xf1, 0x26, 0x80, 0x3d, 0x58, 0x53, 0xf6, 0xc7,
+	0x56, 0x78, 0xc8, 0x24, 0x23, 0x0c, 0xbc, 0x0b, 0x9a, 0xed, 0xc8, 0xd1, 0x18, 0xbf, 0xc8, 0x62,
+	0xf5, 0xe3, 0xcb, 0xb9, 0xc9, 0xa9, 0x23, 0x0b, 0x5b, 0x92, 0x4c, 0x94, 0x88, 0xd9, 0x1a, 0xb5,
+	0x98, 0xec, 0xe1, 0x55, 0xd0, 0x1e, 0xef, 0xd7, 0xb7, 0x0e, 0x1b, 0xc5, 0x8c, 0x61, 0xfc, 0xf0,
+	0x4b, 0x79, 0xe9, 0x22, 0x42, 0x75, 0xf3, 0x2a, 0x68, 0xa4, 0xb1, 0xfb, 0xe8, 0x49, 0xa3, 0x88,
+	0xc6, 0xe3, 0x08, 0xed, 0xb0, 0xe7, 0xd4, 0xfc, 0x17, 0xfd, 0xaf, 0xfe, 0x69, 0x17, 0x7d, 0x0e,
+	0xb9, 0xf8, 0xa2, 0x92, 0x19, 0x2c, 0x56, 0xef, 0x5d, 0xfe, 0x1e, 0x29, 0xcb, 0x3a, 0xec, 0x85,
+	0x94, 0x48, 0x22, 0xbe, 0x03, 0x60, 0x87, 0xe1, 0x89, 0x4f, 0xf9, 0x91, 0x60, 0xc9, 0x8c, 0x27,
+	0x79, 0xb5, 0x72, 0xc8, 0xe2, 0xed, 0x88, 0xf2, 0xee, 0x89, 0xe0, 0x47, 0x7e, 0x20, 0x0b, 0x98,
+	0x27, 0x79, 0xb5, 0xd2, 0x0c, 0xf0, 0x26, 0xcc, 0x39, 0x32, 0x9c, 0x74, 0x6e, 0xbe, 0x3b, 0x4d,
+	0x92, 0x24, 0x25, 0x99, 0x77, 0x21, 0x17, 0x7b, 0xc1, 0x0b, 0x30, 0xbf, 0xfd, 0x68, 0x77, 0xff,
+	0x61, 0x23, 0xce, 0x0b, 0xbf, 0x01, 0x85, 0xe6, 0xde, 0x36, 0x69, 0xec, 0x36, 0xf6, 0x0e, 0xb7,
+	0x1e, 0x16, 0x51, 0xf5, 0x74, 0x16, 0xa0, 0x3e, 0xb8, 0xd4, 0xf1, 0xd7, 0x30, 0xa7, 0xda, 0x1b,
+	0x9b, 0xe3, 0x5b, 0x70, 0xf4, 0x36, 0x34, 0x2e, 0xc3, 0xa8, 0x44, 0xcc, 0x95, 0xdf, 0x7f, 0xfd,
+	0xe7, 0x34, 0x7b, 0x07, 0x16, 0x24, 0xe6, 0xfd, 0x78, 0xae, 0xd3, 0x08, 0x6e, 0x25, 0x4f, 0xea,
+	0xd6, 0xb8, 0x8f, 0xf0, 0x37, 0x90, 0x1f, 0xcc, 0x60, 0x3c, 0xf6, 0x5d, 0x2f, 0x0e, 0x79, 0xe3,
+	0xee, 0x15, 0x28, 0x35, 0x5c, 0xa6, 0x31, 0x80, 0x7f, 0x42, 0x50, 0xbc, 0x38, 0x9e, 0xf0, 0xbd,
+	0x6b, 0x8c, 0x5a, 0x63, 0x7d, 0x3a, 0xf0, 0x75, 0x4c, 0x75, 0x61, 0x56, 0x0e, 0x36, 0x5c, 0x9e,
+	0x34, 0x40, 0x06, 0xa7, 0x4f, 0x46, 0xa4, 0x75, 0x58, 0x9d, 0xe2, 0xc4, 0xef, 0xb3, 0xe8, 0x3e,
+	0xc2, 0xdf, 0x21, 0x28, 0x8c, 0xb4, 0x36, 0x5e, 0xbd, 0xa2, 0xf7, 0x53, 0x0f, 0xab, 0xd3, 0x7d,
+	0x23, 0x53, 0x76, 0x44, 0x4d, 0x3f, 0x7b, 0x55, 0xca, 0xfc, 0xf9, 0xaa, 0x94, 0xf9, 0xb6, 0x5f,
+	0x42, 0x67, 0xfd, 0x12, 0xfa, 0xa3, 0x5f, 0x42, 0x7f, 0xf7, 0x4b, 0xa8, 0xa5, 0xc9, 0x2b, 0xf8,
+	0xc3, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe0, 0xf0, 0x6a, 0xcb, 0xae, 0x0a, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/dispatcher.proto b/vendor/github.com/docker/swarmkit/api/dispatcher.proto
index 505a80b..232580e 100644
--- a/vendor/github.com/docker/swarmkit/api/dispatcher.proto
+++ b/vendor/github.com/docker/swarmkit/api/dispatcher.proto
@@ -2,10 +2,10 @@
 
 package docker.swarmkit.v1;
 
-import "types.proto";
-import "objects.proto";
+import "github.com/docker/swarmkit/api/types.proto";
+import "github.com/docker/swarmkit/api/objects.proto";
 import "gogoproto/gogo.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 import "google/protobuf/duration.proto";
 
 // Dispatcher is the API provided by a manager group for agents to connect to. Agents
diff --git a/vendor/github.com/docker/swarmkit/api/gen.go b/vendor/github.com/docker/swarmkit/api/gen.go
deleted file mode 100644
index 5a0bd33..0000000
--- a/vendor/github.com/docker/swarmkit/api/gen.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package api
-
-//go:generate protoc -I.:../protobuf:../vendor:../vendor/github.com/gogo/protobuf --gogoswarm_out=plugins=grpc+deepcopy+storeobject+raftproxy+authenticatedwrapper,import_path=github.com/docker/swarmkit/api,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto,Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor,Mplugin/plugin.proto=github.com/docker/swarmkit/protobuf/plugin,Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/any.proto=github.com/gogo/protobuf/types:. types.proto specs.proto objects.proto control.proto dispatcher.proto ca.proto snapshot.proto raft.proto health.proto resource.proto logbroker.proto watch.proto
diff --git a/vendor/github.com/docker/swarmkit/api/health.pb.go b/vendor/github.com/docker/swarmkit/api/health.pb.go
index 500e45b..757db6a 100644
--- a/vendor/github.com/docker/swarmkit/api/health.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/health.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: health.proto
+// source: github.com/docker/swarmkit/api/health.proto
 // DO NOT EDIT!
 
 package api
@@ -198,7 +198,7 @@
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "health.proto",
+	Metadata: "github.com/docker/swarmkit/api/health.proto",
 }
 
 func (m *HealthCheckRequest) Marshal() (dAtA []byte, err error) {
@@ -696,26 +696,28 @@
 	ErrIntOverflowHealth   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("health.proto", fileDescriptorHealth) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/health.proto", fileDescriptorHealth) }
 
 var fileDescriptorHealth = []byte{
-	// 287 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0x48, 0x4d, 0xcc,
-	0x29, 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xc9, 0x4f, 0xce, 0x4e, 0x2d,
-	0xd2, 0x2b, 0x2e, 0x4f, 0x2c, 0xca, 0xcd, 0xce, 0x2c, 0xd1, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf,
-	0x4f, 0xcf, 0x07, 0x4b, 0xeb, 0x83, 0x58, 0x10, 0x95, 0x52, 0xc2, 0x05, 0x39, 0xa5, 0xe9, 0x99,
-	0x79, 0xfa, 0x10, 0x0a, 0x22, 0xa8, 0xa4, 0xc7, 0x25, 0xe4, 0x01, 0x36, 0xce, 0x39, 0x23, 0x35,
-	0x39, 0x3b, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0x48, 0x82, 0x8b, 0xbd, 0x38, 0xb5, 0xa8,
-	0x2c, 0x33, 0x39, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0xc6, 0x55, 0x5a, 0xc0, 0xc8,
-	0x25, 0x8c, 0xa2, 0xa1, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x55, 0xc8, 0x97, 0x8b, 0xad, 0xb8, 0x24,
-	0xb1, 0xa4, 0xb4, 0x18, 0xac, 0x81, 0xcf, 0xc8, 0x54, 0x0f, 0xd3, 0x5d, 0x7a, 0x58, 0x34, 0xea,
-	0x05, 0x83, 0x0c, 0xce, 0x4b, 0x0f, 0x06, 0x6b, 0x0e, 0x82, 0x1a, 0xa2, 0x64, 0xc5, 0xc5, 0x8b,
-	0x22, 0x21, 0xc4, 0xcd, 0xc5, 0x1e, 0xea, 0xe7, 0xed, 0xe7, 0x1f, 0xee, 0x27, 0xc0, 0x00, 0xe2,
-	0x04, 0xbb, 0x06, 0x85, 0x79, 0xfa, 0xb9, 0x0b, 0x30, 0x0a, 0xf1, 0x73, 0x71, 0xfb, 0xf9, 0x87,
-	0xc4, 0xc3, 0x04, 0x98, 0x8c, 0x2a, 0xb9, 0xd8, 0x20, 0x16, 0x09, 0xe5, 0x73, 0xb1, 0x82, 0x2d,
-	0x13, 0x52, 0x23, 0xe8, 0x1a, 0xb0, 0xbf, 0xa5, 0xd4, 0x89, 0x74, 0xb5, 0x92, 0xe8, 0xa9, 0x75,
-	0xef, 0x66, 0x30, 0xf1, 0x73, 0xf1, 0x82, 0x15, 0xea, 0xe6, 0x26, 0xe6, 0x25, 0xa6, 0xa7, 0x16,
-	0x39, 0x49, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0xe3, 0xa1, 0x1c, 0x43, 0xc3, 0x23, 0x39, 0xc6, 0x13,
-	0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x31, 0x89, 0x0d, 0x1c, 0xdc,
-	0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x59, 0xcd, 0x52, 0xee, 0xbd, 0x01, 0x00, 0x00,
+	// 315 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4e, 0xcf, 0x2c, 0xc9,
+	0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2, 0x2f, 0x2e,
+	0x4f, 0x2c, 0xca, 0xcd, 0xce, 0x2c, 0xd1, 0x4f, 0x2c, 0xc8, 0xd4, 0xcf, 0x48, 0x4d, 0xcc, 0x29,
+	0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x82, 0xa8, 0xd0, 0x83, 0xa9, 0xd0, 0x2b,
+	0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x4b, 0xeb, 0x83, 0x58, 0x10, 0x95, 0x52, 0xe6,
+	0x78, 0x8c, 0x05, 0xab, 0x48, 0x2a, 0x4d, 0xd3, 0x2f, 0xc8, 0x29, 0x4d, 0xcf, 0xcc, 0x83, 0x52,
+	0x10, 0x8d, 0x4a, 0x7a, 0x5c, 0x42, 0x1e, 0x60, 0x2b, 0x9d, 0x33, 0x52, 0x93, 0xb3, 0x83, 0x52,
+	0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x24, 0xb8, 0xd8, 0x8b, 0x53, 0x8b, 0xca, 0x32, 0x93, 0x53,
+	0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0x60, 0x5c, 0xa5, 0x05, 0x8c, 0x5c, 0xc2, 0x28, 0x1a,
+	0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x85, 0x7c, 0xb9, 0xd8, 0x8a, 0x4b, 0x12, 0x4b, 0x4a, 0x8b,
+	0xc1, 0x1a, 0xf8, 0x8c, 0x4c, 0xf5, 0x30, 0xdd, 0xae, 0x87, 0x45, 0xa3, 0x5e, 0x30, 0xc8, 0xe0,
+	0xbc, 0xf4, 0x60, 0xb0, 0xe6, 0x20, 0xa8, 0x21, 0x4a, 0x56, 0x5c, 0xbc, 0x28, 0x12, 0x42, 0xdc,
+	0x5c, 0xec, 0xa1, 0x7e, 0xde, 0x7e, 0xfe, 0xe1, 0x7e, 0x02, 0x0c, 0x20, 0x4e, 0xb0, 0x6b, 0x50,
+	0x98, 0xa7, 0x9f, 0xbb, 0x00, 0xa3, 0x10, 0x3f, 0x17, 0xb7, 0x9f, 0x7f, 0x48, 0x3c, 0x4c, 0x80,
+	0xc9, 0xa8, 0x92, 0x8b, 0x0d, 0x62, 0x91, 0x50, 0x3e, 0x17, 0x2b, 0xd8, 0x32, 0x21, 0x35, 0x82,
+	0xae, 0x01, 0xfb, 0x5b, 0x4a, 0x9d, 0x48, 0x57, 0x2b, 0x89, 0x9e, 0x5a, 0xf7, 0x6e, 0x06, 0x13,
+	0x3f, 0x17, 0x2f, 0x58, 0xa1, 0x6e, 0x6e, 0x62, 0x5e, 0x62, 0x7a, 0x6a, 0x91, 0x93, 0xc4, 0x89,
+	0x87, 0x72, 0x0c, 0x37, 0x1e, 0xca, 0x31, 0x34, 0x3c, 0x92, 0x63, 0x3c, 0xf1, 0x48, 0x8e, 0xf1,
+	0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x93, 0xd8, 0xc0, 0xc1, 0x6d, 0x0c, 0x08, 0x00,
+	0x00, 0xff, 0xff, 0x7b, 0xf2, 0xdd, 0x23, 0x00, 0x02, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/health.proto b/vendor/github.com/docker/swarmkit/api/health.proto
index 5edb38b..8e066c0 100644
--- a/vendor/github.com/docker/swarmkit/api/health.proto
+++ b/vendor/github.com/docker/swarmkit/api/health.proto
@@ -12,7 +12,7 @@
 package docker.swarmkit.v1;
 
 import "gogoproto/gogo.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 service Health {
 	rpc Check(HealthCheckRequest) returns (HealthCheckResponse) {
diff --git a/vendor/github.com/docker/swarmkit/api/logbroker.pb.go b/vendor/github.com/docker/swarmkit/api/logbroker.pb.go
index 6a22eca..58515aa 100644
--- a/vendor/github.com/docker/swarmkit/api/logbroker.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/logbroker.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: logbroker.proto
+// source: github.com/docker/swarmkit/api/logbroker.proto
 // DO NOT EDIT!
 
 package api
@@ -618,7 +618,7 @@
 			ServerStreams: true,
 		},
 	},
-	Metadata: "logbroker.proto",
+	Metadata: "github.com/docker/swarmkit/api/logbroker.proto",
 }
 
 // Client API for LogBroker service
@@ -790,7 +790,7 @@
 			ClientStreams: true,
 		},
 	},
-	Metadata: "logbroker.proto",
+	Metadata: "github.com/docker/swarmkit/api/logbroker.proto",
 }
 
 func (m *LogSubscriptionOptions) Marshal() (dAtA []byte, err error) {
@@ -3350,67 +3350,71 @@
 	ErrIntOverflowLogbroker   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("logbroker.proto", fileDescriptorLogbroker) }
+func init() {
+	proto.RegisterFile("github.com/docker/swarmkit/api/logbroker.proto", fileDescriptorLogbroker)
+}
 
 var fileDescriptorLogbroker = []byte{
-	// 944 bytes of a gzipped FileDescriptorProto
+	// 966 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0x41, 0x6f, 0x1b, 0x45,
-	0x14, 0xc7, 0x3d, 0xeb, 0xc4, 0x8e, 0x9f, 0x9b, 0xc4, 0x1d, 0xa7, 0x91, 0x65, 0xa8, 0x6d, 0x6d,
-	0xa5, 0x62, 0x45, 0xc5, 0x6e, 0x8d, 0x10, 0x48, 0x91, 0x10, 0x35, 0xae, 0x90, 0x85, 0x9b, 0xa0,
-	0xb1, 0x23, 0xb8, 0x45, 0x6b, 0xef, 0x74, 0x59, 0x79, 0xbd, 0x63, 0x76, 0xc6, 0x09, 0x48, 0x1c,
-	0x38, 0x14, 0x09, 0xe5, 0xc0, 0x0d, 0x09, 0x0e, 0x3d, 0xd1, 0x0b, 0x42, 0xe2, 0xc2, 0x8d, 0x0f,
-	0x80, 0x22, 0x4e, 0x1c, 0x39, 0x59, 0x74, 0x3f, 0x00, 0x9f, 0x01, 0xed, 0xcc, 0xd8, 0xde, 0x60,
-	0xbb, 0x45, 0xe5, 0x92, 0xcc, 0xec, 0xfc, 0xdf, 0xbe, 0xdf, 0xfb, 0xcf, 0x7b, 0x6b, 0xd8, 0xf5,
-	0x98, 0xd3, 0x0f, 0xd8, 0x90, 0x06, 0xb5, 0x71, 0xc0, 0x04, 0xc3, 0xd8, 0x66, 0x83, 0x68, 0xc7,
-	0xcf, 0xad, 0x60, 0x34, 0x74, 0x45, 0xed, 0xec, 0x5e, 0x71, 0xcf, 0x61, 0x0e, 0x93, 0xc7, 0xf5,
-	0x68, 0xa5, 0x94, 0xc5, 0xb2, 0xc3, 0x98, 0xe3, 0xd1, 0xba, 0xdc, 0xf5, 0x27, 0x8f, 0xea, 0xc2,
-	0x1d, 0x51, 0x2e, 0xac, 0xd1, 0x58, 0x0b, 0xf2, 0x63, 0x6f, 0xe2, 0xb8, 0x7e, 0x5d, 0xfd, 0x53,
-	0x0f, 0xcd, 0x5f, 0x10, 0xec, 0x77, 0x98, 0xd3, 0x9d, 0xf4, 0xf9, 0x20, 0x70, 0xc7, 0xc2, 0x65,
-	0xfe, 0xb1, 0xfc, 0xcb, 0xf1, 0x21, 0xa4, 0xb9, 0x08, 0xa8, 0x35, 0xe2, 0x05, 0x54, 0x49, 0x56,
-	0x77, 0x1a, 0x37, 0x6b, 0xcb, 0x30, 0xb5, 0x28, 0x58, 0xaa, 0x9a, 0x46, 0x2e, 0x41, 0x66, 0x11,
-	0x78, 0x1f, 0x52, 0x8f, 0x98, 0xe7, 0xb1, 0xf3, 0x82, 0x51, 0x41, 0xd5, 0x2d, 0xa2, 0x77, 0x18,
-	0xc3, 0x86, 0xb0, 0x5c, 0xaf, 0x90, 0xac, 0xa0, 0x6a, 0x92, 0xc8, 0x35, 0xbe, 0x0b, 0x9b, 0xdc,
-	0xf5, 0x07, 0xb4, 0xb0, 0x51, 0x41, 0xd5, 0x6c, 0xa3, 0x58, 0x53, 0x95, 0xd4, 0x66, 0x95, 0xd4,
-	0x7a, 0xb3, 0x4a, 0x88, 0x12, 0x9a, 0xdf, 0x20, 0xc8, 0x46, 0x89, 0xa9, 0x47, 0x07, 0x82, 0x05,
-	0xb8, 0x0e, 0x59, 0x4e, 0x83, 0x33, 0x77, 0x40, 0x4f, 0x5d, 0x5b, 0xe1, 0x66, 0x9a, 0x3b, 0xe1,
-	0xb4, 0x0c, 0x5d, 0xf5, 0xb8, 0xdd, 0xe2, 0x04, 0xb4, 0xa4, 0x6d, 0x73, 0x7c, 0x1b, 0xb6, 0x7c,
-	0x66, 0x2b, 0xb5, 0x21, 0xd5, 0xd9, 0x70, 0x5a, 0x4e, 0x1f, 0x31, 0x5b, 0x4a, 0xd3, 0xd1, 0xa1,
-	0xd6, 0x09, 0x8b, 0x0f, 0xa5, 0x2e, 0xb9, 0xd0, 0xf5, 0x2c, 0x3e, 0x94, 0xba, 0xe8, 0xb0, 0x6d,
-	0x73, 0xf3, 0x31, 0x02, 0xe8, 0x30, 0xe7, 0x3d, 0xe6, 0x0b, 0xfa, 0x99, 0xc0, 0x77, 0x00, 0x16,
-	0x3c, 0x05, 0x54, 0x41, 0xd5, 0x4c, 0x73, 0x3b, 0x9c, 0x96, 0x33, 0x73, 0x1c, 0x92, 0x99, 0xd3,
-	0xe0, 0x5b, 0x90, 0xd6, 0x30, 0xd2, 0xac, 0x4c, 0x13, 0xc2, 0x69, 0x39, 0xa5, 0x58, 0x48, 0x4a,
-	0xa1, 0x44, 0x22, 0x4d, 0x22, 0xbd, 0xd3, 0x22, 0x05, 0x42, 0x52, 0x8a, 0xc3, 0xbc, 0x07, 0xe9,
-	0x0e, 0x73, 0xee, 0x0b, 0x11, 0xe0, 0x1c, 0x24, 0x87, 0xf4, 0x73, 0x95, 0x9b, 0x44, 0x4b, 0xbc,
-	0x07, 0x9b, 0x67, 0x96, 0x37, 0xa1, 0x2a, 0x09, 0x51, 0x1b, 0xf3, 0xc2, 0x90, 0xe4, 0x0f, 0x29,
-	0xe7, 0x96, 0x43, 0xf1, 0x3b, 0x90, 0x1e, 0xa8, 0x22, 0x64, 0x68, 0xb6, 0x51, 0x5a, 0x73, 0xe9,
-	0xba, 0xd4, 0xe6, 0xc6, 0xe5, 0xb4, 0x9c, 0x20, 0xb3, 0x20, 0xfc, 0x36, 0x64, 0xe6, 0x7d, 0x27,
-	0x13, 0x3d, 0xff, 0x3e, 0x17, 0x62, 0xfc, 0x26, 0xa4, 0x54, 0xf3, 0xc8, 0xfa, 0x5e, 0xd4, 0x6d,
-	0x44, 0x8b, 0xa3, 0x86, 0xb2, 0x2d, 0x61, 0xc9, 0xde, 0xb9, 0x46, 0xe4, 0x1a, 0xbf, 0x05, 0x9b,
-	0x96, 0x10, 0x01, 0x2f, 0x6c, 0x56, 0x92, 0xd5, 0x6c, 0xe3, 0x95, 0x35, 0x6f, 0x8a, 0x7c, 0xd2,
-	0xfc, 0x4a, 0x6f, 0x7e, 0x8f, 0x60, 0x4f, 0x8f, 0x42, 0x9f, 0x76, 0x98, 0xc3, 0x09, 0xfd, 0x74,
-	0x42, 0xb9, 0xc0, 0x87, 0xb0, 0xc5, 0x75, 0xb3, 0x69, 0x5f, 0xca, 0xeb, 0xf0, 0xb4, 0x8c, 0xcc,
-	0x03, 0x70, 0x0b, 0xd2, 0x4c, 0xcd, 0x94, 0x76, 0xe4, 0x60, 0x5d, 0xec, 0xf2, 0x14, 0x92, 0x59,
-	0xa8, 0xf9, 0xf1, 0xbf, 0xd0, 0x66, 0x37, 0xf6, 0x2e, 0x6c, 0x8d, 0xd4, 0x52, 0x35, 0xfe, 0xfa,
-	0x2b, 0xd3, 0x11, 0xba, 0xe4, 0x79, 0x94, 0xf9, 0x2a, 0x14, 0x3b, 0x2e, 0x17, 0xd4, 0x8f, 0xe7,
-	0x9f, 0x95, 0x6e, 0xfe, 0x86, 0x20, 0x1f, 0x3f, 0x98, 0xe5, 0xdd, 0x07, 0x63, 0xde, 0xdb, 0xa9,
-	0x70, 0x5a, 0x36, 0xda, 0x2d, 0x62, 0xb8, 0xf6, 0x15, 0xab, 0x8c, 0xff, 0x61, 0x55, 0xf2, 0xa5,
-	0xad, 0x8a, 0x3a, 0x7d, 0xe0, 0x31, 0xae, 0x3e, 0x28, 0x5b, 0x44, 0x6d, 0xcc, 0x1f, 0x11, 0xe0,
-	0x0f, 0x27, 0x7d, 0xcf, 0xe5, 0x9f, 0xc4, 0xfd, 0x3b, 0x84, 0x5d, 0x1e, 0x7b, 0xd9, 0x62, 0x60,
-	0x71, 0x38, 0x2d, 0xef, 0xc4, 0xf3, 0xb4, 0x5b, 0x64, 0x27, 0x2e, 0x6d, 0xdb, 0x57, 0xcc, 0x37,
-	0x5e, 0xc6, 0xfc, 0x05, 0x6b, 0x32, 0xce, 0x7a, 0x03, 0xf2, 0x31, 0x54, 0x42, 0xf9, 0x98, 0xf9,
-	0x9c, 0x1e, 0x3c, 0x45, 0x90, 0x99, 0x8f, 0x00, 0xbe, 0x03, 0xb8, 0x73, 0xfc, 0xfe, 0x69, 0xb7,
-	0x47, 0x1e, 0xdc, 0x7f, 0x78, 0x7a, 0x72, 0xf4, 0xc1, 0xd1, 0xf1, 0x47, 0x47, 0xb9, 0x44, 0x71,
-	0xef, 0xe2, 0x49, 0x25, 0x37, 0x97, 0x9d, 0xf8, 0x43, 0x9f, 0x9d, 0xfb, 0xf8, 0x00, 0xae, 0xc7,
-	0xd4, 0xdd, 0x5e, 0xeb, 0xf8, 0xa4, 0x97, 0x43, 0xc5, 0xfc, 0xc5, 0x93, 0xca, 0xee, 0x5c, 0xdc,
-	0x15, 0x36, 0x9b, 0x88, 0x65, 0xed, 0x03, 0x42, 0x72, 0xc6, 0xb2, 0x96, 0x06, 0x41, 0xf1, 0xfa,
-	0xd7, 0x3f, 0x94, 0x12, 0xbf, 0x3e, 0x2d, 0x2d, 0xc0, 0x1a, 0x8f, 0x11, 0x6c, 0x44, 0xdc, 0xf8,
-	0x0b, 0xd8, 0xbe, 0xd2, 0xb3, 0xb8, 0xba, 0xca, 0x9d, 0x55, 0x13, 0x57, 0x7c, 0xb1, 0x52, 0x3b,
-	0x6a, 0xde, 0xf8, 0xfd, 0xe7, 0xbf, 0xbf, 0x33, 0x76, 0x61, 0x5b, 0x2a, 0x5f, 0x1f, 0x59, 0xbe,
-	0xe5, 0xd0, 0xe0, 0x2e, 0x6a, 0xfc, 0x64, 0x48, 0xb7, 0x9a, 0xf2, 0xf7, 0x14, 0x7f, 0x8b, 0x20,
-	0xbf, 0xa2, 0xcd, 0x71, 0x6d, 0xe5, 0x85, 0xad, 0x9d, 0x87, 0xe2, 0x6b, 0xcf, 0x01, 0x8b, 0x0f,
-	0x88, 0x79, 0x4b, 0x72, 0xdd, 0x84, 0x6b, 0x8a, 0xeb, 0x9c, 0x05, 0x43, 0x1a, 0x2c, 0x51, 0xe2,
-	0xaf, 0x10, 0x64, 0x63, 0x77, 0x8d, 0x6f, 0xaf, 0x7a, 0xff, 0x72, 0xdf, 0xae, 0xe6, 0x58, 0xd1,
-	0x34, 0xff, 0x89, 0xa3, 0x8a, 0x9a, 0x85, 0xcb, 0x67, 0xa5, 0xc4, 0x9f, 0xcf, 0x4a, 0x89, 0x2f,
-	0xc3, 0x12, 0xba, 0x0c, 0x4b, 0xe8, 0x8f, 0xb0, 0x84, 0xfe, 0x0a, 0x4b, 0xa8, 0x9f, 0x92, 0x1f,
-	0xee, 0x37, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x08, 0xa1, 0xea, 0xc7, 0x9d, 0x08, 0x00, 0x00,
+	0x14, 0xc7, 0x3d, 0xeb, 0xc4, 0x8e, 0x9f, 0x9b, 0xc4, 0x9d, 0xa4, 0x91, 0x65, 0xa8, 0x6d, 0x6d,
+	0xa5, 0x62, 0x45, 0x65, 0xdd, 0x1a, 0xa1, 0x22, 0x45, 0x42, 0xd4, 0xb8, 0x42, 0x16, 0x6e, 0x82,
+	0xc6, 0x8e, 0xe0, 0x16, 0xad, 0xbd, 0xd3, 0xed, 0xca, 0xeb, 0x1d, 0xb3, 0x33, 0x4e, 0x40, 0xe2,
+	0xc0, 0xa1, 0x48, 0x28, 0x07, 0x6e, 0x48, 0x70, 0xe8, 0x89, 0x5e, 0x10, 0x12, 0x17, 0x6e, 0x7c,
+	0x00, 0x14, 0x71, 0xe2, 0xc8, 0xc9, 0xa2, 0xfb, 0x01, 0xf8, 0x0c, 0x68, 0x67, 0xd6, 0xeb, 0x0d,
+	0xb6, 0x53, 0x54, 0x2e, 0xf6, 0x8c, 0xe7, 0xf7, 0xf6, 0xfd, 0xdf, 0x7f, 0xde, 0x5b, 0x83, 0x61,
+	0x3b, 0xe2, 0xc9, 0xa4, 0x6f, 0x0c, 0xd8, 0xa8, 0x6e, 0xb1, 0xc1, 0x90, 0xfa, 0x75, 0x7e, 0x66,
+	0xfa, 0xa3, 0xa1, 0x23, 0xea, 0xe6, 0xd8, 0xa9, 0xbb, 0xcc, 0xee, 0xfb, 0x6c, 0x48, 0x7d, 0x63,
+	0xec, 0x33, 0xc1, 0x30, 0x56, 0x90, 0x31, 0x83, 0x8c, 0xd3, 0x7b, 0xa5, 0x5d, 0x9b, 0xd9, 0x4c,
+	0x1e, 0xd7, 0xc3, 0x95, 0x22, 0x4b, 0x15, 0x9b, 0x31, 0xdb, 0xa5, 0x75, 0xb9, 0xeb, 0x4f, 0x1e,
+	0xd7, 0x85, 0x33, 0xa2, 0x5c, 0x98, 0xa3, 0x71, 0x04, 0xdc, 0xbf, 0x22, 0x75, 0x1c, 0x34, 0x76,
+	0x27, 0xb6, 0xe3, 0x45, 0x5f, 0x2a, 0x50, 0xff, 0x05, 0xc1, 0x5e, 0x87, 0xd9, 0xdd, 0x49, 0x9f,
+	0x0f, 0x7c, 0x67, 0x2c, 0x1c, 0xe6, 0x1d, 0xc9, 0x4f, 0x8e, 0x0f, 0x20, 0xcb, 0x85, 0x4f, 0xcd,
+	0x11, 0x2f, 0xa2, 0x6a, 0xba, 0xb6, 0xd5, 0xb8, 0x69, 0x2c, 0x0a, 0x36, 0xc2, 0x60, 0x49, 0x35,
+	0xb5, 0x42, 0x8a, 0xcc, 0x22, 0xf0, 0x1e, 0x64, 0x1e, 0x33, 0xd7, 0x65, 0x67, 0x45, 0xad, 0x8a,
+	0x6a, 0x1b, 0x24, 0xda, 0x61, 0x0c, 0x6b, 0xc2, 0x74, 0xdc, 0x62, 0xba, 0x8a, 0x6a, 0x69, 0x22,
+	0xd7, 0xf8, 0x2e, 0xac, 0x73, 0xc7, 0x1b, 0xd0, 0xe2, 0x5a, 0x15, 0xd5, 0xf2, 0x8d, 0x92, 0xa1,
+	0xaa, 0x35, 0x66, 0xc2, 0x8d, 0xde, 0xac, 0x5a, 0xa2, 0x40, 0xfd, 0x1b, 0x04, 0xf9, 0x30, 0x31,
+	0x75, 0xe9, 0x40, 0x30, 0x1f, 0xd7, 0x21, 0xcf, 0xa9, 0x7f, 0xea, 0x0c, 0xe8, 0x89, 0x63, 0x29,
+	0xb9, 0xb9, 0xe6, 0x56, 0x30, 0xad, 0x40, 0x57, 0xfd, 0xdc, 0x6e, 0x71, 0x02, 0x11, 0xd2, 0xb6,
+	0x38, 0xbe, 0x0d, 0x1b, 0x1e, 0xb3, 0x14, 0xad, 0x49, 0x3a, 0x1f, 0x4c, 0x2b, 0xd9, 0x43, 0x66,
+	0x49, 0x34, 0x1b, 0x1e, 0x46, 0x9c, 0x30, 0xf9, 0x50, 0x72, 0xe9, 0x39, 0xd7, 0x33, 0xf9, 0x50,
+	0x72, 0xe1, 0x61, 0xdb, 0xe2, 0xfa, 0x53, 0x04, 0xd0, 0x61, 0xf6, 0xfb, 0xcc, 0x13, 0xf4, 0x33,
+	0x81, 0xef, 0x00, 0xcc, 0xf5, 0x14, 0x51, 0x15, 0xd5, 0x72, 0xcd, 0xcd, 0x60, 0x5a, 0xc9, 0xc5,
+	0x72, 0x48, 0x2e, 0x56, 0x83, 0x6f, 0x41, 0x36, 0x12, 0x23, 0xcd, 0xca, 0x35, 0x21, 0x98, 0x56,
+	0x32, 0x4a, 0x0b, 0xc9, 0x28, 0x29, 0x21, 0x14, 0x29, 0x91, 0xde, 0x45, 0x90, 0x12, 0x42, 0x32,
+	0x4a, 0x87, 0x7e, 0x0f, 0xb2, 0x1d, 0x66, 0x3f, 0x10, 0xc2, 0xc7, 0x05, 0x48, 0x0f, 0xe9, 0xe7,
+	0x2a, 0x37, 0x09, 0x97, 0x78, 0x17, 0xd6, 0x4f, 0x4d, 0x77, 0x42, 0x55, 0x12, 0xa2, 0x36, 0xfa,
+	0xb9, 0x26, 0x95, 0x3f, 0xa2, 0x9c, 0x9b, 0x36, 0xc5, 0xef, 0x42, 0x76, 0xa0, 0x8a, 0x90, 0xa1,
+	0xf9, 0x46, 0x79, 0xc5, 0xa5, 0x47, 0xa5, 0x36, 0xd7, 0x2e, 0xa6, 0x95, 0x14, 0x99, 0x05, 0xe1,
+	0x77, 0x20, 0x17, 0xf7, 0xa6, 0x4c, 0x74, 0xf5, 0x7d, 0xce, 0x61, 0xfc, 0x36, 0x64, 0x54, 0xf3,
+	0xc8, 0xfa, 0x5e, 0xd6, 0x6d, 0x24, 0x82, 0xc3, 0x86, 0xb2, 0x4c, 0x61, 0xca, 0xde, 0xb9, 0x46,
+	0xe4, 0x1a, 0xdf, 0x87, 0x75, 0x53, 0x08, 0x9f, 0x17, 0xd7, 0xab, 0xe9, 0x5a, 0xbe, 0xf1, 0xda,
+	0x8a, 0x27, 0x85, 0x3e, 0x45, 0xfa, 0x15, 0xaf, 0x7f, 0x8f, 0x60, 0x37, 0x1a, 0x85, 0x3e, 0xed,
+	0x30, 0x9b, 0x13, 0xfa, 0xe9, 0x84, 0x72, 0x81, 0x0f, 0x60, 0x83, 0x47, 0xcd, 0x16, 0xf9, 0x52,
+	0x59, 0x25, 0x2f, 0xc2, 0x48, 0x1c, 0x80, 0x5b, 0x90, 0x65, 0x6a, 0xa6, 0x22, 0x47, 0xf6, 0x57,
+	0xc5, 0x2e, 0x4e, 0x21, 0x99, 0x85, 0xea, 0x9f, 0xfc, 0x4b, 0xda, 0xec, 0xc6, 0xde, 0x83, 0x8d,
+	0x91, 0x5a, 0xaa, 0xc6, 0x5f, 0x7d, 0x65, 0x51, 0x44, 0x54, 0x72, 0x1c, 0xa5, 0xbf, 0x0e, 0xa5,
+	0x8e, 0xc3, 0x05, 0xf5, 0x92, 0xf9, 0x67, 0xa5, 0xeb, 0xbf, 0x21, 0xd8, 0x49, 0x1e, 0xcc, 0xf2,
+	0xee, 0x81, 0x16, 0xf7, 0x76, 0x26, 0x98, 0x56, 0xb4, 0x76, 0x8b, 0x68, 0x8e, 0x75, 0xc9, 0x2a,
+	0xed, 0x7f, 0x58, 0x95, 0x7e, 0x65, 0xab, 0xc2, 0x4e, 0x1f, 0xb8, 0x8c, 0xab, 0x17, 0xca, 0x06,
+	0x51, 0x1b, 0xfd, 0x47, 0x04, 0xf8, 0xa3, 0x49, 0xdf, 0x75, 0xf8, 0x93, 0xa4, 0x7f, 0x07, 0xb0,
+	0xcd, 0x13, 0x0f, 0x9b, 0x0f, 0x2c, 0x0e, 0xa6, 0x95, 0xad, 0x64, 0x9e, 0x76, 0x8b, 0x6c, 0x25,
+	0xd1, 0xb6, 0x75, 0xc9, 0x7c, 0xed, 0x55, 0xcc, 0x9f, 0x6b, 0x4d, 0x27, 0xb5, 0xde, 0x80, 0x9d,
+	0x84, 0x54, 0x42, 0xf9, 0x98, 0x79, 0x9c, 0xee, 0x3f, 0x47, 0x90, 0x8b, 0x47, 0x00, 0xdf, 0x01,
+	0xdc, 0x39, 0xfa, 0xe0, 0xa4, 0xdb, 0x23, 0x0f, 0x1f, 0x3c, 0x3a, 0x39, 0x3e, 0xfc, 0xf0, 0xf0,
+	0xe8, 0xe3, 0xc3, 0x42, 0xaa, 0xb4, 0x7b, 0xfe, 0xac, 0x5a, 0x88, 0xb1, 0x63, 0x6f, 0xe8, 0xb1,
+	0x33, 0x0f, 0xef, 0xc3, 0xf5, 0x04, 0xdd, 0xed, 0xb5, 0x8e, 0x8e, 0x7b, 0x05, 0x54, 0xda, 0x39,
+	0x7f, 0x56, 0xdd, 0x8e, 0xe1, 0xae, 0xb0, 0xd8, 0x44, 0x2c, 0xb2, 0x0f, 0x09, 0x29, 0x68, 0x8b,
+	0x2c, 0xf5, 0xfd, 0xd2, 0xf5, 0xaf, 0x7f, 0x28, 0xa7, 0x7e, 0x7d, 0x5e, 0x9e, 0x0b, 0x6b, 0x3c,
+	0x45, 0xb0, 0x16, 0xea, 0xc6, 0x5f, 0xc0, 0xe6, 0xa5, 0x9e, 0xc5, 0xb5, 0x65, 0xee, 0x2c, 0x9b,
+	0xb8, 0xd2, 0xcb, 0xc9, 0xc8, 0x51, 0xfd, 0xc6, 0xef, 0x3f, 0xff, 0xfd, 0x9d, 0xb6, 0x0d, 0x9b,
+	0x92, 0x7c, 0x73, 0x64, 0x7a, 0xa6, 0x4d, 0xfd, 0xbb, 0xa8, 0xf1, 0x93, 0x26, 0xdd, 0x6a, 0xca,
+	0xff, 0x5c, 0xfc, 0x2d, 0x82, 0x9d, 0x25, 0x6d, 0x8e, 0x8d, 0xa5, 0x17, 0xb6, 0x72, 0x1e, 0x4a,
+	0x6f, 0x5c, 0x21, 0x2c, 0x39, 0x20, 0xfa, 0x2d, 0xa9, 0xeb, 0x26, 0x5c, 0x53, 0xba, 0xce, 0x98,
+	0x3f, 0xa4, 0xfe, 0x82, 0x4a, 0xfc, 0x15, 0x82, 0x7c, 0xe2, 0xae, 0xf1, 0xed, 0x65, 0xcf, 0x5f,
+	0xec, 0xdb, 0xe5, 0x3a, 0x96, 0x34, 0xcd, 0x7f, 0xd2, 0x51, 0x43, 0xcd, 0xe2, 0xc5, 0x8b, 0x72,
+	0xea, 0xcf, 0x17, 0xe5, 0xd4, 0x97, 0x41, 0x19, 0x5d, 0x04, 0x65, 0xf4, 0x47, 0x50, 0x46, 0x7f,
+	0x05, 0x65, 0xd4, 0xcf, 0xc8, 0x17, 0xf7, 0x5b, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x95, 0x7b,
+	0x3c, 0x04, 0xe0, 0x08, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/logbroker.proto b/vendor/github.com/docker/swarmkit/api/logbroker.proto
index b86b8e8..1549640 100644
--- a/vendor/github.com/docker/swarmkit/api/logbroker.proto
+++ b/vendor/github.com/docker/swarmkit/api/logbroker.proto
@@ -4,7 +4,7 @@
 
 import "gogoproto/gogo.proto";
 import "google/protobuf/timestamp.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 // LogStream defines the stream from which the log message came.
 enum LogStream {
diff --git a/vendor/github.com/docker/swarmkit/api/objects.pb.go b/vendor/github.com/docker/swarmkit/api/objects.pb.go
index b6a9389..01abbe5 100644
--- a/vendor/github.com/docker/swarmkit/api/objects.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/objects.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: objects.proto
+// source: github.com/docker/swarmkit/api/objects.proto
 // DO NOT EDIT!
 
 package api
@@ -57,6 +57,7 @@
 	// ManagerStatus provides the current status of the node's manager
 	// component, if the node is a manager.
 	ManagerStatus *ManagerStatus `protobuf:"bytes,6,opt,name=manager_status,json=managerStatus" json:"manager_status,omitempty"`
+	// DEPRECATED: Use lb_attachments to find the ingress network
 	// The node attachment to the ingress network.
 	Attachment *NetworkAttachment `protobuf:"bytes,7,opt,name=attachment" json:"attachment,omitempty"`
 	// Certificate is the TLS certificate issued for the node, if any.
@@ -71,6 +72,10 @@
 	// shows the privilege level that the CA would currently grant when
 	// issuing or renewing the node's certificate.
 	Role NodeRole `protobuf:"varint,9,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"`
+	// Attachments enumerates the network attachments for the node to set up an
+	// endpoint on the node to be used for load balancing. Each overlay
+	// network, including ingress network, will have an NetworkAttachment.
+	Attachments []*NetworkAttachment `protobuf:"bytes,10,rep,name=attachments" json:"attachments,omitempty"`
 }
 
 func (m *Node) Reset()                    { *m = Node{} }
@@ -403,6 +408,14 @@
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.Attachment, o.Attachment)
 	}
 	github_com_docker_swarmkit_api_deepcopy.Copy(&m.Certificate, &o.Certificate)
+	if o.Attachments != nil {
+		m.Attachments = make([]*NetworkAttachment, len(o.Attachments))
+		for i := range m.Attachments {
+			m.Attachments[i] = &NetworkAttachment{}
+			github_com_docker_swarmkit_api_deepcopy.Copy(m.Attachments[i], o.Attachments[i])
+		}
+	}
+
 }
 
 func (m *Service) Copy() *Service {
@@ -849,6 +862,18 @@
 		i++
 		i = encodeVarintObjects(dAtA, i, uint64(m.Role))
 	}
+	if len(m.Attachments) > 0 {
+		for _, msg := range m.Attachments {
+			dAtA[i] = 0x52
+			i++
+			i = encodeVarintObjects(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
 	return i, nil
 }
 
@@ -1670,6 +1695,12 @@
 	if m.Role != 0 {
 		n += 1 + sovObjects(uint64(m.Role))
 	}
+	if len(m.Attachments) > 0 {
+		for _, e := range m.Attachments {
+			l = e.Size()
+			n += 1 + l + sovObjects(uint64(l))
+		}
+	}
 	return n
 }
 
@@ -4383,6 +4414,7 @@
 		`Attachment:` + strings.Replace(fmt.Sprintf("%v", this.Attachment), "NetworkAttachment", "NetworkAttachment", 1) + `,`,
 		`Certificate:` + strings.Replace(strings.Replace(this.Certificate.String(), "Certificate", "Certificate", 1), `&`, ``, 1) + `,`,
 		`Role:` + fmt.Sprintf("%v", this.Role) + `,`,
+		`Attachments:` + strings.Replace(fmt.Sprintf("%v", this.Attachments), "NetworkAttachment", "NetworkAttachment", 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -5017,6 +5049,37 @@
 					break
 				}
 			}
+		case 10:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Attachments", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowObjects
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthObjects
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Attachments = append(m.Attachments, &NetworkAttachment{})
+			if err := m.Attachments[len(m.Attachments)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipObjects(dAtA[iNdEx:])
@@ -7686,102 +7749,104 @@
 	ErrIntOverflowObjects   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("objects.proto", fileDescriptorObjects) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/objects.proto", fileDescriptorObjects) }
 
 var fileDescriptorObjects = []byte{
-	// 1491 bytes of a gzipped FileDescriptorProto
+	// 1527 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcf, 0x6f, 0x1b, 0x4f,
 	0x15, 0xef, 0xda, 0x1b, 0xff, 0x78, 0x4e, 0x4c, 0x98, 0x86, 0xb0, 0x35, 0xc1, 0x0e, 0xae, 0x40,
-	0x15, 0xaa, 0x9c, 0x12, 0x0a, 0x4a, 0x03, 0xa5, 0xb5, 0x93, 0xa8, 0xb5, 0x4a, 0x69, 0x34, 0x2d,
-	0x2d, 0xb7, 0x65, 0xb2, 0x3b, 0x75, 0x17, 0xaf, 0x77, 0x56, 0x3b, 0x63, 0x17, 0xdf, 0x38, 0x87,
-	0x3f, 0x20, 0x37, 0x0e, 0xfd, 0x17, 0xe0, 0xc2, 0x85, 0x03, 0xa7, 0x1e, 0x39, 0x21, 0x4e, 0x11,
-	0xf5, 0x7f, 0x81, 0xc4, 0xe1, 0xab, 0x99, 0x9d, 0xb5, 0x37, 0xf1, 0x3a, 0x49, 0xbf, 0xaa, 0xa2,
-	0xef, 0x29, 0x33, 0x3b, 0x9f, 0xcf, 0x9b, 0xf7, 0xde, 0xbc, 0x5f, 0x31, 0xac, 0xb0, 0xa3, 0x3f,
-	0x50, 0x47, 0xf0, 0x56, 0x18, 0x31, 0xc1, 0x10, 0x72, 0x99, 0xd3, 0xa7, 0x51, 0x8b, 0xbf, 0x27,
-	0xd1, 0xa0, 0xef, 0x89, 0xd6, 0xe8, 0x27, 0xb5, 0x8a, 0x18, 0x87, 0x54, 0x03, 0x6a, 0x15, 0x1e,
-	0x52, 0x27, 0xd9, 0x34, 0x7a, 0x8c, 0xf5, 0x7c, 0xba, 0xa5, 0x76, 0x47, 0xc3, 0xb7, 0x5b, 0xc2,
-	0x1b, 0x50, 0x2e, 0xc8, 0x20, 0xd4, 0x80, 0xb5, 0x1e, 0xeb, 0x31, 0xb5, 0xdc, 0x92, 0x2b, 0xfd,
-	0xf5, 0xd6, 0x79, 0x1a, 0x09, 0xc6, 0xfa, 0xe8, 0x66, 0xe8, 0x0f, 0x7b, 0x5e, 0xb0, 0x15, 0xff,
-	0x89, 0x3f, 0x36, 0xff, 0x6e, 0x80, 0xf9, 0x9c, 0x0a, 0x82, 0x7e, 0x01, 0xc5, 0x11, 0x8d, 0xb8,
-	0xc7, 0x02, 0xcb, 0xd8, 0x34, 0xee, 0x54, 0xb6, 0xbf, 0xd7, 0x9a, 0xd7, 0xb7, 0xf5, 0x3a, 0x86,
-	0x74, 0xcc, 0x8f, 0xa7, 0x8d, 0x1b, 0x38, 0x61, 0xa0, 0x07, 0x00, 0x4e, 0x44, 0x89, 0xa0, 0xae,
-	0x4d, 0x84, 0x95, 0x53, 0xfc, 0x5a, 0x2b, 0x56, 0xa5, 0x95, 0xa8, 0xd2, 0x7a, 0x95, 0x58, 0x80,
-	0xcb, 0x1a, 0xdd, 0x16, 0x92, 0x3a, 0x0c, 0xdd, 0x84, 0x9a, 0xbf, 0x9c, 0xaa, 0xd1, 0x6d, 0xd1,
-	0xfc, 0xab, 0x09, 0xe6, 0x6f, 0x98, 0x4b, 0xd1, 0x3a, 0xe4, 0x3c, 0x57, 0xa9, 0x5d, 0xee, 0x14,
-	0x26, 0xa7, 0x8d, 0x5c, 0x77, 0x1f, 0xe7, 0x3c, 0x17, 0x6d, 0x83, 0x39, 0xa0, 0x82, 0x68, 0x85,
-	0xac, 0x2c, 0x83, 0xa4, 0xed, 0xda, 0x1a, 0x85, 0x45, 0x3f, 0x07, 0x53, 0x3e, 0x83, 0xd6, 0x64,
-	0x23, 0x8b, 0x23, 0xef, 0x7c, 0x19, 0x52, 0x27, 0xe1, 0x49, 0x3c, 0x3a, 0x80, 0x8a, 0x4b, 0xb9,
-	0x13, 0x79, 0xa1, 0x90, 0x3e, 0x34, 0x15, 0xfd, 0xf6, 0x22, 0xfa, 0xfe, 0x0c, 0x8a, 0xd3, 0x3c,
-	0xf4, 0x4b, 0x28, 0x70, 0x41, 0xc4, 0x90, 0x5b, 0x4b, 0x4a, 0x42, 0x7d, 0xa1, 0x02, 0x0a, 0xa5,
-	0x55, 0xd0, 0x1c, 0xf4, 0x14, 0xaa, 0x03, 0x12, 0x90, 0x1e, 0x8d, 0x6c, 0x2d, 0xa5, 0xa0, 0xa4,
-	0xfc, 0x20, 0xd3, 0xf4, 0x18, 0x19, 0x0b, 0xc2, 0x2b, 0x83, 0xf4, 0x16, 0x1d, 0x00, 0x10, 0x21,
-	0x88, 0xf3, 0x6e, 0x40, 0x03, 0x61, 0x15, 0x95, 0x94, 0x1f, 0x66, 0xea, 0x42, 0xc5, 0x7b, 0x16,
-	0xf5, 0xdb, 0x53, 0x30, 0x4e, 0x11, 0xd1, 0x13, 0xa8, 0x38, 0x34, 0x12, 0xde, 0x5b, 0xcf, 0x21,
-	0x82, 0x5a, 0x25, 0x25, 0xa7, 0x91, 0x25, 0x67, 0x6f, 0x06, 0xd3, 0x46, 0xa5, 0x99, 0xe8, 0x1e,
-	0x98, 0x11, 0xf3, 0xa9, 0x55, 0xde, 0x34, 0xee, 0x54, 0x17, 0x3f, 0x0b, 0x66, 0x3e, 0xc5, 0x0a,
-	0xb9, 0xbb, 0x7e, 0x7c, 0xd2, 0x44, 0xb0, 0x5a, 0x32, 0x56, 0x0d, 0x15, 0x1a, 0xc6, 0x3d, 0xe3,
-	0x77, 0xc6, 0xef, 0x8d, 0xe6, 0xff, 0xf3, 0x50, 0x7c, 0x49, 0xa3, 0x91, 0xe7, 0x7c, 0xd9, 0xc0,
-	0x79, 0x70, 0x26, 0x70, 0x32, 0x6d, 0xd4, 0xd7, 0xce, 0xc5, 0xce, 0x0e, 0x94, 0x68, 0xe0, 0x86,
-	0xcc, 0x0b, 0x84, 0x0e, 0x9c, 0x4c, 0x03, 0x0f, 0x34, 0x06, 0x4f, 0xd1, 0xe8, 0x00, 0x56, 0xe2,
-	0x7c, 0xb0, 0xcf, 0x44, 0xcd, 0x66, 0x16, 0xfd, 0xb7, 0x0a, 0xa8, 0x9f, 0x7b, 0x79, 0x98, 0xda,
-	0xa1, 0x7d, 0x58, 0x09, 0x23, 0x3a, 0xf2, 0xd8, 0x90, 0xdb, 0xca, 0x88, 0xc2, 0x95, 0x8c, 0xc0,
-	0xcb, 0x09, 0x4b, 0xee, 0xd0, 0xaf, 0x60, 0x59, 0x92, 0xed, 0xa4, 0x8e, 0xc0, 0xa5, 0x75, 0x04,
-	0xab, 0x92, 0xa7, 0x37, 0xe8, 0x05, 0x7c, 0xe7, 0x8c, 0x16, 0x53, 0x41, 0x95, 0xcb, 0x05, 0xdd,
-	0x4c, 0x6b, 0xa2, 0x3f, 0xee, 0xa2, 0xe3, 0x93, 0x66, 0x15, 0x96, 0xd3, 0x21, 0xd0, 0xfc, 0x4b,
-	0x0e, 0x4a, 0x89, 0x23, 0xd1, 0x7d, 0xfd, 0x66, 0xc6, 0x62, 0xaf, 0x25, 0x58, 0x65, 0x6f, 0xfc,
-	0x5c, 0xf7, 0x61, 0x29, 0x64, 0x91, 0xe0, 0x56, 0x6e, 0x33, 0xbf, 0x28, 0x45, 0x0f, 0x59, 0x24,
-	0xf6, 0x58, 0xf0, 0xd6, 0xeb, 0xe1, 0x18, 0x8c, 0xde, 0x40, 0x65, 0xe4, 0x45, 0x62, 0x48, 0x7c,
-	0xdb, 0x0b, 0xb9, 0x95, 0x57, 0xdc, 0x1f, 0x5d, 0x74, 0x65, 0xeb, 0x75, 0x8c, 0xef, 0x1e, 0x76,
-	0xaa, 0x93, 0xd3, 0x06, 0x4c, 0xb7, 0x1c, 0x83, 0x16, 0xd5, 0x0d, 0x79, 0xed, 0x39, 0x94, 0xa7,
-	0x27, 0xe8, 0x2e, 0x40, 0x10, 0x67, 0xa4, 0x3d, 0x8d, 0xec, 0x95, 0xc9, 0x69, 0xa3, 0xac, 0xf3,
-	0xb4, 0xbb, 0x8f, 0xcb, 0x1a, 0xd0, 0x75, 0x11, 0x02, 0x93, 0xb8, 0x6e, 0xa4, 0xe2, 0xbc, 0x8c,
-	0xd5, 0xba, 0xf9, 0xe7, 0x22, 0x98, 0xaf, 0x08, 0xef, 0x5f, 0x77, 0x55, 0x95, 0x77, 0xce, 0x65,
-	0xc6, 0x5d, 0x00, 0x1e, 0xc7, 0x9b, 0x34, 0xc7, 0x9c, 0x99, 0xa3, 0xa3, 0x50, 0x9a, 0xa3, 0x01,
-	0xb1, 0x39, 0xdc, 0x67, 0x42, 0x25, 0x81, 0x89, 0xd5, 0x1a, 0xdd, 0x86, 0x62, 0xc0, 0x5c, 0x45,
-	0x2f, 0x28, 0x3a, 0x4c, 0x4e, 0x1b, 0x05, 0x59, 0x2b, 0xba, 0xfb, 0xb8, 0x20, 0x8f, 0xba, 0xae,
-	0x2c, 0x53, 0x24, 0x08, 0x98, 0x20, 0xb2, 0x06, 0x73, 0x5d, 0xee, 0x32, 0xa3, 0xbf, 0x3d, 0x83,
-	0x25, 0x65, 0x2a, 0xc5, 0x44, 0xaf, 0xe1, 0x66, 0xa2, 0x6f, 0x5a, 0x60, 0xe9, 0x73, 0x04, 0x22,
-	0x2d, 0x21, 0x75, 0x92, 0x6a, 0x0b, 0xe5, 0xc5, 0x6d, 0x41, 0x79, 0x30, 0xab, 0x2d, 0x74, 0x60,
-	0xc5, 0xa5, 0xdc, 0x8b, 0xa8, 0xab, 0xca, 0x04, 0x55, 0x99, 0x59, 0xdd, 0xfe, 0xfe, 0x45, 0x42,
-	0x28, 0x5e, 0xd6, 0x1c, 0xb5, 0x43, 0x6d, 0x28, 0xe9, 0xb8, 0xe1, 0x56, 0x45, 0xc5, 0xee, 0x15,
-	0xdb, 0xc1, 0x94, 0x76, 0xa6, 0xcc, 0x2d, 0x7f, 0x56, 0x99, 0x7b, 0x00, 0xe0, 0xb3, 0x9e, 0xed,
-	0x46, 0xde, 0x88, 0x46, 0xd6, 0x8a, 0x1e, 0x12, 0x32, 0xb8, 0xfb, 0x0a, 0x81, 0xcb, 0x3e, 0xeb,
-	0xc5, 0xcb, 0xb9, 0xa2, 0x54, 0xfd, 0xcc, 0xa2, 0x44, 0xa0, 0x46, 0x38, 0xf7, 0x7a, 0x01, 0x75,
-	0xed, 0x1e, 0x0d, 0x68, 0xe4, 0x39, 0x76, 0x44, 0x39, 0x1b, 0x46, 0x0e, 0xe5, 0xd6, 0xb7, 0x94,
-	0x27, 0x32, 0xdb, 0xfc, 0x93, 0x18, 0x8c, 0x35, 0x16, 0x5b, 0x89, 0x98, 0x73, 0x07, 0x7c, 0xb7,
-	0x76, 0x7c, 0xd2, 0x5c, 0x87, 0xb5, 0x74, 0x99, 0xda, 0x31, 0x1e, 0x1b, 0x4f, 0x8d, 0x43, 0xa3,
-	0xf9, 0xcf, 0x1c, 0x7c, 0x7b, 0xce, 0xa7, 0xe8, 0x67, 0x50, 0xd4, 0x5e, 0xbd, 0x68, 0x58, 0xd3,
-	0x3c, 0x9c, 0x60, 0xd1, 0x06, 0x94, 0x65, 0x8a, 0x53, 0xce, 0x69, 0x5c, 0xbc, 0xca, 0x78, 0xf6,
-	0x01, 0x59, 0x50, 0x24, 0xbe, 0x47, 0xe4, 0x59, 0x5e, 0x9d, 0x25, 0x5b, 0x34, 0x84, 0xf5, 0xd8,
-	0xf5, 0xf6, 0xac, 0xb5, 0xdb, 0x2c, 0x14, 0xdc, 0x32, 0x95, 0xfd, 0x8f, 0xae, 0x14, 0x09, 0xfa,
-	0x71, 0x66, 0x1f, 0x5e, 0x84, 0x82, 0x1f, 0x04, 0x22, 0x1a, 0xe3, 0x35, 0x37, 0xe3, 0xa8, 0xf6,
-	0x04, 0x6e, 0x2d, 0xa4, 0xa0, 0x55, 0xc8, 0xf7, 0xe9, 0x38, 0x2e, 0x4f, 0x58, 0x2e, 0xd1, 0x1a,
-	0x2c, 0x8d, 0x88, 0x3f, 0xa4, 0xba, 0x9a, 0xc5, 0x9b, 0xdd, 0xdc, 0x8e, 0xd1, 0xfc, 0x90, 0x83,
-	0xa2, 0x56, 0xe7, 0xba, 0x5b, 0xbe, 0xbe, 0x76, 0xae, 0xb0, 0x3d, 0x84, 0x65, 0xed, 0xd2, 0x38,
-	0x23, 0xcd, 0x4b, 0x63, 0xba, 0x12, 0xe3, 0xe3, 0x6c, 0x7c, 0x08, 0xa6, 0x17, 0x92, 0x81, 0x6e,
-	0xf7, 0x99, 0x37, 0x77, 0x0f, 0xdb, 0xcf, 0x5f, 0x84, 0x71, 0x61, 0x29, 0x4d, 0x4e, 0x1b, 0xa6,
-	0xfc, 0x80, 0x15, 0x2d, 0xb3, 0x31, 0xfe, 0x6d, 0x09, 0x8a, 0x7b, 0xfe, 0x90, 0x0b, 0x1a, 0x5d,
-	0xb7, 0x93, 0xf4, 0xb5, 0x73, 0x4e, 0xda, 0x83, 0x62, 0xc4, 0x98, 0xb0, 0x1d, 0x72, 0x91, 0x7f,
-	0x30, 0x63, 0x62, 0xaf, 0xdd, 0xa9, 0x4a, 0xa2, 0xac, 0xed, 0xf1, 0x1e, 0x17, 0x24, 0x75, 0x8f,
-	0xa0, 0x37, 0xb0, 0x9e, 0x74, 0xc4, 0x23, 0xc6, 0x04, 0x17, 0x11, 0x09, 0xed, 0x3e, 0x1d, 0xcb,
-	0x59, 0x29, 0xbf, 0x68, 0x36, 0x3e, 0x08, 0x9c, 0x68, 0xac, 0x9c, 0xf7, 0x8c, 0x8e, 0xf1, 0x9a,
-	0x16, 0xd0, 0x49, 0xf8, 0xcf, 0xe8, 0x98, 0xa3, 0x47, 0xb0, 0x41, 0xa7, 0x30, 0x29, 0xd1, 0xf6,
-	0xc9, 0x40, 0xf6, 0x7a, 0xdb, 0xf1, 0x99, 0xd3, 0x57, 0xed, 0xc6, 0xc4, 0xb7, 0x68, 0x5a, 0xd4,
-	0xaf, 0x63, 0xc4, 0x9e, 0x04, 0x20, 0x0e, 0xd6, 0x91, 0x4f, 0x9c, 0xbe, 0xef, 0x71, 0xf9, 0xef,
-	0x4f, 0x6a, 0xdc, 0x95, 0x1d, 0x43, 0xea, 0xb6, 0x73, 0x81, 0xb7, 0x5a, 0x9d, 0x19, 0x37, 0x35,
-	0x3c, 0xeb, 0x8c, 0xfa, 0xee, 0x51, 0xf6, 0x29, 0xea, 0x40, 0x65, 0x18, 0xc8, 0xeb, 0x63, 0x1f,
-	0x94, 0xaf, 0xea, 0x03, 0x88, 0x59, 0xd2, 0xf2, 0xda, 0x08, 0x36, 0x2e, 0xba, 0x3c, 0x23, 0x37,
-	0x1f, 0xa7, 0x73, 0xb3, 0xb2, 0xfd, 0xe3, 0xac, 0xfb, 0xb2, 0x45, 0xa6, 0xf2, 0x38, 0x33, 0x6c,
-	0xff, 0x61, 0x40, 0xe1, 0x25, 0x75, 0x22, 0x2a, 0xbe, 0x68, 0xd4, 0xee, 0x9c, 0x89, 0xda, 0x7a,
-	0xf6, 0x20, 0x2c, 0x6f, 0x9d, 0x0b, 0xda, 0x1a, 0x94, 0xbc, 0x40, 0xd0, 0x28, 0x20, 0xbe, 0x8a,
-	0xda, 0x12, 0x9e, 0xee, 0x33, 0x0d, 0xf8, 0x60, 0x40, 0x21, 0x9e, 0x14, 0xaf, 0xdb, 0x80, 0xf8,
-	0xd6, 0xf3, 0x06, 0x64, 0x2a, 0xf9, 0x3f, 0x03, 0x4a, 0x49, 0xc3, 0xfa, 0xa2, 0x6a, 0x9e, 0x9b,
-	0xbc, 0xf2, 0x5f, 0x7b, 0xf2, 0x42, 0x60, 0xf6, 0xbd, 0x40, 0xcf, 0x88, 0x58, 0xad, 0x51, 0x0b,
-	0x8a, 0x21, 0x19, 0xfb, 0x8c, 0xb8, 0xba, 0x50, 0xae, 0xcd, 0xfd, 0xb0, 0xd0, 0x0e, 0xc6, 0x38,
-	0x01, 0xed, 0xae, 0x1d, 0x9f, 0x34, 0x57, 0xa1, 0x9a, 0xb6, 0xfc, 0x9d, 0xd1, 0xfc, 0xb7, 0x01,
-	0xe5, 0x83, 0x3f, 0x0a, 0x1a, 0xa8, 0x79, 0xe0, 0x1b, 0x69, 0xfc, 0xe6, 0xfc, 0x8f, 0x0f, 0xe5,
-	0x33, 0xbf, 0x2b, 0x64, 0x3d, 0x6a, 0xc7, 0xfa, 0xf8, 0xa9, 0x7e, 0xe3, 0x3f, 0x9f, 0xea, 0x37,
-	0xfe, 0x34, 0xa9, 0x1b, 0x1f, 0x27, 0x75, 0xe3, 0x5f, 0x93, 0xba, 0xf1, 0xdf, 0x49, 0xdd, 0x38,
-	0x2a, 0x28, 0xff, 0xfc, 0xf4, 0xab, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x48, 0xcb, 0x39, 0xc2,
-	0x12, 0x00, 0x00,
+	0x55, 0x55, 0x39, 0x25, 0x14, 0x48, 0x03, 0xa5, 0xb5, 0x93, 0xa8, 0xb5, 0x4a, 0x69, 0x34, 0x2d,
+	0x2d, 0xb7, 0x65, 0xb2, 0x3b, 0x75, 0x17, 0xaf, 0x77, 0x56, 0x3b, 0x63, 0x17, 0xdf, 0x7a, 0x0e,
+	0x7f, 0x40, 0x6e, 0x1c, 0xfa, 0x37, 0x70, 0xe1, 0xc2, 0x81, 0x53, 0x8f, 0x9c, 0x10, 0xa7, 0x88,
+	0xfa, 0xbf, 0x40, 0xe2, 0x80, 0x66, 0x76, 0xd6, 0xde, 0xc4, 0x9b, 0x5f, 0xa8, 0x8a, 0xbe, 0xa7,
+	0xcc, 0xec, 0x7c, 0x3e, 0xef, 0xd7, 0xbc, 0xf7, 0xe6, 0xc5, 0x70, 0xaf, 0xe7, 0x89, 0xf7, 0xc3,
+	0x83, 0x96, 0xc3, 0x06, 0x1b, 0x2e, 0x73, 0xfa, 0x34, 0xda, 0xe0, 0x1f, 0x48, 0x34, 0xe8, 0x7b,
+	0x62, 0x83, 0x84, 0xde, 0x06, 0x3b, 0xf8, 0x03, 0x75, 0x04, 0x6f, 0x85, 0x11, 0x13, 0x0c, 0xa1,
+	0x18, 0xd2, 0x4a, 0x20, 0xad, 0xd1, 0x8f, 0x6b, 0x77, 0x2f, 0x90, 0x20, 0xc6, 0x21, 0xd5, 0xfc,
+	0x0b, 0xb1, 0x3c, 0xa4, 0x4e, 0x82, 0x6d, 0xf4, 0x18, 0xeb, 0xf9, 0x74, 0x43, 0xed, 0x0e, 0x86,
+	0xef, 0x36, 0x84, 0x37, 0xa0, 0x5c, 0x90, 0x41, 0xa8, 0x01, 0x2b, 0x3d, 0xd6, 0x63, 0x6a, 0xb9,
+	0x21, 0x57, 0xfa, 0xeb, 0xad, 0xd3, 0x34, 0x12, 0x8c, 0xf5, 0xd1, 0xcf, 0xcf, 0xd1, 0x3e, 0x85,
+	0x87, 0xfe, 0xb0, 0xe7, 0x05, 0xfa, 0x4f, 0x4c, 0x6c, 0xfe, 0xd5, 0x00, 0xf3, 0x05, 0x15, 0x04,
+	0xfd, 0x02, 0x8a, 0x23, 0x1a, 0x71, 0x8f, 0x05, 0x96, 0xb1, 0x6e, 0xdc, 0xa9, 0x6c, 0x7e, 0xaf,
+	0x35, 0x1f, 0x91, 0xd6, 0x9b, 0x18, 0xd2, 0x31, 0x3f, 0x1f, 0x37, 0x6e, 0xe0, 0x84, 0x81, 0x1e,
+	0x02, 0x38, 0x11, 0x25, 0x82, 0xba, 0x36, 0x11, 0x56, 0x4e, 0xf1, 0x6b, 0xad, 0xd8, 0xdc, 0x56,
+	0xa2, 0xbf, 0xf5, 0x3a, 0xf1, 0x12, 0x97, 0x35, 0xba, 0x2d, 0x24, 0x75, 0x18, 0xba, 0x09, 0x35,
+	0x7f, 0x31, 0x55, 0xa3, 0xdb, 0xa2, 0xf9, 0x71, 0x01, 0xcc, 0xdf, 0x30, 0x97, 0xa2, 0x55, 0xc8,
+	0x79, 0xae, 0x32, 0xbb, 0xdc, 0x29, 0x4c, 0x8e, 0x1b, 0xb9, 0xee, 0x2e, 0xce, 0x79, 0x2e, 0xda,
+	0x04, 0x73, 0x40, 0x05, 0xd1, 0x06, 0x59, 0x59, 0x0e, 0x49, 0xdf, 0xb5, 0x37, 0x0a, 0x8b, 0x7e,
+	0x06, 0xa6, 0xbc, 0x2a, 0x6d, 0xc9, 0x5a, 0x16, 0x47, 0xea, 0x7c, 0x15, 0x52, 0x27, 0xe1, 0x49,
+	0x3c, 0xda, 0x83, 0x8a, 0x4b, 0xb9, 0x13, 0x79, 0xa1, 0x90, 0x31, 0x34, 0x15, 0xfd, 0xf6, 0x59,
+	0xf4, 0xdd, 0x19, 0x14, 0xa7, 0x79, 0xe8, 0x97, 0x50, 0xe0, 0x82, 0x88, 0x21, 0xb7, 0x16, 0x94,
+	0x84, 0xfa, 0x99, 0x06, 0x28, 0x94, 0x36, 0x41, 0x73, 0xd0, 0x33, 0xa8, 0x0e, 0x48, 0x40, 0x7a,
+	0x34, 0xb2, 0xb5, 0x94, 0x82, 0x92, 0xf2, 0x83, 0x4c, 0xd7, 0x63, 0x64, 0x2c, 0x08, 0x2f, 0x0d,
+	0xd2, 0x5b, 0xd4, 0x05, 0x20, 0x42, 0x10, 0xe7, 0xfd, 0x80, 0x06, 0xc2, 0x2a, 0x2a, 0x29, 0x3f,
+	0xcc, 0xb4, 0x85, 0x8a, 0x0f, 0x2c, 0xea, 0xb7, 0xa7, 0xe0, 0x4e, 0xce, 0x32, 0x70, 0x8a, 0x8c,
+	0x9e, 0x42, 0xc5, 0xa1, 0x91, 0xf0, 0xde, 0x79, 0x0e, 0x11, 0xd4, 0x2a, 0x29, 0x59, 0x8d, 0x2c,
+	0x59, 0x3b, 0x33, 0x98, 0x76, 0x2c, 0xcd, 0x44, 0xf7, 0xc1, 0x8c, 0x98, 0x4f, 0xad, 0xf2, 0xba,
+	0x71, 0xa7, 0x7a, 0xf6, 0xd5, 0x60, 0xe6, 0x53, 0xac, 0x90, 0x52, 0xf5, 0xcc, 0x10, 0x6e, 0xc1,
+	0x7a, 0xfe, 0xd2, 0x6e, 0xe0, 0x34, 0x73, 0x7b, 0xf5, 0xf0, 0xa8, 0x89, 0x60, 0xb9, 0x64, 0x2c,
+	0x1b, 0x2a, 0xcf, 0x8c, 0xfb, 0xc6, 0xef, 0x8c, 0xdf, 0x1b, 0xcd, 0xff, 0xe6, 0xa1, 0xf8, 0x8a,
+	0x46, 0x23, 0xcf, 0xf9, 0xba, 0x59, 0xf8, 0xf0, 0x44, 0x16, 0x66, 0x06, 0x4b, 0xab, 0x9d, 0x4b,
+	0xc4, 0x2d, 0x28, 0xd1, 0xc0, 0x0d, 0x99, 0x17, 0x08, 0x9d, 0x85, 0x99, 0x91, 0xda, 0xd3, 0x18,
+	0x3c, 0x45, 0xa3, 0x3d, 0x58, 0x8a, 0x8b, 0xcb, 0x3e, 0x91, 0x82, 0xeb, 0x59, 0xf4, 0xdf, 0x2a,
+	0xa0, 0xce, 0x9d, 0xc5, 0x61, 0x6a, 0x87, 0x76, 0x61, 0x29, 0x8c, 0xe8, 0xc8, 0x63, 0x43, 0x6e,
+	0x2b, 0x27, 0x0a, 0x97, 0x72, 0x02, 0x2f, 0x26, 0x2c, 0xb9, 0x43, 0xbf, 0x82, 0x45, 0x49, 0xb6,
+	0x93, 0xa6, 0x04, 0x17, 0x36, 0x25, 0x5c, 0x91, 0x04, 0xbd, 0x41, 0x2f, 0xe1, 0x3b, 0x27, 0xac,
+	0x98, 0x0a, 0xaa, 0x5c, 0x2c, 0xe8, 0x66, 0xda, 0x12, 0xfd, 0x71, 0x1b, 0x1d, 0x1e, 0x35, 0xab,
+	0xb0, 0x98, 0x4e, 0x81, 0xe6, 0x9f, 0x73, 0x50, 0x4a, 0x02, 0x89, 0x1e, 0xe8, 0x3b, 0x33, 0xce,
+	0x8e, 0x5a, 0x82, 0x55, 0xfe, 0xc6, 0xd7, 0xf5, 0x00, 0x16, 0x42, 0x16, 0x09, 0x6e, 0xe5, 0x54,
+	0x72, 0x66, 0xd6, 0xfb, 0x3e, 0x8b, 0xc4, 0x0e, 0x0b, 0xde, 0x79, 0x3d, 0x1c, 0x83, 0xd1, 0x5b,
+	0xa8, 0x8c, 0xbc, 0x48, 0x0c, 0x89, 0x6f, 0x7b, 0x21, 0xb7, 0xf2, 0x8a, 0xfb, 0xa3, 0xf3, 0x54,
+	0xb6, 0xde, 0xc4, 0xf8, 0xee, 0x7e, 0xa7, 0x3a, 0x39, 0x6e, 0xc0, 0x74, 0xcb, 0x31, 0x68, 0x51,
+	0xdd, 0x90, 0xd7, 0x5e, 0x40, 0x79, 0x7a, 0x82, 0xee, 0x01, 0x04, 0x71, 0x5d, 0xd8, 0xd3, 0xcc,
+	0x5e, 0x9a, 0x1c, 0x37, 0xca, 0xba, 0x5a, 0xba, 0xbb, 0xb8, 0xac, 0x01, 0x5d, 0x17, 0x21, 0x30,
+	0x89, 0xeb, 0x46, 0x2a, 0xcf, 0xcb, 0x58, 0xad, 0x9b, 0x7f, 0x2a, 0x82, 0xf9, 0x9a, 0xf0, 0xfe,
+	0x75, 0xb7, 0x68, 0xa9, 0x73, 0xae, 0x32, 0xee, 0x01, 0xf0, 0x38, 0xdf, 0xa4, 0x3b, 0xe6, 0xcc,
+	0x1d, 0x9d, 0x85, 0xd2, 0x1d, 0x0d, 0x88, 0xdd, 0xe1, 0x3e, 0x13, 0xaa, 0x08, 0x4c, 0xac, 0xd6,
+	0xe8, 0x36, 0x14, 0x03, 0xe6, 0x2a, 0x7a, 0x41, 0xd1, 0x61, 0x72, 0xdc, 0x28, 0xc8, 0xa6, 0xd3,
+	0xdd, 0xc5, 0x05, 0x79, 0xd4, 0x75, 0x55, 0xd3, 0x09, 0x02, 0x26, 0x88, 0x6c, 0xe8, 0x5c, 0xf7,
+	0xce, 0xcc, 0xec, 0x6f, 0xcf, 0x60, 0x49, 0xbf, 0x4b, 0x31, 0xd1, 0x1b, 0xb8, 0x99, 0xd8, 0x9b,
+	0x16, 0x58, 0xba, 0x8a, 0x40, 0xa4, 0x25, 0xa4, 0x4e, 0x52, 0x6f, 0x4c, 0xf9, 0xec, 0x37, 0x46,
+	0x45, 0x30, 0xeb, 0x8d, 0xe9, 0xc0, 0x92, 0x4b, 0xb9, 0x17, 0x51, 0x57, 0xb5, 0x09, 0xaa, 0x2a,
+	0xb3, 0xba, 0xf9, 0xfd, 0xf3, 0x84, 0x50, 0xbc, 0xa8, 0x39, 0x6a, 0x87, 0xda, 0x50, 0xd2, 0x79,
+	0xc3, 0xad, 0xca, 0x55, 0x9a, 0xf2, 0x94, 0x76, 0xa2, 0xcd, 0x2d, 0x5e, 0xa9, 0xcd, 0x3d, 0x04,
+	0xf0, 0x59, 0xcf, 0x76, 0x23, 0x6f, 0x44, 0x23, 0x6b, 0x49, 0x4f, 0x1c, 0x19, 0xdc, 0x5d, 0x85,
+	0xc0, 0x65, 0x9f, 0xf5, 0xe2, 0xe5, 0x5c, 0x53, 0xaa, 0x5e, 0xb1, 0x29, 0x11, 0xa8, 0x11, 0xce,
+	0xbd, 0x5e, 0x40, 0x5d, 0xbb, 0x47, 0x03, 0x1a, 0x79, 0x8e, 0x1d, 0x51, 0xce, 0x86, 0x91, 0x43,
+	0xb9, 0xf5, 0x2d, 0x15, 0x89, 0xcc, 0x99, 0xe1, 0x69, 0x0c, 0xc6, 0x1a, 0x8b, 0xad, 0x44, 0xcc,
+	0xa9, 0x03, 0xbe, 0x5d, 0x3b, 0x3c, 0x6a, 0xae, 0xc2, 0x4a, 0xba, 0x4d, 0x6d, 0x19, 0x4f, 0x8c,
+	0x67, 0xc6, 0xbe, 0xd1, 0xfc, 0x7b, 0x0e, 0xbe, 0x3d, 0x17, 0x53, 0xf4, 0x53, 0x28, 0xea, 0xa8,
+	0x9e, 0x37, 0xf9, 0x69, 0x1e, 0x4e, 0xb0, 0x68, 0x0d, 0xca, 0xb2, 0xc4, 0x29, 0xe7, 0x34, 0x6e,
+	0x5e, 0x65, 0x3c, 0xfb, 0x80, 0x2c, 0x28, 0x12, 0xdf, 0x23, 0xf2, 0x2c, 0xaf, 0xce, 0x92, 0x2d,
+	0x1a, 0xc2, 0x6a, 0x1c, 0x7a, 0x7b, 0xf6, 0xc0, 0xda, 0x2c, 0x14, 0xdc, 0x32, 0x95, 0xff, 0x8f,
+	0x2f, 0x95, 0x09, 0xfa, 0x72, 0x66, 0x1f, 0x5e, 0x86, 0x82, 0xef, 0x05, 0x22, 0x1a, 0xe3, 0x15,
+	0x37, 0xe3, 0xa8, 0xf6, 0x14, 0x6e, 0x9d, 0x49, 0x41, 0xcb, 0x90, 0xef, 0xd3, 0x71, 0xdc, 0x9e,
+	0xb0, 0x5c, 0xa2, 0x15, 0x58, 0x18, 0x11, 0x7f, 0x48, 0x75, 0x37, 0x8b, 0x37, 0xdb, 0xb9, 0x2d,
+	0xa3, 0xf9, 0x29, 0x07, 0x45, 0x6d, 0xce, 0x75, 0x3f, 0xf9, 0x5a, 0xed, 0x5c, 0x63, 0x7b, 0x04,
+	0x8b, 0x3a, 0xa4, 0x71, 0x45, 0x9a, 0x17, 0xe6, 0x74, 0x25, 0xc6, 0xc7, 0xd5, 0xf8, 0x08, 0x4c,
+	0x2f, 0x24, 0x03, 0xfd, 0xdc, 0x67, 0x6a, 0xee, 0xee, 0xb7, 0x5f, 0xbc, 0x0c, 0xe3, 0xc6, 0x52,
+	0x9a, 0x1c, 0x37, 0x4c, 0xf9, 0x01, 0x2b, 0x5a, 0xe6, 0xc3, 0xf8, 0x97, 0x05, 0x28, 0xee, 0xf8,
+	0x43, 0x2e, 0x68, 0x74, 0xdd, 0x41, 0xd2, 0x6a, 0xe7, 0x82, 0xb4, 0x03, 0xc5, 0x88, 0x31, 0x61,
+	0x3b, 0xe4, 0xbc, 0xf8, 0x60, 0xc6, 0xc4, 0x4e, 0xbb, 0x53, 0x95, 0x44, 0xd9, 0xdb, 0xe3, 0x3d,
+	0x2e, 0x48, 0xea, 0x0e, 0x41, 0x6f, 0x61, 0x35, 0x79, 0x11, 0x0f, 0x18, 0x13, 0x5c, 0x44, 0x24,
+	0xb4, 0xfb, 0x74, 0x2c, 0x67, 0xa5, 0xfc, 0x59, 0x83, 0xf6, 0x5e, 0xe0, 0x44, 0x63, 0x15, 0xbc,
+	0xe7, 0x74, 0x8c, 0x57, 0xb4, 0x80, 0x4e, 0xc2, 0x7f, 0x4e, 0xc7, 0x1c, 0x3d, 0x86, 0x35, 0x3a,
+	0x85, 0x49, 0x89, 0xb6, 0x4f, 0x06, 0xf2, 0xad, 0xb7, 0x1d, 0x9f, 0x39, 0x7d, 0xf5, 0xdc, 0x98,
+	0xf8, 0x16, 0x4d, 0x8b, 0xfa, 0x75, 0x8c, 0xd8, 0x91, 0x00, 0xc4, 0xc1, 0x3a, 0xf0, 0x89, 0xd3,
+	0xf7, 0x3d, 0x2e, 0xff, 0x97, 0x4a, 0xcd, 0xcd, 0xf2, 0xc5, 0x90, 0xb6, 0x6d, 0x9d, 0x13, 0xad,
+	0x56, 0x67, 0xc6, 0x4d, 0x4d, 0xe1, 0xba, 0xa2, 0xbe, 0x7b, 0x90, 0x7d, 0x8a, 0x3a, 0x50, 0x19,
+	0x06, 0x52, 0x7d, 0x1c, 0x83, 0xf2, 0x65, 0x63, 0x00, 0x31, 0x4b, 0x7a, 0x5e, 0x1b, 0xc1, 0xda,
+	0x79, 0xca, 0x33, 0x6a, 0xf3, 0x49, 0xba, 0x36, 0x2b, 0x9b, 0x77, 0xb3, 0xf4, 0x65, 0x8b, 0x4c,
+	0xd5, 0x71, 0x66, 0xda, 0xfe, 0xcd, 0x80, 0xc2, 0x2b, 0xea, 0x44, 0x54, 0x7c, 0xd5, 0xac, 0xdd,
+	0x3a, 0x91, 0xb5, 0xf5, 0xec, 0x41, 0x58, 0x6a, 0x9d, 0x4b, 0xda, 0x1a, 0x94, 0xbc, 0x40, 0xd0,
+	0x28, 0x20, 0xbe, 0xca, 0xda, 0x12, 0x9e, 0xee, 0x33, 0x1d, 0xf8, 0x64, 0x40, 0x21, 0x9e, 0x14,
+	0xaf, 0xdb, 0x81, 0x58, 0xeb, 0x69, 0x07, 0x32, 0x8d, 0xfc, 0x8f, 0x01, 0xa5, 0xe4, 0xc1, 0xfa,
+	0xaa, 0x66, 0x9e, 0x9a, 0xbc, 0xf2, 0xff, 0xf7, 0xe4, 0x85, 0xc0, 0xec, 0x7b, 0x81, 0x9e, 0x11,
+	0xb1, 0x5a, 0xa3, 0x16, 0x14, 0x43, 0x32, 0xf6, 0x19, 0x71, 0x75, 0xa3, 0x5c, 0x99, 0xfb, 0x95,
+	0xa2, 0x1d, 0x8c, 0x71, 0x02, 0xda, 0x5e, 0x39, 0x3c, 0x6a, 0x2e, 0x43, 0x35, 0xed, 0xf9, 0x7b,
+	0xa3, 0xf9, 0x4f, 0x03, 0xca, 0x7b, 0x7f, 0x14, 0x34, 0x50, 0xf3, 0xc0, 0x37, 0xd2, 0xf9, 0xf5,
+	0xf9, 0x5f, 0x32, 0xca, 0x27, 0x7e, 0xa4, 0xc8, 0xba, 0xd4, 0x8e, 0xf5, 0xf9, 0x4b, 0xfd, 0xc6,
+	0xbf, 0xbe, 0xd4, 0x6f, 0x7c, 0x9c, 0xd4, 0x8d, 0xcf, 0x93, 0xba, 0xf1, 0x8f, 0x49, 0xdd, 0xf8,
+	0xf7, 0xa4, 0x6e, 0x1c, 0x14, 0x54, 0x7c, 0x7e, 0xf2, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9,
+	0xa1, 0x26, 0x54, 0x90, 0x13, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/objects.proto b/vendor/github.com/docker/swarmkit/api/objects.proto
index 311c1f2..c3ee419 100644
--- a/vendor/github.com/docker/swarmkit/api/objects.proto
+++ b/vendor/github.com/docker/swarmkit/api/objects.proto
@@ -2,12 +2,12 @@
 
 package docker.swarmkit.v1;
 
-import "types.proto";
-import "specs.proto";
+import "github.com/docker/swarmkit/api/types.proto";
+import "github.com/docker/swarmkit/api/specs.proto";
 import "google/protobuf/timestamp.proto";
 import "gogoproto/gogo.proto";
 import "google/protobuf/any.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 // This file contains definitions for all first-class objects in the cluster
 // API. Such types typically have a corresponding specification, with the
@@ -59,8 +59,9 @@
 	// component, if the node is a manager.
 	ManagerStatus manager_status = 6;
 
+	// DEPRECATED: Use lb_attachments to find the ingress network
 	// The node attachment to the ingress network.
-	NetworkAttachment attachment = 7;
+	NetworkAttachment attachment = 7 [deprecated=true];
 
 	// Certificate is the TLS certificate issued for the node, if any.
 	Certificate certificate = 8 [(gogoproto.nullable) = false];
@@ -75,6 +76,11 @@
 	// shows the privilege level that the CA would currently grant when
 	// issuing or renewing the node's certificate.
 	NodeRole role = 9;
+
+	// Attachments enumerates the network attachments for the node to set up an
+	// endpoint on the node to be used for load balancing. Each overlay
+	// network, including ingress network, will have an NetworkAttachment.
+	repeated NetworkAttachment attachments = 10;
 }
 
 message Service {
@@ -257,7 +263,7 @@
 
 	// List of aliases by which a task is resolved in a network
 	repeated string aliases = 3;
-	
+
 	// Map of all the driver attachment options for this network
 	map<string,string> driver_attachment_opts = 4;
 }
diff --git a/vendor/github.com/docker/swarmkit/api/raft.pb.go b/vendor/github.com/docker/swarmkit/api/raft.pb.go
index 6a1e8ef..4710ee6 100644
--- a/vendor/github.com/docker/swarmkit/api/raft.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/raft.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: raft.proto
+// source: github.com/docker/swarmkit/api/raft.proto
 // DO NOT EDIT!
 
 package api
@@ -907,7 +907,7 @@
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "raft.proto",
+	Metadata: "github.com/docker/swarmkit/api/raft.proto",
 }
 
 // Client API for RaftMembership service
@@ -1008,7 +1008,7 @@
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "raft.proto",
+	Metadata: "github.com/docker/swarmkit/api/raft.proto",
 }
 
 func (m *RaftMember) Marshal() (dAtA []byte, err error) {
@@ -3571,68 +3571,69 @@
 	ErrIntOverflowRaft   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("raft.proto", fileDescriptorRaft) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/raft.proto", fileDescriptorRaft) }
 
 var fileDescriptorRaft = []byte{
-	// 953 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x96, 0x4d, 0x6f, 0x1b, 0x45,
-	0x18, 0xc7, 0x77, 0xd7, 0x5b, 0x27, 0x79, 0xdc, 0xbc, 0x68, 0x42, 0xc2, 0x76, 0x29, 0x8e, 0xbb,
-	0x45, 0xc2, 0x2d, 0x64, 0x2d, 0x0c, 0x12, 0xa8, 0xd0, 0x43, 0xec, 0x58, 0xb2, 0x69, 0xeb, 0x54,
-	0x9b, 0x04, 0x7a, 0x0b, 0xeb, 0xdd, 0x89, 0xbb, 0xd8, 0xde, 0x31, 0x33, 0x63, 0x07, 0x2e, 0xa8,
-	0x47, 0x94, 0x2b, 0x07, 0x10, 0x52, 0x4f, 0x70, 0xee, 0x07, 0xe0, 0x03, 0xa0, 0x88, 0x13, 0x37,
-	0x38, 0x45, 0xd4, 0x1f, 0x00, 0xbe, 0x02, 0x9a, 0xd9, 0x5d, 0x3b, 0x38, 0x6b, 0x37, 0x17, 0x7b,
-	0x3c, 0xf3, 0xfb, 0x3f, 0xff, 0x79, 0xe6, 0xe5, 0x19, 0x03, 0x50, 0xf7, 0x98, 0xdb, 0x7d, 0x4a,
-	0x38, 0x41, 0xc8, 0x27, 0x5e, 0x07, 0x53, 0x9b, 0x9d, 0xb8, 0xb4, 0xd7, 0x09, 0xb8, 0x3d, 0x7c,
-	0xcf, 0x5c, 0x26, 0xad, 0x2f, 0xb1, 0xc7, 0x59, 0x84, 0x98, 0x39, 0xfe, 0x4d, 0x1f, 0x27, 0x3f,
-	0xb6, 0xdb, 0x01, 0x7f, 0x3a, 0x68, 0xd9, 0x1e, 0xe9, 0x95, 0x3c, 0x42, 0x31, 0x61, 0x25, 0xcc,
-	0x3d, 0xbf, 0x24, 0x42, 0xca, 0x8f, 0x7e, 0xab, 0x34, 0x09, 0x6f, 0xbe, 0xd6, 0x26, 0x6d, 0x22,
-	0x9b, 0x25, 0xd1, 0x8a, 0x7b, 0xd7, 0xfb, 0xdd, 0x41, 0x3b, 0x08, 0x4b, 0xd1, 0x57, 0xd4, 0x69,
-	0xbd, 0x50, 0x01, 0x1c, 0xf7, 0x98, 0x3f, 0xc2, 0xbd, 0x16, 0xa6, 0xe8, 0x36, 0x2c, 0x88, 0x38,
-	0x47, 0x81, 0x6f, 0xa8, 0x05, 0xb5, 0xa8, 0x57, 0x60, 0x74, 0xbe, 0x95, 0x15, 0x40, 0x63, 0xd7,
-	0xc9, 0x8a, 0xa1, 0x86, 0x2f, 0xa0, 0x90, 0xf8, 0x58, 0x40, 0x5a, 0x41, 0x2d, 0x2e, 0x45, 0x50,
-	0x93, 0xf8, 0x58, 0x40, 0x62, 0xa8, 0xe1, 0x23, 0x04, 0xba, 0xeb, 0xfb, 0xd4, 0xc8, 0x08, 0xc2,
-	0x91, 0x6d, 0x54, 0x81, 0x2c, 0xe3, 0x2e, 0x1f, 0x30, 0x43, 0x2f, 0xa8, 0xc5, 0x5c, 0xf9, 0x2d,
-	0xfb, 0xf2, 0x3a, 0xd8, 0x93, 0xd9, 0xec, 0x4b, 0xb6, 0xa2, 0x9f, 0x9d, 0x6f, 0x29, 0x4e, 0xac,
-	0xb4, 0x6e, 0x41, 0xee, 0x53, 0x12, 0x84, 0x0e, 0xfe, 0x6a, 0x80, 0x19, 0x1f, 0xdb, 0xa8, 0x13,
-	0x1b, 0xeb, 0x27, 0x15, 0xae, 0x47, 0x0c, 0xeb, 0x93, 0x90, 0xe1, 0xab, 0x65, 0xf5, 0x11, 0x2c,
-	0xf4, 0xa4, 0x2d, 0x33, 0xb4, 0x42, 0xa6, 0x98, 0x2b, 0xe7, 0xe7, 0xcf, 0xce, 0x49, 0x70, 0xf4,
-	0x0e, 0xac, 0x52, 0xdc, 0x23, 0x43, 0xec, 0x1f, 0x25, 0x11, 0x32, 0x85, 0x4c, 0x51, 0xaf, 0x68,
-	0x6b, 0x8a, 0xb3, 0x12, 0x0f, 0x45, 0x22, 0x66, 0x55, 0xe0, 0xfa, 0x43, 0xec, 0x0e, 0x71, 0x92,
-	0x40, 0x19, 0x74, 0xb1, 0x62, 0x72, 0x62, 0xaf, 0xf6, 0x94, 0xac, 0xb5, 0x0a, 0xcb, 0x71, 0x8c,
-	0x28, 0x41, 0xeb, 0x21, 0xdc, 0x78, 0x4c, 0x89, 0x87, 0x19, 0x8b, 0x58, 0xc6, 0xdc, 0xf6, 0xd8,
-	0xe1, 0x8e, 0x48, 0x4c, 0xf6, 0xc4, 0x26, 0xab, 0x76, 0x74, 0x64, 0xec, 0x04, 0x4c, 0xc6, 0xef,
-	0xe9, 0xcf, 0x7e, 0xb0, 0x14, 0xeb, 0x26, 0x98, 0x69, 0xd1, 0x62, 0xaf, 0x4f, 0x60, 0xc3, 0xc1,
-	0x8c, 0x74, 0x87, 0x78, 0xc7, 0xf7, 0xa9, 0x80, 0x62, 0x9f, 0xab, 0xac, 0xb2, 0xf5, 0x2e, 0x6c,
-	0x4e, 0xab, 0xe3, 0x4d, 0x4a, 0xdb, 0xc9, 0x2e, 0xac, 0x37, 0x42, 0x8e, 0x69, 0xe8, 0x76, 0x45,
-	0x9c, 0xc4, 0x69, 0x13, 0xb4, 0xb1, 0x49, 0x76, 0x74, 0xbe, 0xa5, 0x35, 0x76, 0x1d, 0x2d, 0xf0,
-	0xd1, 0x7d, 0xc8, 0xba, 0x1e, 0x0f, 0x48, 0x18, 0xef, 0xe0, 0x56, 0xda, 0x6a, 0xee, 0x73, 0x42,
-	0xf1, 0x8e, 0xc4, 0x92, 0xa3, 0x15, 0x89, 0xac, 0xdf, 0x74, 0xc8, 0x5d, 0x18, 0x45, 0x1f, 0x8f,
-	0xc3, 0x09, 0xab, 0x95, 0xf2, 0xed, 0x57, 0x84, 0x7b, 0x10, 0x84, 0x7e, 0x12, 0x0c, 0xd9, 0xf1,
-	0xbe, 0x6a, 0x72, 0xc9, 0x8d, 0x34, 0xa9, 0xb8, 0x31, 0x75, 0x25, 0xda, 0x53, 0xf4, 0x21, 0x2c,
-	0x30, 0x4c, 0x87, 0x81, 0x87, 0xe5, 0x95, 0xc9, 0x95, 0xdf, 0x48, 0x75, 0x8b, 0x90, 0xba, 0xe2,
-	0x24, 0xb4, 0x30, 0xe2, 0x2e, 0xeb, 0xc4, 0x57, 0x2a, 0xd5, 0xe8, 0xc0, 0x65, 0x1d, 0x61, 0x24,
-	0x38, 0x61, 0x14, 0x62, 0x7e, 0x42, 0x68, 0xc7, 0xb8, 0x36, 0xdb, 0xa8, 0x19, 0x21, 0xc2, 0x28,
-	0xa6, 0x85, 0xd0, 0xeb, 0x0e, 0x18, 0xc7, 0xd4, 0xc8, 0xce, 0x16, 0x56, 0x23, 0x44, 0x08, 0x63,
-	0x1a, 0x7d, 0x00, 0x59, 0x86, 0x3d, 0x8a, 0xb9, 0xb1, 0x20, 0x75, 0x66, 0x7a, 0x66, 0x82, 0xa8,
-	0x8b, 0x8b, 0x2e, 0x5b, 0xe8, 0x1e, 0x2c, 0x52, 0xcc, 0xc8, 0x80, 0x7a, 0xd8, 0x58, 0x94, 0xba,
-	0x9b, 0xa9, 0x97, 0x23, 0x66, 0xea, 0x8a, 0x33, 0xe6, 0xd1, 0x7d, 0x58, 0xc2, 0x5f, 0x73, 0x1c,
-	0x32, 0xb1, 0x79, 0x4b, 0x52, 0xfc, 0x66, 0x9a, 0xb8, 0x96, 0x40, 0x75, 0xc5, 0x99, 0x28, 0xc4,
-	0x84, 0x3d, 0x12, 0x1e, 0x07, 0x6d, 0x03, 0x66, 0x4f, 0xb8, 0x2a, 0x09, 0x31, 0xe1, 0x88, 0xad,
-	0x2c, 0x42, 0x96, 0xbb, 0xb4, 0x8d, 0xf9, 0xdd, 0x7f, 0x55, 0x58, 0x9d, 0x3a, 0x17, 0xe8, 0x6d,
-	0x58, 0x38, 0x6c, 0x3e, 0x68, 0xee, 0x7d, 0xde, 0x5c, 0x53, 0x4c, 0xf3, 0xf4, 0x79, 0x61, 0x73,
-	0x8a, 0x38, 0x0c, 0x3b, 0x21, 0x39, 0x09, 0x51, 0x19, 0xd6, 0xf7, 0x0f, 0xf6, 0x9c, 0xda, 0xd1,
-	0x4e, 0xf5, 0xa0, 0xb1, 0xd7, 0x3c, 0xaa, 0x3a, 0xb5, 0x9d, 0x83, 0xda, 0x9a, 0x6a, 0xde, 0x38,
-	0x7d, 0x5e, 0xd8, 0x98, 0x12, 0x55, 0x29, 0x76, 0x39, 0xbe, 0xa4, 0x39, 0x7c, 0xbc, 0x2b, 0x34,
-	0x5a, 0xaa, 0xe6, 0xb0, 0xef, 0xa7, 0x69, 0x9c, 0xda, 0xa3, 0xbd, 0xcf, 0x6a, 0x6b, 0x99, 0x54,
-	0x8d, 0x23, 0x8b, 0x98, 0xf9, 0xfa, 0x77, 0x3f, 0xe7, 0x95, 0x5f, 0x7f, 0xc9, 0x4f, 0x67, 0x57,
-	0xfe, 0x5e, 0x03, 0x5d, 0xdc, 0x50, 0x74, 0xaa, 0x02, 0xba, 0x5c, 0x3c, 0xd0, 0x76, 0xda, 0x0a,
-	0xce, 0x2c, 0x59, 0xa6, 0x7d, 0x55, 0x3c, 0xae, 0x49, 0x1b, 0xbf, 0xbf, 0xf8, 0xe7, 0x47, 0x6d,
-	0x15, 0x96, 0x25, 0xbf, 0xdd, 0x73, 0x43, 0xb7, 0x8d, 0x29, 0xfa, 0x16, 0x56, 0xfe, 0x5f, 0x6c,
-	0xd0, 0x9d, 0x59, 0x47, 0xe8, 0x52, 0x39, 0x33, 0xef, 0x5e, 0x05, 0x9d, 0xeb, 0x5f, 0xfe, 0x53,
-	0x85, 0x95, 0x49, 0xf1, 0x66, 0x4f, 0x83, 0x3e, 0xfa, 0x02, 0x74, 0xf1, 0x34, 0xa1, 0xd4, 0xd2,
-	0x74, 0xe1, 0x61, 0x33, 0x0b, 0xb3, 0x81, 0xf9, 0x49, 0x7b, 0x70, 0x4d, 0x3e, 0x0e, 0x28, 0x35,
-	0xc2, 0xc5, 0xb7, 0xc7, 0xbc, 0x35, 0x87, 0x98, 0x6b, 0x52, 0x31, 0xce, 0x5e, 0xe6, 0x95, 0xbf,
-	0x5e, 0xe6, 0x95, 0x67, 0xa3, 0xbc, 0x7a, 0x36, 0xca, 0xab, 0x7f, 0x8c, 0xf2, 0xea, 0xdf, 0xa3,
-	0xbc, 0xfa, 0x24, 0xf3, 0x44, 0x6f, 0x65, 0xe5, 0x7f, 0x8b, 0xf7, 0xff, 0x0b, 0x00, 0x00, 0xff,
-	0xff, 0x9a, 0xef, 0x6e, 0xdb, 0xf3, 0x08, 0x00, 0x00,
+	// 974 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x96, 0x4f, 0x6f, 0x1b, 0x45,
+	0x18, 0xc6, 0x77, 0xd7, 0x5b, 0x27, 0x79, 0xd3, 0x26, 0xd1, 0x94, 0x84, 0xed, 0x52, 0x1c, 0x77,
+	0x8b, 0x84, 0x13, 0x9a, 0xb5, 0x30, 0x48, 0x45, 0x85, 0x1e, 0x62, 0xc7, 0x92, 0x4d, 0x5b, 0xa7,
+	0xda, 0x24, 0xd0, 0x5b, 0x58, 0xef, 0x4e, 0xdc, 0xc5, 0xf6, 0x8e, 0x99, 0x19, 0x3b, 0x70, 0x41,
+	0x3d, 0xa2, 0x5c, 0x39, 0x80, 0x90, 0x7a, 0x82, 0x73, 0x3f, 0x00, 0x1f, 0x00, 0x45, 0x9c, 0xb8,
+	0xc1, 0x29, 0xa2, 0xfe, 0x00, 0xf0, 0x15, 0xd0, 0xcc, 0xee, 0x3a, 0xc6, 0x59, 0x3b, 0xb9, 0x24,
+	0xa3, 0x9d, 0xdf, 0xf3, 0x3e, 0xef, 0x3b, 0x7f, 0xde, 0x31, 0x6c, 0xb4, 0x02, 0xfe, 0xbc, 0xdf,
+	0xb4, 0x3d, 0xd2, 0x2d, 0xfa, 0xc4, 0x6b, 0x63, 0x5a, 0x64, 0xc7, 0x2e, 0xed, 0xb6, 0x03, 0x5e,
+	0x74, 0x7b, 0x41, 0x91, 0xba, 0x47, 0xdc, 0xee, 0x51, 0xc2, 0x09, 0x42, 0xd1, 0xbc, 0x9d, 0xcc,
+	0xdb, 0x83, 0xf7, 0xcd, 0x7b, 0x97, 0xc8, 0x49, 0xf3, 0x4b, 0xec, 0x71, 0x16, 0x45, 0x30, 0x37,
+	0x2f, 0xa1, 0xf9, 0x37, 0x3d, 0x9c, 0xb0, 0x5b, 0x63, 0xac, 0x47, 0x28, 0x26, 0xac, 0x88, 0xb9,
+	0xe7, 0xcb, 0x84, 0xe4, 0x9f, 0x5e, 0x73, 0x2c, 0x39, 0xf3, 0x8d, 0x16, 0x69, 0x11, 0x39, 0x2c,
+	0x8a, 0x51, 0xfc, 0xf5, 0xfe, 0x0c, 0x43, 0x49, 0x34, 0xfb, 0x47, 0xc5, 0x5e, 0xa7, 0xdf, 0x0a,
+	0xc2, 0xf8, 0x5f, 0x24, 0xb4, 0x5e, 0xa9, 0x00, 0x8e, 0x7b, 0xc4, 0x9f, 0xe0, 0x6e, 0x13, 0x53,
+	0x74, 0x17, 0xe6, 0x84, 0xd7, 0x61, 0xe0, 0x1b, 0x6a, 0x5e, 0x2d, 0xe8, 0x65, 0x18, 0x9e, 0xad,
+	0x67, 0x05, 0x50, 0xdf, 0x71, 0xb2, 0x62, 0xaa, 0xee, 0x0b, 0x28, 0x24, 0x3e, 0x16, 0x90, 0x96,
+	0x57, 0x0b, 0x0b, 0x11, 0xd4, 0x20, 0x3e, 0x16, 0x90, 0x98, 0xaa, 0xfb, 0x08, 0x81, 0xee, 0xfa,
+	0x3e, 0x35, 0x32, 0x82, 0x70, 0xe4, 0x18, 0x95, 0x21, 0xcb, 0xb8, 0xcb, 0xfb, 0xcc, 0xd0, 0xf3,
+	0x6a, 0x61, 0xb1, 0xf4, 0x8e, 0x7d, 0x71, 0xa5, 0xed, 0xf3, 0x6c, 0xf6, 0x24, 0x5b, 0xd6, 0x4f,
+	0xcf, 0xd6, 0x15, 0x27, 0x56, 0x5a, 0x77, 0x60, 0xf1, 0x53, 0x12, 0x84, 0x0e, 0xfe, 0xaa, 0x8f,
+	0x19, 0x1f, 0xd9, 0xa8, 0xe7, 0x36, 0xd6, 0x4f, 0x2a, 0x5c, 0x8f, 0x18, 0xd6, 0x23, 0x21, 0xc3,
+	0x57, 0xab, 0xea, 0x23, 0x98, 0xeb, 0x4a, 0x5b, 0x66, 0x68, 0xf9, 0x4c, 0x61, 0xb1, 0x94, 0x9b,
+	0x9d, 0x9d, 0x93, 0xe0, 0xe8, 0x3d, 0x58, 0xa6, 0xb8, 0x4b, 0x06, 0xd8, 0x3f, 0x4c, 0x22, 0x64,
+	0xf2, 0x99, 0x82, 0x5e, 0xd6, 0x56, 0x14, 0x67, 0x29, 0x9e, 0x8a, 0x44, 0xcc, 0x2a, 0xc3, 0xf5,
+	0xc7, 0xd8, 0x1d, 0xe0, 0xa4, 0x80, 0x12, 0xe8, 0x62, 0xc5, 0x64, 0x62, 0x97, 0x7b, 0x4a, 0xd6,
+	0x5a, 0x86, 0x1b, 0x71, 0x8c, 0xa8, 0x40, 0xeb, 0x31, 0xdc, 0x7a, 0x4a, 0x89, 0x87, 0x19, 0x8b,
+	0x58, 0xc6, 0xdc, 0xd6, 0xc8, 0x61, 0x43, 0x14, 0x26, 0xbf, 0xc4, 0x26, 0xcb, 0x76, 0x74, 0xac,
+	0xec, 0x04, 0x4c, 0xe6, 0x1f, 0xe8, 0x2f, 0x7e, 0xb0, 0x14, 0xeb, 0x36, 0x98, 0x69, 0xd1, 0x62,
+	0xaf, 0x4f, 0x60, 0xd5, 0xc1, 0x8c, 0x74, 0x06, 0x78, 0xdb, 0xf7, 0xa9, 0x80, 0x62, 0x9f, 0xab,
+	0xac, 0xb2, 0x75, 0x0f, 0xd6, 0x26, 0xd5, 0xf1, 0x26, 0xa5, 0xed, 0x64, 0x07, 0x6e, 0xd6, 0x43,
+	0x8e, 0x69, 0xe8, 0x76, 0x44, 0x9c, 0xc4, 0x69, 0x0d, 0xb4, 0x91, 0x49, 0x76, 0x78, 0xb6, 0xae,
+	0xd5, 0x77, 0x1c, 0x2d, 0xf0, 0xd1, 0x43, 0xc8, 0xba, 0x1e, 0x0f, 0x48, 0x18, 0xef, 0xe0, 0x7a,
+	0xda, 0x6a, 0xee, 0x71, 0x42, 0xf1, 0xb6, 0xc4, 0x92, 0xa3, 0x15, 0x89, 0xac, 0xdf, 0x74, 0x58,
+	0x1c, 0x9b, 0x45, 0x1f, 0x8f, 0xc2, 0x09, 0xab, 0xa5, 0xd2, 0xdd, 0x4b, 0xc2, 0x3d, 0x0a, 0x42,
+	0x3f, 0x09, 0x86, 0xec, 0x78, 0x5f, 0x35, 0xb9, 0xe4, 0x46, 0x9a, 0x54, 0xdc, 0x98, 0x9a, 0x12,
+	0xed, 0x29, 0xba, 0x0f, 0x73, 0x0c, 0xd3, 0x41, 0xe0, 0x61, 0x79, 0x65, 0x16, 0x4b, 0x6f, 0xa5,
+	0xba, 0x45, 0x48, 0x4d, 0x71, 0x12, 0x5a, 0x18, 0x71, 0x97, 0xb5, 0xe3, 0x2b, 0x95, 0x6a, 0xb4,
+	0xef, 0xb2, 0xb6, 0x30, 0x12, 0x9c, 0x30, 0x0a, 0x31, 0x3f, 0x26, 0xb4, 0x6d, 0x5c, 0x9b, 0x6e,
+	0xd4, 0x88, 0x10, 0x61, 0x14, 0xd3, 0x42, 0xe8, 0x75, 0xfa, 0x8c, 0x63, 0x6a, 0x64, 0xa7, 0x0b,
+	0x2b, 0x11, 0x22, 0x84, 0x31, 0x8d, 0x3e, 0x84, 0x2c, 0xc3, 0x1e, 0xc5, 0xdc, 0x98, 0x93, 0x3a,
+	0x33, 0xbd, 0x32, 0x41, 0xd4, 0xc4, 0x45, 0x97, 0x23, 0xf4, 0x00, 0xe6, 0x29, 0x66, 0xa4, 0x4f,
+	0x3d, 0x6c, 0xcc, 0x4b, 0xdd, 0xed, 0xd4, 0xcb, 0x11, 0x33, 0x35, 0xc5, 0x19, 0xf1, 0xe8, 0x21,
+	0x2c, 0xe0, 0xaf, 0x39, 0x0e, 0x99, 0xd8, 0xbc, 0x05, 0x29, 0x7e, 0x3b, 0x4d, 0x5c, 0x4d, 0xa0,
+	0x9a, 0xe2, 0x9c, 0x2b, 0x44, 0xc2, 0x1e, 0x09, 0x8f, 0x82, 0x96, 0x01, 0xd3, 0x13, 0xae, 0x48,
+	0x42, 0x24, 0x1c, 0xb1, 0xe5, 0x79, 0xc8, 0x72, 0x97, 0xb6, 0x30, 0xdf, 0xfc, 0x57, 0x85, 0xe5,
+	0x89, 0x73, 0x81, 0xde, 0x85, 0xb9, 0x83, 0xc6, 0xa3, 0xc6, 0xee, 0xe7, 0x8d, 0x15, 0xc5, 0x34,
+	0x4f, 0x5e, 0xe6, 0xd7, 0x26, 0x88, 0x83, 0xb0, 0x1d, 0x92, 0xe3, 0x10, 0x95, 0xe0, 0xe6, 0xde,
+	0xfe, 0xae, 0x53, 0x3d, 0xdc, 0xae, 0xec, 0xd7, 0x77, 0x1b, 0x87, 0x15, 0xa7, 0xba, 0xbd, 0x5f,
+	0x5d, 0x51, 0xcd, 0x5b, 0x27, 0x2f, 0xf3, 0xab, 0x13, 0xa2, 0x0a, 0xc5, 0x2e, 0xc7, 0x17, 0x34,
+	0x07, 0x4f, 0x77, 0x84, 0x46, 0x4b, 0xd5, 0x1c, 0xf4, 0xfc, 0x34, 0x8d, 0x53, 0x7d, 0xb2, 0xfb,
+	0x59, 0x75, 0x25, 0x93, 0xaa, 0x71, 0x64, 0x13, 0x33, 0xdf, 0xfc, 0xee, 0xe7, 0x9c, 0xf2, 0xeb,
+	0x2f, 0xb9, 0xc9, 0xea, 0x4a, 0xdf, 0x6b, 0xa0, 0x8b, 0x1b, 0x8a, 0x4e, 0x54, 0x40, 0x17, 0x9b,
+	0x07, 0xda, 0x4a, 0x5b, 0xc1, 0xa9, 0x2d, 0xcb, 0xb4, 0xaf, 0x8a, 0xc7, 0x3d, 0x69, 0xf5, 0xf7,
+	0x57, 0xff, 0xfc, 0xa8, 0x2d, 0xc3, 0x0d, 0xc9, 0x6f, 0x75, 0xdd, 0xd0, 0x6d, 0x61, 0x8a, 0xbe,
+	0x85, 0xa5, 0xff, 0x37, 0x1b, 0xb4, 0x31, 0xed, 0x08, 0x5d, 0x68, 0x67, 0xe6, 0xe6, 0x55, 0xd0,
+	0x99, 0xfe, 0xa5, 0x3f, 0x55, 0x58, 0x3a, 0x6f, 0xde, 0xec, 0x79, 0xd0, 0x43, 0x5f, 0x80, 0x2e,
+	0x9e, 0x26, 0x94, 0xda, 0x9a, 0xc6, 0x1e, 0x36, 0x33, 0x3f, 0x1d, 0x98, 0x5d, 0xb4, 0x07, 0xd7,
+	0xe4, 0xe3, 0x80, 0x52, 0x23, 0x8c, 0xbf, 0x3d, 0xe6, 0x9d, 0x19, 0xc4, 0x4c, 0x93, 0xb2, 0x71,
+	0xfa, 0x3a, 0xa7, 0xfc, 0xf5, 0x3a, 0xa7, 0xbc, 0x18, 0xe6, 0xd4, 0xd3, 0x61, 0x4e, 0xfd, 0x63,
+	0x98, 0x53, 0xff, 0x1e, 0xe6, 0xd4, 0x67, 0x99, 0x67, 0x7a, 0x33, 0x2b, 0x7f, 0x5b, 0x7c, 0xf0,
+	0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0x01, 0xa3, 0x4f, 0x74, 0x09, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/raft.proto b/vendor/github.com/docker/swarmkit/api/raft.proto
index e464f3a..b398315 100644
--- a/vendor/github.com/docker/swarmkit/api/raft.proto
+++ b/vendor/github.com/docker/swarmkit/api/raft.proto
@@ -2,11 +2,11 @@
 
 package docker.swarmkit.v1;
 
-import "objects.proto";
-import "types.proto";
+import "github.com/docker/swarmkit/api/objects.proto";
+import "github.com/docker/swarmkit/api/types.proto";
 import "github.com/coreos/etcd/raft/raftpb/raft.proto";
 import weak "gogoproto/gogo.proto";
-import weak "plugin/plugin.proto";
+import weak "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 // Raft defines the RPC communication between raft nodes.
 service Raft {
diff --git a/vendor/github.com/docker/swarmkit/api/resource.pb.go b/vendor/github.com/docker/swarmkit/api/resource.pb.go
index 4afd800..ead5d27 100644
--- a/vendor/github.com/docker/swarmkit/api/resource.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/resource.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: resource.proto
+// source: github.com/docker/swarmkit/api/resource.proto
 // DO NOT EDIT!
 
 package api
@@ -262,7 +262,7 @@
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
-	Metadata: "resource.proto",
+	Metadata: "github.com/docker/swarmkit/api/resource.proto",
 }
 
 func (m *AttachNetworkRequest) Marshal() (dAtA []byte, err error) {
@@ -1061,31 +1061,35 @@
 	ErrIntOverflowResource   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("resource.proto", fileDescriptorResource) }
+func init() {
+	proto.RegisterFile("github.com/docker/swarmkit/api/resource.proto", fileDescriptorResource)
+}
 
 var fileDescriptorResource = []byte{
-	// 368 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2b, 0x4a, 0x2d, 0xce,
-	0x2f, 0x2d, 0x4a, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4a, 0xc9, 0x4f, 0xce,
-	0x4e, 0x2d, 0xd2, 0x2b, 0x2e, 0x4f, 0x2c, 0xca, 0xcd, 0xce, 0x2c, 0xd1, 0x2b, 0x33, 0x94, 0xe2,
-	0x2e, 0xa9, 0x2c, 0x48, 0x2d, 0x86, 0x28, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x33, 0xf5,
-	0x41, 0x2c, 0xa8, 0xa8, 0x70, 0x41, 0x4e, 0x69, 0x7a, 0x66, 0x9e, 0x3e, 0x84, 0x82, 0x08, 0x2a,
-	0xf5, 0x33, 0x72, 0x89, 0x38, 0x96, 0x94, 0x24, 0x26, 0x67, 0xf8, 0xa5, 0x96, 0x94, 0xe7, 0x17,
-	0x65, 0x07, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0x39, 0x73, 0xb1, 0x25, 0xe7, 0xe7, 0xa5,
-	0x65, 0xa6, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x1b, 0x69, 0xeb, 0x61, 0xda, 0xaa, 0x07, 0xd5,
-	0x03, 0x31, 0x20, 0x37, 0x35, 0xaf, 0xc4, 0x19, 0xac, 0x25, 0x08, 0xaa, 0x55, 0xc8, 0x88, 0x8b,
-	0x27, 0x39, 0x3f, 0xaf, 0x24, 0x31, 0x33, 0x2f, 0xb5, 0x28, 0x3e, 0x33, 0x45, 0x82, 0x49, 0x81,
-	0x51, 0x83, 0xd3, 0x89, 0xff, 0xd1, 0x3d, 0x79, 0x6e, 0x67, 0x98, 0xb8, 0xa7, 0x4b, 0x10, 0x37,
-	0x5c, 0x91, 0x67, 0x8a, 0x92, 0x1f, 0x97, 0x28, 0x9a, 0x83, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53,
-	0x85, 0x4c, 0xb9, 0x78, 0x13, 0xe1, 0x16, 0x81, 0x4c, 0x63, 0x04, 0x9b, 0x26, 0xf0, 0xe8, 0x9e,
-	0x3c, 0x0f, 0xc2, 0x05, 0x9e, 0x2e, 0x41, 0x3c, 0x08, 0x65, 0x9e, 0x29, 0x4a, 0xbe, 0x5c, 0x22,
-	0x2e, 0xa9, 0x58, 0x3c, 0x48, 0xa6, 0x71, 0xe2, 0x5c, 0xa2, 0x68, 0xc6, 0x41, 0x9c, 0x67, 0xb4,
-	0x9a, 0x89, 0x4b, 0x30, 0x08, 0x1a, 0x51, 0x8e, 0x39, 0x39, 0xf9, 0xc9, 0x89, 0x25, 0xf9, 0x45,
-	0x42, 0x9d, 0x8c, 0x5c, 0xbc, 0x28, 0xde, 0x11, 0xd2, 0xc0, 0x16, 0x90, 0xd8, 0xa2, 0x40, 0x4a,
-	0x93, 0x08, 0x95, 0x10, 0xcb, 0x95, 0x94, 0x4f, 0xad, 0x7b, 0x37, 0x83, 0x49, 0x96, 0x8b, 0x07,
-	0xac, 0x54, 0x17, 0x24, 0x97, 0x5a, 0xc4, 0xc5, 0x0b, 0xe1, 0xe5, 0x26, 0xe6, 0x25, 0xa6, 0xa7,
-	0x42, 0xdc, 0x82, 0xe2, 0x76, 0xec, 0x6e, 0xc1, 0x16, 0x5a, 0xd8, 0xdd, 0x82, 0x35, 0x20, 0x88,
-	0x72, 0x8b, 0x93, 0xc4, 0x89, 0x87, 0x72, 0x0c, 0x37, 0x1e, 0xca, 0x31, 0x34, 0x3c, 0x92, 0x63,
-	0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x93, 0xd8, 0xc0,
-	0x09, 0xd3, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x48, 0x12, 0x41, 0xf6, 0x02, 0x00, 0x00,
+	// 397 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0xcf, 0x4e, 0xf2, 0x40,
+	0x14, 0xc5, 0x19, 0x16, 0x24, 0xdf, 0x50, 0xf2, 0x69, 0x03, 0x91, 0x90, 0x58, 0x48, 0xdd, 0xa0,
+	0x86, 0x36, 0x62, 0x8c, 0x6b, 0xfe, 0x6c, 0xba, 0x90, 0x45, 0x5f, 0xc0, 0x0c, 0xed, 0x50, 0x1a,
+	0x68, 0xa7, 0x4e, 0xa7, 0x12, 0x77, 0x6e, 0x5d, 0xb9, 0xf5, 0x1d, 0x4c, 0x7c, 0x0e, 0xe2, 0xca,
+	0xa5, 0x2b, 0x22, 0x7d, 0x00, 0x9f, 0xc1, 0xd0, 0x29, 0x10, 0x70, 0xa2, 0xc4, 0x55, 0xa7, 0xd3,
+	0x73, 0xce, 0xfd, 0xdd, 0x7b, 0x0b, 0x1b, 0x8e, 0xcb, 0x86, 0x51, 0x5f, 0xb3, 0x88, 0xa7, 0xdb,
+	0xc4, 0x1a, 0x61, 0xaa, 0x87, 0x13, 0x44, 0xbd, 0x91, 0xcb, 0x74, 0x14, 0xb8, 0x3a, 0xc5, 0x21,
+	0x89, 0xa8, 0x85, 0xb5, 0x80, 0x12, 0x46, 0x64, 0x99, 0x6b, 0xb4, 0xa5, 0x46, 0xbb, 0x3d, 0xab,
+	0x9c, 0xfc, 0x12, 0xc1, 0xee, 0x02, 0x1c, 0x72, 0x7f, 0xa5, 0xe8, 0x10, 0x87, 0x24, 0x47, 0x7d,
+	0x71, 0x4a, 0x6f, 0x2f, 0x7f, 0x48, 0x48, 0x14, 0xfd, 0x68, 0xa0, 0x07, 0xe3, 0xc8, 0x71, 0xfd,
+	0xf4, 0xc1, 0x8d, 0xea, 0x23, 0x80, 0xc5, 0x16, 0x63, 0xc8, 0x1a, 0xf6, 0x30, 0x9b, 0x10, 0x3a,
+	0x32, 0xf1, 0x4d, 0x84, 0x43, 0x26, 0x77, 0x60, 0xce, 0x22, 0xfe, 0xc0, 0x75, 0xca, 0xa0, 0x06,
+	0xea, 0xf9, 0xe6, 0xa9, 0xf6, 0x1d, 0x5c, 0x4b, 0x3d, 0x3c, 0xc0, 0xc3, 0x3e, 0xeb, 0x24, 0x16,
+	0x33, 0xb5, 0xca, 0x4d, 0x28, 0x59, 0xc4, 0x67, 0xc8, 0xf5, 0x31, 0xbd, 0x76, 0xed, 0x72, 0xb6,
+	0x06, 0xea, 0xff, 0xda, 0xff, 0xe3, 0x59, 0x35, 0xdf, 0x59, 0xde, 0x1b, 0x5d, 0x33, 0xbf, 0x12,
+	0x19, 0xb6, 0xda, 0x83, 0xa5, 0x2d, 0xa0, 0x30, 0x20, 0x7e, 0x88, 0xe5, 0x0b, 0x58, 0x40, 0xab,
+	0x42, 0x8b, 0x34, 0x90, 0xa4, 0xed, 0xc5, 0xb3, 0xaa, 0xb4, 0x26, 0x30, 0xba, 0xa6, 0xb4, 0x96,
+	0x19, 0xb6, 0x7a, 0x05, 0x8b, 0x5d, 0x2c, 0x68, 0xf0, 0x8f, 0x71, 0x07, 0xb0, 0xb4, 0x15, 0xc7,
+	0xf1, 0x9a, 0xcf, 0x59, 0xb8, 0x6f, 0xa6, 0xbb, 0x6e, 0x8d, 0xc7, 0xc4, 0x42, 0x8c, 0x50, 0xf9,
+	0x01, 0xc0, 0xc2, 0x46, 0x3b, 0x72, 0x5d, 0x34, 0x48, 0xd1, 0x0a, 0x2a, 0xc7, 0x3b, 0x28, 0x79,
+	0x71, 0xf5, 0xe8, 0xf5, 0xe5, 0xf3, 0x29, 0x7b, 0x08, 0xa5, 0x44, 0xda, 0x58, 0x7c, 0xc3, 0x14,
+	0x16, 0xf8, 0x9b, 0x87, 0x7c, 0xe4, 0x60, 0xce, 0xb2, 0xc1, 0x2e, 0x66, 0x11, 0x4d, 0x4b, 0xcc,
+	0x22, 0x1c, 0xc4, 0x4e, 0x2c, 0xed, 0xf2, 0x74, 0xae, 0x64, 0xde, 0xe7, 0x4a, 0xe6, 0x3e, 0x56,
+	0xc0, 0x34, 0x56, 0xc0, 0x5b, 0xac, 0x80, 0x8f, 0x58, 0x01, 0xfd, 0x5c, 0xf2, 0x63, 0x9e, 0x7f,
+	0x05, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x7a, 0x29, 0xfc, 0x58, 0x03, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/resource.proto b/vendor/github.com/docker/swarmkit/api/resource.proto
index 92a8302..ecaa749 100644
--- a/vendor/github.com/docker/swarmkit/api/resource.proto
+++ b/vendor/github.com/docker/swarmkit/api/resource.proto
@@ -2,9 +2,9 @@
 
 package docker.swarmkit.v1;
 
-import "types.proto";
+import "github.com/docker/swarmkit/api/types.proto";
 import "gogoproto/gogo.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 // Allocator is the API provided by a manager group for agents to control the allocation of certain entities.
 //
diff --git a/vendor/github.com/docker/swarmkit/api/snapshot.pb.go b/vendor/github.com/docker/swarmkit/api/snapshot.pb.go
index 928d1c7..f8c32b7 100644
--- a/vendor/github.com/docker/swarmkit/api/snapshot.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/snapshot.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: snapshot.proto
+// source: github.com/docker/swarmkit/api/snapshot.proto
 // DO NOT EDIT!
 
 package api
@@ -1305,38 +1305,41 @@
 	ErrIntOverflowSnapshot   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("snapshot.proto", fileDescriptorSnapshot) }
+func init() {
+	proto.RegisterFile("github.com/docker/swarmkit/api/snapshot.proto", fileDescriptorSnapshot)
+}
 
 var fileDescriptorSnapshot = []byte{
-	// 469 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x93, 0xbf, 0x6f, 0xd3, 0x40,
-	0x14, 0xc7, 0x7d, 0xce, 0x0f, 0xa7, 0xaf, 0x6a, 0x29, 0x27, 0x86, 0x53, 0x28, 0x26, 0x04, 0x86,
-	0x4c, 0x06, 0x02, 0x12, 0x08, 0xa9, 0x0c, 0xa9, 0x18, 0x18, 0xe8, 0x70, 0x41, 0x15, 0xab, 0xe3,
-	0x5c, 0x52, 0x63, 0xe2, 0x8b, 0xee, 0x5d, 0x53, 0x46, 0xf8, 0xef, 0x32, 0x32, 0x32, 0x21, 0x92,
-	0x85, 0x7f, 0x03, 0xdd, 0x9d, 0x6d, 0x22, 0xe1, 0x74, 0xb3, 0x4e, 0x9f, 0xcf, 0x7b, 0xdf, 0x3b,
-	0xbf, 0x07, 0xc7, 0x98, 0xc7, 0x4b, 0xbc, 0x92, 0x3a, 0x5a, 0x2a, 0xa9, 0x25, 0xa5, 0x53, 0x99,
-	0x64, 0x42, 0x45, 0x78, 0x13, 0xab, 0x45, 0x96, 0xea, 0x68, 0xf5, 0xbc, 0x7b, 0x24, 0x27, 0x9f,
-	0x45, 0xa2, 0xd1, 0x21, 0x5d, 0x50, 0xf1, 0xac, 0xc0, 0xbb, 0xf7, 0xe6, 0x72, 0x2e, 0xed, 0xe7,
-	0x53, 0xf3, 0xe5, 0x4e, 0xfb, 0xdf, 0x9b, 0x70, 0x34, 0xd6, 0x52, 0x89, 0x71, 0x51, 0x9c, 0x46,
-	0xd0, 0xca, 0xe5, 0x54, 0x20, 0x23, 0xbd, 0xc6, 0xe0, 0x70, 0xc8, 0xa2, 0xff, 0xdb, 0x44, 0x17,
-	0x72, 0x2a, 0xb8, 0xc3, 0xe8, 0x2b, 0xe8, 0xa0, 0x50, 0xab, 0x34, 0x11, 0xc8, 0x7c, 0xab, 0xdc,
-	0xaf, 0x53, 0xc6, 0x8e, 0xe1, 0x15, 0x6c, 0xc4, 0x5c, 0xe8, 0x1b, 0xa9, 0x32, 0x64, 0x8d, 0xfd,
-	0xe2, 0x85, 0x63, 0x78, 0x05, 0x9b, 0x84, 0x3a, 0xc6, 0x0c, 0x59, 0x73, 0x7f, 0xc2, 0x8f, 0x31,
-	0x66, 0xdc, 0x61, 0xa6, 0x51, 0xf2, 0xe5, 0x1a, 0xb5, 0x50, 0xc8, 0x5a, 0xfb, 0x1b, 0x9d, 0x3b,
-	0x86, 0x57, 0x30, 0x7d, 0x09, 0x01, 0x8a, 0x44, 0x09, 0x8d, 0xac, 0x6d, 0xbd, 0x6e, 0xfd, 0xcd,
-	0x0c, 0xc2, 0x4b, 0x94, 0xbe, 0x81, 0x03, 0x25, 0x50, 0x5e, 0x2b, 0xf3, 0x22, 0x81, 0xf5, 0x4e,
-	0xeb, 0x3c, 0x5e, 0x40, 0xfc, 0x1f, 0x4e, 0xcf, 0x00, 0xc4, 0x57, 0x2d, 0x72, 0x4c, 0x65, 0x8e,
-	0xac, 0x63, 0xe5, 0x07, 0x75, 0xf2, 0xbb, 0x92, 0xe2, 0x3b, 0x82, 0x09, 0x9c, 0xc8, 0x7c, 0x96,
-	0xce, 0x91, 0x1d, 0xec, 0x0f, 0x7c, 0x6e, 0x11, 0x5e, 0xa2, 0xfd, 0x14, 0xee, 0x14, 0x77, 0xaf,
-	0x86, 0xe0, 0x35, 0x04, 0x0b, 0xb1, 0x98, 0x98, 0x17, 0x73, 0x63, 0x10, 0xd6, 0xde, 0x20, 0x9e,
-	0xe9, 0x0f, 0x16, 0xe3, 0x25, 0x4e, 0x4f, 0x21, 0x50, 0x62, 0x21, 0x57, 0x62, 0x6a, 0xa7, 0xa1,
-	0x39, 0xf2, 0x4f, 0x3c, 0x5e, 0x1e, 0xf5, 0xff, 0x10, 0xe8, 0x54, 0x4d, 0xde, 0x42, 0xb0, 0x12,
-	0xca, 0x24, 0x67, 0xa4, 0x47, 0x06, 0xc7, 0xc3, 0x27, 0xb5, 0xcf, 0x5b, 0x4e, 0xfd, 0xa5, 0x63,
-	0x79, 0x29, 0xd1, 0xf7, 0x00, 0x45, 0xd7, 0xab, 0x74, 0xc9, 0xfc, 0x1e, 0x19, 0x1c, 0x0e, 0x1f,
-	0xdf, 0xf2, 0x67, 0xcb, 0x4a, 0xa3, 0xe6, 0xfa, 0xd7, 0x43, 0x8f, 0xef, 0xc8, 0xf4, 0x0c, 0x5a,
-	0x68, 0xb6, 0x80, 0x35, 0x6c, 0x95, 0x47, 0xb5, 0x41, 0x76, 0xd7, 0xa4, 0xa8, 0xe1, 0xac, 0xfe,
-	0x5d, 0x08, 0x8a, 0x74, 0xb4, 0x0d, 0xfe, 0xe5, 0xb3, 0x13, 0x6f, 0xc4, 0xd6, 0x9b, 0xd0, 0xfb,
-	0xb9, 0x09, 0xbd, 0x6f, 0xdb, 0x90, 0xac, 0xb7, 0x21, 0xf9, 0xb1, 0x0d, 0xc9, 0xef, 0x6d, 0x48,
-	0x3e, 0xf9, 0x93, 0xb6, 0xdd, 0xbd, 0x17, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x0f, 0xc4,
-	0x6e, 0xd2, 0x03, 0x00, 0x00,
+	// 493 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0xbf, 0x8f, 0xd3, 0x30,
+	0x14, 0xc7, 0x93, 0xf4, 0x47, 0x7a, 0x3e, 0x01, 0x87, 0xc5, 0x60, 0x95, 0x23, 0x94, 0xc2, 0x50,
+	0x24, 0x48, 0xa0, 0x20, 0x81, 0x90, 0x8e, 0xa1, 0x27, 0x06, 0x06, 0x6e, 0x70, 0xd1, 0x89, 0x35,
+	0x4d, 0xdd, 0x36, 0x84, 0xc4, 0x95, 0x9f, 0xdb, 0x63, 0x84, 0xff, 0xae, 0x23, 0x23, 0x13, 0xe2,
+	0xba, 0xf0, 0x6f, 0x20, 0xdb, 0x71, 0xa8, 0x44, 0x7a, 0xb7, 0x45, 0xd6, 0xe7, 0xf3, 0xde, 0xd7,
+	0xce, 0x7b, 0xe8, 0xe9, 0x3c, 0x95, 0x8b, 0xd5, 0x24, 0x4c, 0x78, 0x1e, 0x4d, 0x79, 0x92, 0x31,
+	0x11, 0xc1, 0x45, 0x2c, 0xf2, 0x2c, 0x95, 0x51, 0xbc, 0x4c, 0x23, 0x28, 0xe2, 0x25, 0x2c, 0xb8,
+	0x0c, 0x97, 0x82, 0x4b, 0x8e, 0xb1, 0x61, 0x42, 0xcb, 0x84, 0xeb, 0xe7, 0xdd, 0x27, 0xd7, 0x94,
+	0xe0, 0x93, 0xcf, 0x2c, 0x91, 0x60, 0x2a, 0x74, 0x1f, 0x5f, 0x43, 0x8b, 0x78, 0x56, 0x36, 0xeb,
+	0xde, 0x99, 0xf3, 0x39, 0xd7, 0x9f, 0x91, 0xfa, 0x32, 0xa7, 0xfd, 0xef, 0x4d, 0x74, 0x63, 0x2c,
+	0xb9, 0x60, 0xe3, 0x32, 0x1a, 0x0e, 0x51, 0xab, 0xe0, 0x53, 0x06, 0xc4, 0xed, 0x35, 0x06, 0x87,
+	0x43, 0x12, 0xfe, 0x1f, 0x32, 0x3c, 0xe3, 0x53, 0x46, 0x0d, 0x86, 0x5f, 0xa1, 0x0e, 0x30, 0xb1,
+	0x4e, 0x13, 0x06, 0xc4, 0xd3, 0xca, 0xdd, 0x3a, 0x65, 0x6c, 0x18, 0x5a, 0xc1, 0x4a, 0x2c, 0x98,
+	0xbc, 0xe0, 0x22, 0x03, 0xd2, 0xd8, 0x2f, 0x9e, 0x19, 0x86, 0x56, 0xb0, 0x4a, 0x28, 0x63, 0xc8,
+	0x80, 0x34, 0xf7, 0x27, 0xfc, 0x18, 0x43, 0x46, 0x0d, 0xa6, 0x1a, 0x25, 0x5f, 0x56, 0x20, 0x99,
+	0x00, 0xd2, 0xda, 0xdf, 0xe8, 0xd4, 0x30, 0xb4, 0x82, 0xf1, 0x4b, 0xe4, 0x03, 0x4b, 0x04, 0x93,
+	0x40, 0xda, 0xda, 0xeb, 0xd6, 0xdf, 0x4c, 0x21, 0xd4, 0xa2, 0xf8, 0x0d, 0x3a, 0x10, 0x0c, 0xf8,
+	0x4a, 0xa8, 0x17, 0xf1, 0xb5, 0x77, 0x5c, 0xe7, 0xd1, 0x12, 0xa2, 0xff, 0x70, 0x7c, 0x82, 0x10,
+	0xfb, 0x2a, 0x59, 0x01, 0x29, 0x2f, 0x80, 0x74, 0xb4, 0x7c, 0xaf, 0x4e, 0x7e, 0x67, 0x29, 0xba,
+	0x23, 0xa8, 0xc0, 0x09, 0x2f, 0x66, 0xe9, 0x1c, 0xc8, 0xc1, 0xfe, 0xc0, 0xa7, 0x1a, 0xa1, 0x16,
+	0xed, 0xa7, 0xe8, 0x56, 0x79, 0xf7, 0x6a, 0x08, 0x5e, 0x23, 0x3f, 0x67, 0xf9, 0x44, 0xbd, 0x98,
+	0x19, 0x83, 0xa0, 0xf6, 0x06, 0xf1, 0x4c, 0x7e, 0xd0, 0x18, 0xb5, 0x38, 0x3e, 0x46, 0xbe, 0x60,
+	0x39, 0x5f, 0xb3, 0xa9, 0x9e, 0x86, 0xe6, 0xc8, 0x3b, 0x72, 0xa8, 0x3d, 0xea, 0xff, 0x71, 0x51,
+	0xa7, 0x6a, 0xf2, 0x16, 0xf9, 0x6b, 0x26, 0x54, 0x72, 0xe2, 0xf6, 0xdc, 0xc1, 0xcd, 0xe1, 0xa3,
+	0xda, 0xe7, 0xb5, 0x3b, 0x73, 0x6e, 0x58, 0x6a, 0x25, 0xfc, 0x1e, 0xa1, 0xb2, 0xeb, 0x22, 0x5d,
+	0x12, 0xaf, 0xe7, 0x0e, 0x0e, 0x87, 0x0f, 0xaf, 0xf8, 0xb3, 0xb6, 0xd2, 0xa8, 0xb9, 0xf9, 0x75,
+	0xdf, 0xa1, 0x3b, 0x32, 0x3e, 0x41, 0x2d, 0x50, 0x5b, 0x40, 0x1a, 0xba, 0xca, 0x83, 0xda, 0x20,
+	0xbb, 0x6b, 0x52, 0xd6, 0x30, 0x56, 0xff, 0x36, 0xf2, 0xcb, 0x74, 0xb8, 0x8d, 0xbc, 0xf3, 0x67,
+	0x47, 0xce, 0x88, 0x6c, 0x2e, 0x03, 0xe7, 0xe7, 0x65, 0xe0, 0x7c, 0xdb, 0x06, 0xee, 0x66, 0x1b,
+	0xb8, 0x3f, 0xb6, 0x81, 0xfb, 0x7b, 0x1b, 0xb8, 0x9f, 0xbc, 0x49, 0x5b, 0xef, 0xde, 0x8b, 0xbf,
+	0x01, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xbe, 0x47, 0xec, 0x2f, 0x04, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/snapshot.proto b/vendor/github.com/docker/swarmkit/api/snapshot.proto
index 713649c..91e9592 100644
--- a/vendor/github.com/docker/swarmkit/api/snapshot.proto
+++ b/vendor/github.com/docker/swarmkit/api/snapshot.proto
@@ -2,8 +2,8 @@
 
 package docker.swarmkit.v1;
 
-import "objects.proto";
-import "raft.proto";
+import "github.com/docker/swarmkit/api/objects.proto";
+import "github.com/docker/swarmkit/api/raft.proto";
 import weak "gogoproto/gogo.proto";
 
 // StoreSnapshot is used to store snapshots of the store.
diff --git a/vendor/github.com/docker/swarmkit/api/specs.pb.go b/vendor/github.com/docker/swarmkit/api/specs.pb.go
index bb9b0db..bda30a3 100644
--- a/vendor/github.com/docker/swarmkit/api/specs.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/specs.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: specs.proto
+// source: github.com/docker/swarmkit/api/specs.proto
 // DO NOT EDIT!
 
 package api
@@ -107,7 +107,7 @@
 	return proto.EnumName(EndpointSpec_ResolutionMode_name, int32(x))
 }
 func (EndpointSpec_ResolutionMode) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptorSpecs, []int{8, 0}
+	return fileDescriptorSpecs, []int{9, 0}
 }
 
 type NodeSpec struct {
@@ -310,6 +310,15 @@
 	// using the same reconciliation-based mechanism that performs rolling
 	// updates.
 	ForceUpdate uint64 `protobuf:"varint,9,opt,name=force_update,json=forceUpdate,proto3" json:"force_update,omitempty"`
+	// ResourceReferences provides a generic way to specify resources that
+	// are used by this task, and should be sent down to agents along with
+	// the task. Inside the runtime field there may be more specific
+	// information about how to use the resource, but ResourceReferences
+	// establishes the relationship at the store level, and instructs the
+	// dispatcher to send the related objects.
+	//
+	// ResourceReferences is a list of ResourceReferences used by the task.
+	ResourceReferences []ResourceReference `protobuf:"bytes,11,rep,name=resource_references,json=resourceReferences" json:"resource_references"`
 }
 
 func (m *TaskSpec) Reset()                    { *m = TaskSpec{} }
@@ -457,6 +466,15 @@
 	return n
 }
 
+type ResourceReference struct {
+	ResourceID   string       `protobuf:"bytes,1,opt,name=resource_id,json=resourceId,proto3" json:"resource_id,omitempty"`
+	ResourceType ResourceType `protobuf:"varint,2,opt,name=resource_type,json=resourceType,proto3,enum=docker.swarmkit.v1.ResourceType" json:"resource_type,omitempty"`
+}
+
+func (m *ResourceReference) Reset()                    { *m = ResourceReference{} }
+func (*ResourceReference) ProtoMessage()               {}
+func (*ResourceReference) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{5} }
+
 type GenericRuntimeSpec struct {
 	Kind    string                `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"`
 	Payload *google_protobuf3.Any `protobuf:"bytes,2,opt,name=payload" json:"payload,omitempty"`
@@ -464,7 +482,7 @@
 
 func (m *GenericRuntimeSpec) Reset()                    { *m = GenericRuntimeSpec{} }
 func (*GenericRuntimeSpec) ProtoMessage()               {}
-func (*GenericRuntimeSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{5} }
+func (*GenericRuntimeSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{6} }
 
 // NetworkAttachmentSpec specifies runtime parameters required to attach
 // a container to a network.
@@ -476,7 +494,7 @@
 
 func (m *NetworkAttachmentSpec) Reset()                    { *m = NetworkAttachmentSpec{} }
 func (*NetworkAttachmentSpec) ProtoMessage()               {}
-func (*NetworkAttachmentSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{6} }
+func (*NetworkAttachmentSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{7} }
 
 // Container specifies runtime parameters for a container.
 type ContainerSpec struct {
@@ -571,7 +589,7 @@
 
 func (m *ContainerSpec) Reset()                    { *m = ContainerSpec{} }
 func (*ContainerSpec) ProtoMessage()               {}
-func (*ContainerSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{7} }
+func (*ContainerSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{8} }
 
 // PullOptions allows one to parameterize an image pull.
 type ContainerSpec_PullOptions struct {
@@ -585,7 +603,7 @@
 func (m *ContainerSpec_PullOptions) Reset()      { *m = ContainerSpec_PullOptions{} }
 func (*ContainerSpec_PullOptions) ProtoMessage() {}
 func (*ContainerSpec_PullOptions) Descriptor() ([]byte, []int) {
-	return fileDescriptorSpecs, []int{7, 1}
+	return fileDescriptorSpecs, []int{8, 1}
 }
 
 // DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)
@@ -603,7 +621,7 @@
 
 func (m *ContainerSpec_DNSConfig) Reset()                    { *m = ContainerSpec_DNSConfig{} }
 func (*ContainerSpec_DNSConfig) ProtoMessage()               {}
-func (*ContainerSpec_DNSConfig) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{7, 2} }
+func (*ContainerSpec_DNSConfig) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{8, 2} }
 
 // EndpointSpec defines the properties that can be configured to
 // access and loadbalance the service.
@@ -616,7 +634,7 @@
 
 func (m *EndpointSpec) Reset()                    { *m = EndpointSpec{} }
 func (*EndpointSpec) ProtoMessage()               {}
-func (*EndpointSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{8} }
+func (*EndpointSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{9} }
 
 // NetworkSpec specifies user defined network parameters.
 type NetworkSpec struct {
@@ -651,7 +669,7 @@
 
 func (m *NetworkSpec) Reset()                    { *m = NetworkSpec{} }
 func (*NetworkSpec) ProtoMessage()               {}
-func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{9} }
+func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{10} }
 
 type isNetworkSpec_ConfigFrom interface {
 	isNetworkSpec_ConfigFrom()
@@ -753,7 +771,7 @@
 
 func (m *ClusterSpec) Reset()                    { *m = ClusterSpec{} }
 func (*ClusterSpec) ProtoMessage()               {}
-func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{10} }
+func (*ClusterSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{11} }
 
 // SecretSpec specifies a user-provided secret.
 type SecretSpec struct {
@@ -772,7 +790,7 @@
 
 func (m *SecretSpec) Reset()                    { *m = SecretSpec{} }
 func (*SecretSpec) ProtoMessage()               {}
-func (*SecretSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{11} }
+func (*SecretSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{12} }
 
 // ConfigSpec specifies user-provided configuration files.
 type ConfigSpec struct {
@@ -791,7 +809,7 @@
 
 func (m *ConfigSpec) Reset()                    { *m = ConfigSpec{} }
 func (*ConfigSpec) ProtoMessage()               {}
-func (*ConfigSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{12} }
+func (*ConfigSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{13} }
 
 func init() {
 	proto.RegisterType((*NodeSpec)(nil), "docker.swarmkit.v1.NodeSpec")
@@ -799,6 +817,7 @@
 	proto.RegisterType((*ReplicatedService)(nil), "docker.swarmkit.v1.ReplicatedService")
 	proto.RegisterType((*GlobalService)(nil), "docker.swarmkit.v1.GlobalService")
 	proto.RegisterType((*TaskSpec)(nil), "docker.swarmkit.v1.TaskSpec")
+	proto.RegisterType((*ResourceReference)(nil), "docker.swarmkit.v1.ResourceReference")
 	proto.RegisterType((*GenericRuntimeSpec)(nil), "docker.swarmkit.v1.GenericRuntimeSpec")
 	proto.RegisterType((*NetworkAttachmentSpec)(nil), "docker.swarmkit.v1.NetworkAttachmentSpec")
 	proto.RegisterType((*ContainerSpec)(nil), "docker.swarmkit.v1.ContainerSpec")
@@ -946,6 +965,13 @@
 		}
 	}
 
+	if o.ResourceReferences != nil {
+		m.ResourceReferences = make([]ResourceReference, len(o.ResourceReferences))
+		for i := range m.ResourceReferences {
+			github_com_docker_swarmkit_api_deepcopy.Copy(&m.ResourceReferences[i], &o.ResourceReferences[i])
+		}
+	}
+
 	if o.Runtime != nil {
 		switch o.Runtime.(type) {
 		case *TaskSpec_Attachment:
@@ -971,6 +997,21 @@
 
 }
 
+func (m *ResourceReference) Copy() *ResourceReference {
+	if m == nil {
+		return nil
+	}
+	o := &ResourceReference{}
+	o.CopyFrom(m)
+	return o
+}
+
+func (m *ResourceReference) CopyFrom(src interface{}) {
+
+	o := src.(*ResourceReference)
+	*m = *o
+}
+
 func (m *GenericRuntimeSpec) Copy() *GenericRuntimeSpec {
 	if m == nil {
 		return nil
@@ -1544,6 +1585,18 @@
 		i++
 		i = encodeVarintSpecs(dAtA, i, uint64(m.ForceUpdate))
 	}
+	if len(m.ResourceReferences) > 0 {
+		for _, msg := range m.ResourceReferences {
+			dAtA[i] = 0x5a
+			i++
+			i = encodeVarintSpecs(dAtA, i, uint64(msg.Size()))
+			n, err := msg.MarshalTo(dAtA[i:])
+			if err != nil {
+				return 0, err
+			}
+			i += n
+		}
+	}
 	return i, nil
 }
 
@@ -1589,6 +1642,35 @@
 	}
 	return i, nil
 }
+func (m *ResourceReference) Marshal() (dAtA []byte, err error) {
+	size := m.Size()
+	dAtA = make([]byte, size)
+	n, err := m.MarshalTo(dAtA)
+	if err != nil {
+		return nil, err
+	}
+	return dAtA[:n], nil
+}
+
+func (m *ResourceReference) MarshalTo(dAtA []byte) (int, error) {
+	var i int
+	_ = i
+	var l int
+	_ = l
+	if len(m.ResourceID) > 0 {
+		dAtA[i] = 0xa
+		i++
+		i = encodeVarintSpecs(dAtA, i, uint64(len(m.ResourceID)))
+		i += copy(dAtA[i:], m.ResourceID)
+	}
+	if m.ResourceType != 0 {
+		dAtA[i] = 0x10
+		i++
+		i = encodeVarintSpecs(dAtA, i, uint64(m.ResourceType))
+	}
+	return i, nil
+}
+
 func (m *GenericRuntimeSpec) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -2458,6 +2540,12 @@
 	if m.ForceUpdate != 0 {
 		n += 1 + sovSpecs(uint64(m.ForceUpdate))
 	}
+	if len(m.ResourceReferences) > 0 {
+		for _, e := range m.ResourceReferences {
+			l = e.Size()
+			n += 1 + l + sovSpecs(uint64(l))
+		}
+	}
 	return n
 }
 
@@ -2488,6 +2576,19 @@
 	}
 	return n
 }
+func (m *ResourceReference) Size() (n int) {
+	var l int
+	_ = l
+	l = len(m.ResourceID)
+	if l > 0 {
+		n += 1 + l + sovSpecs(uint64(l))
+	}
+	if m.ResourceType != 0 {
+		n += 1 + sovSpecs(uint64(m.ResourceType))
+	}
+	return n
+}
+
 func (m *GenericRuntimeSpec) Size() (n int) {
 	var l int
 	_ = l
@@ -2861,6 +2962,7 @@
 		`LogDriver:` + strings.Replace(fmt.Sprintf("%v", this.LogDriver), "Driver", "Driver", 1) + `,`,
 		`Networks:` + strings.Replace(fmt.Sprintf("%v", this.Networks), "NetworkAttachmentConfig", "NetworkAttachmentConfig", 1) + `,`,
 		`ForceUpdate:` + fmt.Sprintf("%v", this.ForceUpdate) + `,`,
+		`ResourceReferences:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ResourceReferences), "ResourceReference", "ResourceReference", 1), `&`, ``, 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -2895,6 +2997,17 @@
 	}, "")
 	return s
 }
+func (this *ResourceReference) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&ResourceReference{`,
+		`ResourceID:` + fmt.Sprintf("%v", this.ResourceID) + `,`,
+		`ResourceType:` + fmt.Sprintf("%v", this.ResourceType) + `,`,
+		`}`,
+	}, "")
+	return s
+}
 func (this *GenericRuntimeSpec) String() string {
 	if this == nil {
 		return "nil"
@@ -3934,6 +4047,135 @@
 			}
 			m.Runtime = &TaskSpec_Generic{v}
 			iNdEx = postIndex
+		case 11:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ResourceReferences", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpecs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthSpecs
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.ResourceReferences = append(m.ResourceReferences, ResourceReference{})
+			if err := m.ResourceReferences[len(m.ResourceReferences)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			iNdEx = preIndex
+			skippy, err := skipSpecs(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if skippy < 0 {
+				return ErrInvalidLengthSpecs
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			iNdEx += skippy
+		}
+	}
+
+	if iNdEx > l {
+		return io.ErrUnexpectedEOF
+	}
+	return nil
+}
+func (m *ResourceReference) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		preIndex := iNdEx
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if shift >= 64 {
+				return ErrIntOverflowSpecs
+			}
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		if wireType == 4 {
+			return fmt.Errorf("proto: ResourceReference: wiretype end group for non-group")
+		}
+		if fieldNum <= 0 {
+			return fmt.Errorf("proto: ResourceReference: illegal tag %d (wire type %d)", fieldNum, wire)
+		}
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ResourceID", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpecs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthSpecs
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.ResourceID = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 2:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field ResourceType", wireType)
+			}
+			m.ResourceType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowSpecs
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.ResourceType |= (ResourceType(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
 			skippy, err := skipSpecs(dAtA[iNdEx:])
@@ -6207,126 +6449,132 @@
 	ErrIntOverflowSpecs   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/specs.proto", fileDescriptorSpecs) }
 
 var fileDescriptorSpecs = []byte{
-	// 1880 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x73, 0x1b, 0x49,
-	0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xdc, 0x24, 0x61, 0xac, 0xb0, 0xb2, 0xa2, 0x0d,
-	0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0xbb, 0x61, 0x01, 0xc9, 0x12, 0x8e, 0x31, 0x76, 0x54,
-	0x6d, 0x6f, 0x20, 0x27, 0x55, 0x7b, 0xa6, 0x2d, 0x4d, 0x79, 0xd4, 0x3d, 0xf4, 0xf4, 0x68, 0x4b,
-	0x37, 0x8e, 0x5b, 0xb9, 0x72, 0x76, 0x71, 0xa0, 0xf8, 0x5f, 0x72, 0xa4, 0x38, 0xc1, 0xc5, 0x45,
-	0xfc, 0x2f, 0x70, 0xe3, 0x02, 0xd5, 0x3d, 0x3d, 0xd2, 0x28, 0x19, 0xc7, 0xa9, 0x22, 0x87, 0xbd,
-	0x75, 0xbf, 0xfe, 0xbe, 0xd7, 0xdd, 0xaf, 0xbf, 0xee, 0xf7, 0x1a, 0xac, 0x30, 0xa0, 0x4e, 0xd8,
-	0x0a, 0x04, 0x97, 0x1c, 0x21, 0x97, 0x3b, 0xe7, 0x54, 0xb4, 0xc2, 0xaf, 0x89, 0x18, 0x9f, 0x7b,
-	0xb2, 0x35, 0xf9, 0x71, 0xcd, 0x92, 0xd3, 0x80, 0x1a, 0x40, 0xed, 0xce, 0x90, 0x0f, 0xb9, 0x6e,
-	0x6e, 0xab, 0x96, 0xb1, 0xd6, 0x87, 0x9c, 0x0f, 0x7d, 0xba, 0xad, 0x7b, 0xa7, 0xd1, 0xd9, 0xb6,
-	0x1b, 0x09, 0x22, 0x3d, 0xce, 0xcc, 0xf8, 0xc6, 0x9b, 0xe3, 0x84, 0x4d, 0xe3, 0xa1, 0xe6, 0x45,
-	0x1e, 0x4a, 0x47, 0xdc, 0xa5, 0xc7, 0x01, 0x75, 0xd0, 0x1e, 0x58, 0x84, 0x31, 0x2e, 0x35, 0x37,
-	0xb4, 0x73, 0x8d, 0xdc, 0x96, 0xb5, 0xb3, 0xd9, 0x7a, 0x7b, 0x51, 0xad, 0xf6, 0x1c, 0xd6, 0xc9,
-	0xbf, 0xba, 0xdc, 0x5c, 0xc2, 0x69, 0x26, 0xfa, 0x25, 0x54, 0x5c, 0x1a, 0x7a, 0x82, 0xba, 0x03,
-	0xc1, 0x7d, 0x6a, 0x2f, 0x37, 0x72, 0x5b, 0xb7, 0x76, 0xbe, 0x97, 0xe5, 0x49, 0x4d, 0x8e, 0xb9,
-	0x4f, 0xb1, 0x65, 0x18, 0xaa, 0x83, 0xf6, 0x00, 0xc6, 0x74, 0x7c, 0x4a, 0x45, 0x38, 0xf2, 0x02,
-	0x7b, 0x45, 0xd3, 0x7f, 0x70, 0x1d, 0x5d, 0xad, 0xbd, 0x75, 0x38, 0x83, 0xe3, 0x14, 0x15, 0x1d,
-	0x42, 0x85, 0x4c, 0x88, 0xe7, 0x93, 0x53, 0xcf, 0xf7, 0xe4, 0xd4, 0xce, 0x6b, 0x57, 0x9f, 0xbc,
-	0xd3, 0x55, 0x3b, 0x45, 0xc0, 0x0b, 0xf4, 0xa6, 0x0b, 0x30, 0x9f, 0x08, 0x3d, 0x82, 0x62, 0xbf,
-	0x77, 0xd4, 0xdd, 0x3f, 0xda, 0xab, 0x2e, 0xd5, 0x36, 0x5e, 0x5e, 0x34, 0xee, 0x2a, 0x1f, 0x73,
-	0x40, 0x9f, 0x32, 0xd7, 0x63, 0x43, 0xb4, 0x05, 0xa5, 0xf6, 0xee, 0x6e, 0xaf, 0x7f, 0xd2, 0xeb,
-	0x56, 0x73, 0xb5, 0xda, 0xcb, 0x8b, 0xc6, 0xbd, 0x45, 0x60, 0xdb, 0x71, 0x68, 0x20, 0xa9, 0x5b,
-	0xcb, 0x7f, 0xf3, 0x97, 0xfa, 0x52, 0xf3, 0x9b, 0x1c, 0x54, 0xd2, 0x8b, 0x40, 0x8f, 0xa0, 0xd0,
-	0xde, 0x3d, 0xd9, 0x7f, 0xde, 0xab, 0x2e, 0xcd, 0xe9, 0x69, 0x44, 0xdb, 0x91, 0xde, 0x84, 0xa2,
-	0x87, 0xb0, 0xda, 0x6f, 0x7f, 0x75, 0xdc, 0xab, 0xe6, 0xe6, 0xcb, 0x49, 0xc3, 0xfa, 0x24, 0x0a,
-	0x35, 0xaa, 0x8b, 0xdb, 0xfb, 0x47, 0xd5, 0xe5, 0x6c, 0x54, 0x57, 0x10, 0x8f, 0x99, 0xa5, 0xfc,
-	0x39, 0x0f, 0xd6, 0x31, 0x15, 0x13, 0xcf, 0xf9, 0xc0, 0x12, 0xf9, 0x0c, 0xf2, 0x92, 0x84, 0xe7,
-	0x5a, 0x1a, 0x56, 0xb6, 0x34, 0x4e, 0x48, 0x78, 0xae, 0x26, 0x35, 0x74, 0x8d, 0x57, 0xca, 0x10,
-	0x34, 0xf0, 0x3d, 0x87, 0x48, 0xea, 0x6a, 0x65, 0x58, 0x3b, 0xdf, 0xcf, 0x62, 0xe3, 0x19, 0xca,
-	0xac, 0xff, 0xe9, 0x12, 0x4e, 0x51, 0xd1, 0x13, 0x28, 0x0c, 0x7d, 0x7e, 0x4a, 0x7c, 0xad, 0x09,
-	0x6b, 0xe7, 0x41, 0x96, 0x93, 0x3d, 0x8d, 0x98, 0x3b, 0x30, 0x14, 0xf4, 0x18, 0x0a, 0x51, 0xe0,
-	0x12, 0x49, 0xed, 0x82, 0x26, 0x37, 0xb2, 0xc8, 0x5f, 0x69, 0xc4, 0x2e, 0x67, 0x67, 0xde, 0x10,
-	0x1b, 0x3c, 0x3a, 0x80, 0x12, 0xa3, 0xf2, 0x6b, 0x2e, 0xce, 0x43, 0xbb, 0xd8, 0x58, 0xd9, 0xb2,
-	0x76, 0x3e, 0xcd, 0x14, 0x63, 0x8c, 0x69, 0x4b, 0x49, 0x9c, 0xd1, 0x98, 0x32, 0x19, 0xbb, 0xe9,
-	0x2c, 0xdb, 0x39, 0x3c, 0x73, 0x80, 0x7e, 0x0e, 0x25, 0xca, 0xdc, 0x80, 0x7b, 0x4c, 0xda, 0xa5,
-	0xeb, 0x17, 0xd2, 0x33, 0x18, 0x15, 0x4c, 0x3c, 0x63, 0x28, 0xb6, 0xe0, 0xbe, 0x7f, 0x4a, 0x9c,
-	0x73, 0xbb, 0xfc, 0x9e, 0xdb, 0x98, 0x31, 0x3a, 0x05, 0xc8, 0x8f, 0xb9, 0x4b, 0x9b, 0xdb, 0xb0,
-	0xfe, 0x56, 0xa8, 0x51, 0x0d, 0x4a, 0x26, 0xd4, 0xb1, 0x46, 0xf2, 0x78, 0xd6, 0x6f, 0xde, 0x86,
-	0xb5, 0x85, 0xb0, 0x36, 0xff, 0x9e, 0x87, 0x52, 0x72, 0xd6, 0xa8, 0x0d, 0x65, 0x87, 0x33, 0x49,
-	0x3c, 0x46, 0x85, 0x91, 0x57, 0xe6, 0xc9, 0xec, 0x26, 0x20, 0xc5, 0x7a, 0xba, 0x84, 0xe7, 0x2c,
-	0xf4, 0x6b, 0x28, 0x0b, 0x1a, 0xf2, 0x48, 0x38, 0x34, 0x34, 0xfa, 0xda, 0xca, 0x56, 0x48, 0x0c,
-	0xc2, 0xf4, 0x0f, 0x91, 0x27, 0xa8, 0x8a, 0x72, 0x88, 0xe7, 0x54, 0xf4, 0x04, 0x8a, 0x82, 0x86,
-	0x92, 0x08, 0xf9, 0x2e, 0x89, 0xe0, 0x18, 0xd2, 0xe7, 0xbe, 0xe7, 0x4c, 0x71, 0xc2, 0x40, 0x4f,
-	0xa0, 0x1c, 0xf8, 0xc4, 0xd1, 0x5e, 0xed, 0x55, 0x4d, 0xff, 0x28, 0x8b, 0xde, 0x4f, 0x40, 0x78,
-	0x8e, 0x47, 0x9f, 0x03, 0xf8, 0x7c, 0x38, 0x70, 0x85, 0x37, 0xa1, 0xc2, 0x48, 0xac, 0x96, 0xc5,
-	0xee, 0x6a, 0x04, 0x2e, 0xfb, 0x7c, 0x18, 0x37, 0xd1, 0xde, 0xff, 0xa5, 0xaf, 0x94, 0xb6, 0x0e,
-	0x00, 0xc8, 0x6c, 0xd4, 0xa8, 0xeb, 0x93, 0xf7, 0x72, 0x65, 0x4e, 0x24, 0x45, 0x47, 0x0f, 0xa0,
-	0x72, 0xc6, 0x85, 0x43, 0x07, 0xe6, 0xd6, 0x94, 0xb5, 0x26, 0x2c, 0x6d, 0x8b, 0xf5, 0x85, 0x3a,
-	0x50, 0x1c, 0x52, 0x46, 0x85, 0xe7, 0xd8, 0xa0, 0x27, 0x7b, 0x94, 0x79, 0x21, 0x63, 0x08, 0x8e,
-	0x98, 0xf4, 0xc6, 0xd4, 0xcc, 0x94, 0x10, 0x3b, 0x65, 0x28, 0x8a, 0x78, 0xa4, 0xf9, 0x7b, 0x40,
-	0x6f, 0x63, 0x11, 0x82, 0xfc, 0xb9, 0xc7, 0x5c, 0x2d, 0xac, 0x32, 0xd6, 0x6d, 0xd4, 0x82, 0x62,
-	0x40, 0xa6, 0x3e, 0x27, 0xae, 0x11, 0xcb, 0x9d, 0x56, 0x9c, 0x2f, 0x5b, 0x49, 0xbe, 0x6c, 0xb5,
-	0xd9, 0x14, 0x27, 0xa0, 0xe6, 0x01, 0xdc, 0xcd, 0xdc, 0x32, 0xda, 0x81, 0xca, 0x4c, 0x84, 0x03,
-	0xcf, 0x4c, 0xd2, 0xb9, 0x7d, 0x75, 0xb9, 0x69, 0xcd, 0xd4, 0xba, 0xdf, 0xc5, 0xd6, 0x0c, 0xb4,
-	0xef, 0x36, 0xff, 0x54, 0x86, 0xb5, 0x05, 0x29, 0xa3, 0x3b, 0xb0, 0xea, 0x8d, 0xc9, 0x90, 0x9a,
-	0x35, 0xc6, 0x1d, 0xd4, 0x83, 0x82, 0x4f, 0x4e, 0xa9, 0xaf, 0x04, 0xad, 0x0e, 0xf5, 0x47, 0x37,
-	0xde, 0x89, 0xd6, 0x6f, 0x35, 0xbe, 0xc7, 0xa4, 0x98, 0x62, 0x43, 0x46, 0x36, 0x14, 0x1d, 0x3e,
-	0x1e, 0x13, 0xa6, 0x9e, 0xce, 0x95, 0xad, 0x32, 0x4e, 0xba, 0x2a, 0x32, 0x44, 0x0c, 0x43, 0x3b,
-	0xaf, 0xcd, 0xba, 0x8d, 0xaa, 0xb0, 0x42, 0xd9, 0xc4, 0x5e, 0xd5, 0x26, 0xd5, 0x54, 0x16, 0xd7,
-	0x8b, 0x15, 0x59, 0xc6, 0xaa, 0xa9, 0x78, 0x51, 0x48, 0x85, 0x5d, 0x8c, 0x23, 0xaa, 0xda, 0xe8,
-	0x67, 0x50, 0x18, 0xf3, 0x88, 0xc9, 0xd0, 0x2e, 0xe9, 0xc5, 0x6e, 0x64, 0x2d, 0xf6, 0x50, 0x21,
-	0xcc, 0xd3, 0x6e, 0xe0, 0xa8, 0x07, 0xeb, 0xa1, 0xe4, 0xc1, 0x60, 0x28, 0x88, 0x43, 0x07, 0x01,
-	0x15, 0x1e, 0x77, 0xcd, 0xd3, 0xb4, 0xf1, 0xd6, 0xa1, 0x74, 0x4d, 0x91, 0x83, 0x6f, 0x2b, 0xce,
-	0x9e, 0xa2, 0xf4, 0x35, 0x03, 0xf5, 0xa1, 0x12, 0x44, 0xbe, 0x3f, 0xe0, 0x41, 0x9c, 0xa5, 0x62,
-	0x3d, 0xbd, 0x47, 0xc8, 0xfa, 0x91, 0xef, 0x3f, 0x8b, 0x49, 0xd8, 0x0a, 0xe6, 0x1d, 0x74, 0x0f,
-	0x0a, 0x43, 0xc1, 0xa3, 0x20, 0xb4, 0x2d, 0x1d, 0x0c, 0xd3, 0x43, 0x5f, 0x42, 0x31, 0xa4, 0x8e,
-	0xa0, 0x32, 0xb4, 0x2b, 0x7a, 0xab, 0x1f, 0x67, 0x4d, 0x72, 0xac, 0x21, 0x98, 0x9e, 0x51, 0x41,
-	0x99, 0x43, 0x71, 0xc2, 0x41, 0x1b, 0xb0, 0x22, 0xe5, 0xd4, 0x5e, 0x6b, 0xe4, 0xb6, 0x4a, 0x9d,
-	0xe2, 0xd5, 0xe5, 0xe6, 0xca, 0xc9, 0xc9, 0x0b, 0xac, 0x6c, 0xea, 0x05, 0x1d, 0xf1, 0x50, 0x32,
-	0x32, 0xa6, 0xf6, 0x2d, 0x1d, 0xdb, 0x59, 0x1f, 0xbd, 0x00, 0x70, 0x59, 0x38, 0x70, 0xf4, 0x95,
-	0xb5, 0x6f, 0xeb, 0xdd, 0x7d, 0x7a, 0xf3, 0xee, 0xba, 0x47, 0xc7, 0x26, 0x8b, 0xac, 0x5d, 0x5d,
-	0x6e, 0x96, 0x67, 0x5d, 0x5c, 0x76, 0x59, 0x18, 0x37, 0x51, 0x07, 0xac, 0x11, 0x25, 0xbe, 0x1c,
-	0x39, 0x23, 0xea, 0x9c, 0xdb, 0xd5, 0xeb, 0xd3, 0xc2, 0x53, 0x0d, 0x33, 0x1e, 0xd2, 0x24, 0xa5,
-	0x60, 0xb5, 0xd4, 0xd0, 0x5e, 0xd7, 0xb1, 0x8a, 0x3b, 0xe8, 0x23, 0x00, 0x1e, 0x50, 0x36, 0x08,
-	0xa5, 0xeb, 0x31, 0x1b, 0xa9, 0x2d, 0xe3, 0xb2, 0xb2, 0x1c, 0x2b, 0x03, 0xba, 0xaf, 0x1e, 0x6d,
-	0xe2, 0x0e, 0x38, 0xf3, 0xa7, 0xf6, 0x77, 0xf4, 0x68, 0x49, 0x19, 0x9e, 0x31, 0x7f, 0x8a, 0x36,
-	0xc1, 0xd2, 0xba, 0x08, 0xbd, 0x21, 0x23, 0xbe, 0x7d, 0x47, 0xc7, 0x03, 0x94, 0xe9, 0x58, 0x5b,
-	0xd4, 0x39, 0xc4, 0xd1, 0x08, 0xed, 0xbb, 0xd7, 0x9f, 0x83, 0x59, 0xec, 0xfc, 0x1c, 0x0c, 0x07,
-	0xfd, 0x02, 0x20, 0x10, 0xde, 0xc4, 0xf3, 0xe9, 0x90, 0x86, 0xf6, 0x3d, 0xbd, 0xe9, 0x7a, 0xe6,
-	0x6b, 0x3d, 0x43, 0xe1, 0x14, 0xa3, 0xf6, 0x39, 0x58, 0xa9, 0xdb, 0xa6, 0x6e, 0xc9, 0x39, 0x9d,
-	0x9a, 0x0b, 0xac, 0x9a, 0x2a, 0x24, 0x13, 0xe2, 0x47, 0x71, 0x25, 0x5c, 0xc6, 0x71, 0xe7, 0x8b,
-	0xe5, 0xc7, 0xb9, 0xda, 0x0e, 0x58, 0x29, 0xd5, 0xa1, 0x8f, 0x61, 0x4d, 0xd0, 0xa1, 0x17, 0x4a,
-	0x31, 0x1d, 0x90, 0x48, 0x8e, 0xec, 0x5f, 0x69, 0x42, 0x25, 0x31, 0xb6, 0x23, 0x39, 0xaa, 0x0d,
-	0x60, 0x7e, 0x78, 0xa8, 0x01, 0x96, 0x12, 0x45, 0x48, 0xc5, 0x84, 0x0a, 0x95, 0x6d, 0x55, 0xcc,
-	0xd3, 0x26, 0x25, 0xde, 0x90, 0x12, 0xe1, 0x8c, 0xf4, 0xdb, 0x51, 0xc6, 0xa6, 0xa7, 0x1e, 0x83,
-	0xe4, 0x86, 0x98, 0xc7, 0xc0, 0x74, 0x9b, 0xff, 0xce, 0x41, 0x25, 0x5d, 0x34, 0xa0, 0xdd, 0x38,
-	0xd9, 0xeb, 0x2d, 0xdd, 0xda, 0xd9, 0xbe, 0xa9, 0xc8, 0xd0, 0xa9, 0xd5, 0x8f, 0x94, 0xb3, 0x43,
-	0x55, 0xdf, 0x6b, 0x32, 0xfa, 0x29, 0xac, 0x06, 0x5c, 0xc8, 0xe4, 0x09, 0xcb, 0x0e, 0x30, 0x17,
-	0x49, 0x2a, 0x8a, 0xc1, 0xcd, 0x11, 0xdc, 0x5a, 0xf4, 0x86, 0x1e, 0xc2, 0xca, 0xf3, 0xfd, 0x7e,
-	0x75, 0xa9, 0x76, 0xff, 0xe5, 0x45, 0xe3, 0xbb, 0x8b, 0x83, 0xcf, 0x3d, 0x21, 0x23, 0xe2, 0xef,
-	0xf7, 0xd1, 0x0f, 0x61, 0xb5, 0x7b, 0x74, 0x8c, 0x71, 0x35, 0x57, 0xdb, 0x7c, 0x79, 0xd1, 0xb8,
-	0xbf, 0x88, 0x53, 0x43, 0x3c, 0x62, 0x2e, 0xe6, 0xa7, 0xb3, 0x5a, 0xf7, 0x3f, 0xcb, 0x60, 0x99,
-	0x97, 0xfd, 0x43, 0x7f, 0x87, 0xd6, 0xe2, 0x54, 0x9e, 0x5c, 0xd9, 0xe5, 0x1b, 0x33, 0x7a, 0x25,
-	0x26, 0x98, 0x33, 0x7e, 0x00, 0x15, 0x2f, 0x98, 0x7c, 0x36, 0xa0, 0x8c, 0x9c, 0xfa, 0xa6, 0xec,
-	0x2d, 0x61, 0x4b, 0xd9, 0x7a, 0xb1, 0x49, 0xbd, 0x17, 0x1e, 0x93, 0x54, 0x30, 0x53, 0xd0, 0x96,
-	0xf0, 0xac, 0x8f, 0xbe, 0x84, 0xbc, 0x17, 0x90, 0xb1, 0x29, 0x43, 0x32, 0x77, 0xb0, 0xdf, 0x6f,
-	0x1f, 0x1a, 0x0d, 0x76, 0x4a, 0x57, 0x97, 0x9b, 0x79, 0x65, 0xc0, 0x9a, 0x86, 0xea, 0x49, 0x25,
-	0xa0, 0x66, 0xd2, 0x6f, 0x7f, 0x09, 0xa7, 0x2c, 0x4a, 0x47, 0x1e, 0x1b, 0x0a, 0x1a, 0x86, 0x3a,
-	0x0b, 0x94, 0x70, 0xd2, 0x45, 0x35, 0x28, 0x9a, 0x7a, 0x42, 0x17, 0x10, 0x65, 0x95, 0xab, 0x8d,
-	0xa1, 0xb3, 0x06, 0x56, 0x1c, 0x8d, 0xc1, 0x99, 0xe0, 0xe3, 0xe6, 0x7f, 0xf3, 0x60, 0xed, 0xfa,
-	0x51, 0x28, 0x4d, 0x1a, 0xfc, 0x60, 0xc1, 0x7f, 0x01, 0xeb, 0x44, 0x7f, 0xaf, 0x08, 0x53, 0x39,
-	0x45, 0x97, 0x69, 0xe6, 0x00, 0x1e, 0x66, 0xba, 0x9b, 0x81, 0xe3, 0x92, 0xae, 0x53, 0x50, 0x3e,
-	0xed, 0x1c, 0xae, 0x92, 0x37, 0x46, 0xd0, 0x31, 0xac, 0x71, 0xe1, 0x8c, 0x68, 0x28, 0xe3, 0x4c,
-	0x64, 0xbe, 0x23, 0x99, 0x1f, 0xd5, 0x67, 0x69, 0xa0, 0x79, 0x86, 0xe3, 0xd5, 0x2e, 0xfa, 0x40,
-	0x8f, 0x21, 0x2f, 0xc8, 0x59, 0x52, 0x72, 0x66, 0x5e, 0x12, 0x4c, 0xce, 0xe4, 0x82, 0x0b, 0xcd,
-	0x40, 0xbf, 0x01, 0x70, 0xbd, 0x30, 0x20, 0xd2, 0x19, 0x51, 0x61, 0x0e, 0x3b, 0x73, 0x8b, 0xdd,
-	0x19, 0x6a, 0xc1, 0x4b, 0x8a, 0x8d, 0x0e, 0xa0, 0xec, 0x90, 0x44, 0xae, 0x85, 0xeb, 0xff, 0x68,
-	0xbb, 0x6d, 0xe3, 0xa2, 0xaa, 0x5c, 0x5c, 0x5d, 0x6e, 0x96, 0x12, 0x0b, 0x2e, 0x39, 0xc4, 0xc8,
-	0xf7, 0x00, 0xd6, 0xd4, 0xdf, 0x6d, 0xe0, 0xd2, 0x33, 0x12, 0xf9, 0x32, 0x96, 0xc9, 0x35, 0x69,
-	0x45, 0x7d, 0x04, 0xba, 0x06, 0x67, 0xd6, 0x55, 0x91, 0x29, 0x1b, 0xfa, 0x1d, 0xac, 0x53, 0xe6,
-	0x88, 0xa9, 0x16, 0x6b, 0xb2, 0xc2, 0xd2, 0xf5, 0x9b, 0xed, 0xcd, 0xc0, 0x0b, 0x9b, 0xad, 0xd2,
-	0x37, 0xec, 0xcd, 0x7f, 0xe6, 0x00, 0xe2, 0x4c, 0xfd, 0x61, 0x05, 0x88, 0x20, 0xef, 0x12, 0x49,
-	0xb4, 0xe6, 0x2a, 0x58, 0xb7, 0xd1, 0x17, 0x00, 0x92, 0x8e, 0x03, 0x9f, 0x48, 0x8f, 0x0d, 0x8d,
-	0x6c, 0xde, 0xf5, 0x1c, 0xa4, 0xd0, 0x68, 0x07, 0x0a, 0xe6, 0x63, 0x90, 0xbf, 0x91, 0x67, 0x90,
-	0xcd, 0xbf, 0xe6, 0x00, 0xe2, 0x6d, 0x7e, 0xab, 0xf7, 0xd6, 0xb1, 0x5f, 0xbd, 0xae, 0x2f, 0xfd,
-	0xe3, 0x75, 0x7d, 0xe9, 0x8f, 0x57, 0xf5, 0xdc, 0xab, 0xab, 0x7a, 0xee, 0x6f, 0x57, 0xf5, 0xdc,
-	0xbf, 0xae, 0xea, 0xb9, 0xd3, 0x82, 0xae, 0xfb, 0x7e, 0xf2, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff,
-	0xc1, 0xd8, 0x19, 0x9e, 0x30, 0x13, 0x00, 0x00,
+	// 1975 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x6f, 0x1b, 0xb9,
+	0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xc2, 0xcd, 0xa6, 0x13, 0xa5, 0x6b, 0x2b, 0xda,
+	0x6c, 0xea, 0xdd, 0x45, 0x25, 0xd4, 0x2d, 0xb6, 0xd9, 0x4d, 0xb7, 0xad, 0x64, 0xa9, 0x8e, 0x9b,
+	0xc6, 0x11, 0x68, 0x6f, 0xda, 0x00, 0x05, 0x04, 0x6a, 0x86, 0x1e, 0x0d, 0x3c, 0x1a, 0x4e, 0x39,
+	0x1c, 0x2d, 0x74, 0xeb, 0x71, 0x91, 0x1e, 0x7b, 0x0e, 0x7a, 0x28, 0x7a, 0xef, 0x9f, 0x91, 0x63,
+	0x8f, 0xed, 0xc5, 0xe8, 0xea, 0x5f, 0xe8, 0xad, 0x97, 0x16, 0xe4, 0x70, 0x46, 0xa3, 0x64, 0x6c,
+	0x07, 0x68, 0x0e, 0xbd, 0x91, 0x8f, 0xdf, 0xf7, 0x48, 0x3e, 0x7e, 0x8f, 0x7c, 0x84, 0x4f, 0x1c,
+	0x57, 0x4c, 0xa2, 0x71, 0xdb, 0x62, 0xd3, 0x8e, 0xcd, 0xac, 0x33, 0xca, 0x3b, 0xe1, 0xd7, 0x84,
+	0x4f, 0xcf, 0x5c, 0xd1, 0x21, 0x81, 0xdb, 0x09, 0x03, 0x6a, 0x85, 0xed, 0x80, 0x33, 0xc1, 0x10,
+	0x8a, 0x01, 0xed, 0x04, 0xd0, 0x9e, 0xfd, 0xa0, 0x71, 0x15, 0x5f, 0xcc, 0x03, 0xaa, 0xf9, 0x8d,
+	0x9b, 0x0e, 0x73, 0x98, 0x6a, 0x76, 0x64, 0x4b, 0x5b, 0xb7, 0x1d, 0xc6, 0x1c, 0x8f, 0x76, 0x54,
+	0x6f, 0x1c, 0x9d, 0x76, 0xec, 0x88, 0x13, 0xe1, 0x32, 0x5f, 0x8f, 0xdf, 0x7e, 0x7d, 0x9c, 0xf8,
+	0xf3, 0x78, 0xa8, 0xf5, 0xb2, 0x08, 0x95, 0x23, 0x66, 0xd3, 0xe3, 0x80, 0x5a, 0xe8, 0x00, 0x0c,
+	0xe2, 0xfb, 0x4c, 0x28, 0x6e, 0x68, 0x16, 0x9a, 0x85, 0x5d, 0x63, 0x6f, 0xa7, 0xfd, 0xe6, 0x9a,
+	0xdb, 0xdd, 0x25, 0xac, 0x57, 0x7c, 0x75, 0xbe, 0xb3, 0x86, 0xb3, 0x4c, 0xf4, 0x33, 0xa8, 0xd9,
+	0x34, 0x74, 0x39, 0xb5, 0x47, 0x9c, 0x79, 0xd4, 0x5c, 0x6f, 0x16, 0x76, 0xaf, 0xed, 0x7d, 0x37,
+	0xcf, 0x93, 0x9c, 0x1c, 0x33, 0x8f, 0x62, 0x43, 0x33, 0x64, 0x07, 0x1d, 0x00, 0x4c, 0xe9, 0x74,
+	0x4c, 0x79, 0x38, 0x71, 0x03, 0x73, 0x43, 0xd1, 0xbf, 0x77, 0x11, 0x5d, 0xae, 0xbd, 0xfd, 0x24,
+	0x85, 0xe3, 0x0c, 0x15, 0x3d, 0x81, 0x1a, 0x99, 0x11, 0xd7, 0x23, 0x63, 0xd7, 0x73, 0xc5, 0xdc,
+	0x2c, 0x2a, 0x57, 0x1f, 0x5f, 0xea, 0xaa, 0x9b, 0x21, 0xe0, 0x15, 0x7a, 0xcb, 0x06, 0x58, 0x4e,
+	0x84, 0xee, 0x43, 0x79, 0x38, 0x38, 0xea, 0x1f, 0x1e, 0x1d, 0xd4, 0xd7, 0x1a, 0xb7, 0x5f, 0xbc,
+	0x6c, 0xbe, 0x2f, 0x7d, 0x2c, 0x01, 0x43, 0xea, 0xdb, 0xae, 0xef, 0xa0, 0x5d, 0xa8, 0x74, 0xf7,
+	0xf7, 0x07, 0xc3, 0x93, 0x41, 0xbf, 0x5e, 0x68, 0x34, 0x5e, 0xbc, 0x6c, 0xde, 0x5a, 0x05, 0x76,
+	0x2d, 0x8b, 0x06, 0x82, 0xda, 0x8d, 0xe2, 0x37, 0x7f, 0xde, 0x5e, 0x6b, 0x7d, 0x53, 0x80, 0x5a,
+	0x76, 0x11, 0xe8, 0x3e, 0x94, 0xba, 0xfb, 0x27, 0x87, 0xcf, 0x06, 0xf5, 0xb5, 0x25, 0x3d, 0x8b,
+	0xe8, 0x5a, 0xc2, 0x9d, 0x51, 0x74, 0x0f, 0x36, 0x87, 0xdd, 0xaf, 0x8e, 0x07, 0xf5, 0xc2, 0x72,
+	0x39, 0x59, 0xd8, 0x90, 0x44, 0xa1, 0x42, 0xf5, 0x71, 0xf7, 0xf0, 0xa8, 0xbe, 0x9e, 0x8f, 0xea,
+	0x73, 0xe2, 0xfa, 0x7a, 0x29, 0x7f, 0x2a, 0x82, 0x71, 0x4c, 0xf9, 0xcc, 0xb5, 0xde, 0xb1, 0x44,
+	0x3e, 0x83, 0xa2, 0x20, 0xe1, 0x99, 0x92, 0x86, 0x91, 0x2f, 0x8d, 0x13, 0x12, 0x9e, 0xc9, 0x49,
+	0x35, 0x5d, 0xe1, 0xa5, 0x32, 0x38, 0x0d, 0x3c, 0xd7, 0x22, 0x82, 0xda, 0x4a, 0x19, 0xc6, 0xde,
+	0x47, 0x79, 0x6c, 0x9c, 0xa2, 0xf4, 0xfa, 0x1f, 0xad, 0xe1, 0x0c, 0x15, 0x3d, 0x84, 0x92, 0xe3,
+	0xb1, 0x31, 0xf1, 0x94, 0x26, 0x8c, 0xbd, 0xbb, 0x79, 0x4e, 0x0e, 0x14, 0x62, 0xe9, 0x40, 0x53,
+	0xd0, 0x03, 0x28, 0x45, 0x81, 0x4d, 0x04, 0x35, 0x4b, 0x8a, 0xdc, 0xcc, 0x23, 0x7f, 0xa5, 0x10,
+	0xfb, 0xcc, 0x3f, 0x75, 0x1d, 0xac, 0xf1, 0xe8, 0x31, 0x54, 0x7c, 0x2a, 0xbe, 0x66, 0xfc, 0x2c,
+	0x34, 0xcb, 0xcd, 0x8d, 0x5d, 0x63, 0xef, 0xd3, 0x5c, 0x31, 0xc6, 0x98, 0xae, 0x10, 0xc4, 0x9a,
+	0x4c, 0xa9, 0x2f, 0x62, 0x37, 0xbd, 0x75, 0xb3, 0x80, 0x53, 0x07, 0xe8, 0x27, 0x50, 0xa1, 0xbe,
+	0x1d, 0x30, 0xd7, 0x17, 0x66, 0xe5, 0xe2, 0x85, 0x0c, 0x34, 0x46, 0x06, 0x13, 0xa7, 0x0c, 0xc9,
+	0xe6, 0xcc, 0xf3, 0xc6, 0xc4, 0x3a, 0x33, 0xab, 0x6f, 0xb9, 0x8d, 0x94, 0xd1, 0x2b, 0x41, 0x71,
+	0xca, 0x6c, 0xda, 0xea, 0xc0, 0x8d, 0x37, 0x42, 0x8d, 0x1a, 0x50, 0xd1, 0xa1, 0x8e, 0x35, 0x52,
+	0xc4, 0x69, 0xbf, 0x75, 0x1d, 0xb6, 0x56, 0xc2, 0xda, 0xfa, 0xeb, 0x26, 0x54, 0x92, 0xb3, 0x46,
+	0x5d, 0xa8, 0x5a, 0xcc, 0x17, 0xc4, 0xf5, 0x29, 0xd7, 0xf2, 0xca, 0x3d, 0x99, 0xfd, 0x04, 0x24,
+	0x59, 0x8f, 0xd6, 0xf0, 0x92, 0x85, 0x7e, 0x01, 0x55, 0x4e, 0x43, 0x16, 0x71, 0x8b, 0x86, 0x5a,
+	0x5f, 0xbb, 0xf9, 0x0a, 0x89, 0x41, 0x98, 0xfe, 0x2e, 0x72, 0x39, 0x95, 0x51, 0x0e, 0xf1, 0x92,
+	0x8a, 0x1e, 0x42, 0x99, 0xd3, 0x50, 0x10, 0x2e, 0x2e, 0x93, 0x08, 0x8e, 0x21, 0x43, 0xe6, 0xb9,
+	0xd6, 0x1c, 0x27, 0x0c, 0xf4, 0x10, 0xaa, 0x81, 0x47, 0x2c, 0xe5, 0xd5, 0xdc, 0x54, 0xf4, 0x0f,
+	0xf2, 0xe8, 0xc3, 0x04, 0x84, 0x97, 0x78, 0xf4, 0x39, 0x80, 0xc7, 0x9c, 0x91, 0xcd, 0xdd, 0x19,
+	0xe5, 0x5a, 0x62, 0x8d, 0x3c, 0x76, 0x5f, 0x21, 0x70, 0xd5, 0x63, 0x4e, 0xdc, 0x44, 0x07, 0xff,
+	0x93, 0xbe, 0x32, 0xda, 0x7a, 0x0c, 0x40, 0xd2, 0x51, 0xad, 0xae, 0x8f, 0xdf, 0xca, 0x95, 0x3e,
+	0x91, 0x0c, 0x1d, 0xdd, 0x85, 0xda, 0x29, 0xe3, 0x16, 0x1d, 0xe9, 0xac, 0xa9, 0x2a, 0x4d, 0x18,
+	0xca, 0x16, 0xeb, 0x0b, 0xf5, 0xa0, 0xec, 0x50, 0x9f, 0x72, 0xd7, 0x32, 0x41, 0x4d, 0x76, 0x3f,
+	0x37, 0x21, 0x63, 0x08, 0x8e, 0x7c, 0xe1, 0x4e, 0xa9, 0x9e, 0x29, 0x21, 0xa2, 0xdf, 0xc2, 0x7b,
+	0xc9, 0xf1, 0x8d, 0x38, 0x3d, 0xa5, 0x9c, 0xfa, 0x52, 0x03, 0x86, 0x8a, 0xc3, 0x47, 0x97, 0x6b,
+	0x40, 0xa3, 0xf5, 0x65, 0x83, 0xf8, 0xeb, 0x03, 0x61, 0xaf, 0x0a, 0x65, 0x1e, 0xcf, 0xdb, 0xfa,
+	0x43, 0x41, 0xaa, 0xfe, 0x35, 0x04, 0xea, 0x80, 0x91, 0x4e, 0xef, 0xda, 0x4a, 0xbd, 0xd5, 0xde,
+	0xb5, 0xc5, 0xf9, 0x0e, 0x24, 0xd8, 0xc3, 0xbe, 0xbc, 0x83, 0x74, 0xdb, 0x46, 0x03, 0xd8, 0x4a,
+	0x09, 0xf2, 0x99, 0xd7, 0x0f, 0x65, 0xf3, 0xb2, 0x95, 0x9e, 0xcc, 0x03, 0x8a, 0x6b, 0x3c, 0xd3,
+	0x6b, 0xfd, 0x06, 0xd0, 0x9b, 0x71, 0x41, 0x08, 0x8a, 0x67, 0xae, 0xaf, 0x97, 0x81, 0x55, 0x1b,
+	0xb5, 0xa1, 0x1c, 0x90, 0xb9, 0xc7, 0x88, 0xad, 0x13, 0xe3, 0x66, 0x3b, 0xae, 0x0d, 0xda, 0x49,
+	0x6d, 0xd0, 0xee, 0xfa, 0x73, 0x9c, 0x80, 0x5a, 0x8f, 0xe1, 0xfd, 0xdc, 0xe3, 0x45, 0x7b, 0x50,
+	0x4b, 0x13, 0x6e, 0xb9, 0xd7, 0xeb, 0x8b, 0xf3, 0x1d, 0x23, 0xcd, 0xcc, 0xc3, 0x3e, 0x36, 0x52,
+	0xd0, 0xa1, 0xdd, 0xfa, 0x63, 0x15, 0xb6, 0x56, 0xd2, 0x16, 0xdd, 0x84, 0x4d, 0x77, 0x4a, 0x1c,
+	0xaa, 0xd7, 0x18, 0x77, 0xd0, 0x00, 0x4a, 0x1e, 0x19, 0x53, 0x4f, 0x26, 0xaf, 0x3c, 0xb8, 0xef,
+	0x5f, 0x99, 0xff, 0xed, 0x5f, 0x29, 0xfc, 0xc0, 0x17, 0x7c, 0x8e, 0x35, 0x19, 0x99, 0x50, 0xb6,
+	0xd8, 0x74, 0x4a, 0x7c, 0xf9, 0x4c, 0x6c, 0xec, 0x56, 0x71, 0xd2, 0x95, 0x91, 0x21, 0xdc, 0x09,
+	0xcd, 0xa2, 0x32, 0xab, 0x36, 0xaa, 0xc3, 0x06, 0xf5, 0x67, 0xe6, 0xa6, 0x32, 0xc9, 0xa6, 0xb4,
+	0xd8, 0x6e, 0x9c, 0x7d, 0x55, 0x2c, 0x9b, 0x92, 0x17, 0x85, 0x94, 0x9b, 0xe5, 0x38, 0xa2, 0xb2,
+	0x8d, 0x7e, 0x0c, 0xa5, 0x29, 0x8b, 0x7c, 0x11, 0x9a, 0x15, 0xb5, 0xd8, 0xdb, 0x79, 0x8b, 0x7d,
+	0x22, 0x11, 0x5a, 0x59, 0x1a, 0x8e, 0x06, 0x70, 0x23, 0x14, 0x2c, 0x18, 0x39, 0x9c, 0x58, 0x74,
+	0x14, 0x50, 0xee, 0x32, 0x5b, 0x5f, 0xc3, 0xb7, 0xdf, 0x38, 0x94, 0xbe, 0x2e, 0xe8, 0xf0, 0x75,
+	0xc9, 0x39, 0x90, 0x94, 0xa1, 0x62, 0xa0, 0x21, 0xd4, 0x82, 0xc8, 0xf3, 0x46, 0x2c, 0x88, 0x5f,
+	0xe4, 0x38, 0x77, 0xde, 0x22, 0x64, 0xc3, 0xc8, 0xf3, 0x9e, 0xc6, 0x24, 0x6c, 0x04, 0xcb, 0x0e,
+	0xba, 0x05, 0x25, 0x87, 0xb3, 0x28, 0x88, 0xf3, 0xa6, 0x8a, 0x75, 0x0f, 0x7d, 0x09, 0xe5, 0x90,
+	0x5a, 0x9c, 0x8a, 0xd0, 0xac, 0xa9, 0xad, 0x7e, 0x98, 0x37, 0xc9, 0xb1, 0x82, 0xa4, 0x39, 0x81,
+	0x13, 0x0e, 0xba, 0x0d, 0x1b, 0x42, 0xcc, 0xcd, 0xad, 0x66, 0x61, 0xb7, 0xd2, 0x2b, 0x2f, 0xce,
+	0x77, 0x36, 0x4e, 0x4e, 0x9e, 0x63, 0x69, 0x93, 0xaf, 0xc5, 0x84, 0x85, 0xc2, 0x27, 0x53, 0x6a,
+	0x5e, 0x53, 0xb1, 0x4d, 0xfb, 0xe8, 0x39, 0x80, 0xed, 0x87, 0x23, 0x4b, 0x5d, 0x4f, 0xe6, 0x75,
+	0xb5, 0xbb, 0x4f, 0xaf, 0xde, 0x5d, 0xff, 0xe8, 0x58, 0xbf, 0x98, 0x5b, 0x8b, 0xf3, 0x9d, 0x6a,
+	0xda, 0xc5, 0x55, 0xdb, 0x0f, 0xe3, 0x26, 0xea, 0x81, 0x31, 0xa1, 0xc4, 0x13, 0x13, 0x6b, 0x42,
+	0xad, 0x33, 0xb3, 0x7e, 0xf1, 0x13, 0xf8, 0x48, 0xc1, 0xb4, 0x87, 0x2c, 0x49, 0x2a, 0x58, 0x2e,
+	0x35, 0x34, 0x6f, 0xa8, 0x58, 0xc5, 0x1d, 0xf4, 0x01, 0x00, 0x0b, 0xa8, 0x3f, 0x0a, 0x85, 0xed,
+	0xfa, 0x26, 0x92, 0x5b, 0xc6, 0x55, 0x69, 0x39, 0x96, 0x06, 0x74, 0x47, 0x3e, 0x50, 0xc4, 0x1e,
+	0x31, 0xdf, 0x9b, 0x9b, 0xef, 0xa9, 0xd1, 0x8a, 0x34, 0x3c, 0xf5, 0xbd, 0x39, 0xda, 0x01, 0x43,
+	0xe9, 0x22, 0x74, 0x1d, 0x9f, 0x78, 0xe6, 0x4d, 0x15, 0x0f, 0x90, 0xa6, 0x63, 0x65, 0x91, 0xe7,
+	0x10, 0x47, 0x23, 0x34, 0xdf, 0xbf, 0xf8, 0x1c, 0xf4, 0x62, 0x97, 0xe7, 0xa0, 0x39, 0xe8, 0xa7,
+	0x00, 0x01, 0x77, 0x67, 0xae, 0x47, 0x1d, 0x1a, 0x9a, 0xb7, 0xd4, 0xa6, 0xb7, 0x73, 0x5f, 0xa6,
+	0x14, 0x85, 0x33, 0x8c, 0xc6, 0xe7, 0x60, 0x64, 0xb2, 0x4d, 0x66, 0xc9, 0x19, 0x9d, 0xeb, 0x04,
+	0x96, 0x4d, 0x19, 0x92, 0x19, 0xf1, 0xa2, 0xf8, 0x32, 0xab, 0xe2, 0xb8, 0xf3, 0xc5, 0xfa, 0x83,
+	0x42, 0x63, 0x0f, 0x8c, 0x8c, 0xea, 0xd0, 0x87, 0xf2, 0xf6, 0x73, 0xdc, 0x50, 0xf0, 0xf9, 0x88,
+	0x44, 0x62, 0x62, 0xfe, 0x5c, 0x11, 0x6a, 0x89, 0xb1, 0x1b, 0x89, 0x49, 0x63, 0x04, 0xcb, 0xc3,
+	0x43, 0x4d, 0x30, 0xa4, 0x28, 0x42, 0xca, 0x67, 0x94, 0xcb, 0xca, 0x42, 0xc6, 0x3c, 0x6b, 0x92,
+	0xe2, 0x0d, 0x29, 0xe1, 0xd6, 0x44, 0xdd, 0x1d, 0x55, 0xac, 0x7b, 0xf2, 0x32, 0x48, 0x32, 0x44,
+	0x5f, 0x06, 0xba, 0xdb, 0xfa, 0x57, 0x01, 0x6a, 0xd9, 0x02, 0x09, 0xed, 0xc7, 0x85, 0x8d, 0xda,
+	0xd2, 0xb5, 0xbd, 0xce, 0x55, 0x05, 0x95, 0xba, 0x98, 0xbd, 0x48, 0x3a, 0x7b, 0x22, 0xff, 0x32,
+	0x8a, 0x8c, 0x7e, 0x04, 0x9b, 0x01, 0xe3, 0x22, 0xb9, 0xc2, 0xf2, 0x03, 0xcc, 0x78, 0xf2, 0xec,
+	0xc6, 0xe0, 0xd6, 0x04, 0xae, 0xad, 0x7a, 0x43, 0xf7, 0x60, 0xe3, 0xd9, 0xe1, 0xb0, 0xbe, 0xd6,
+	0xb8, 0xf3, 0xe2, 0x65, 0xf3, 0x3b, 0xab, 0x83, 0xcf, 0x5c, 0x2e, 0x22, 0xe2, 0x1d, 0x0e, 0xd1,
+	0x27, 0xb0, 0xd9, 0x3f, 0x3a, 0xc6, 0xb8, 0x5e, 0x68, 0xec, 0xbc, 0x78, 0xd9, 0xbc, 0xb3, 0x8a,
+	0x93, 0x43, 0x2c, 0xf2, 0x6d, 0xcc, 0xc6, 0x69, 0x5d, 0xff, 0xef, 0x75, 0x30, 0xf4, 0xcd, 0xfe,
+	0xae, 0xbf, 0x7e, 0x5b, 0x71, 0xd9, 0x92, 0xa4, 0xec, 0xfa, 0x95, 0xd5, 0x4b, 0x2d, 0x26, 0xe8,
+	0x33, 0xbe, 0x0b, 0x35, 0x37, 0x98, 0x7d, 0x36, 0xa2, 0x3e, 0x19, 0x7b, 0xba, 0xc4, 0xaf, 0x60,
+	0x43, 0xda, 0x06, 0xb1, 0x49, 0xde, 0x17, 0xae, 0x2f, 0x28, 0xf7, 0x75, 0xf1, 0x5e, 0xc1, 0x69,
+	0x1f, 0x7d, 0x09, 0x45, 0x37, 0x20, 0x53, 0x5d, 0x72, 0xe5, 0xee, 0xe0, 0x70, 0xd8, 0x7d, 0xa2,
+	0x35, 0xd8, 0xab, 0x2c, 0xce, 0x77, 0x8a, 0xd2, 0x80, 0x15, 0x0d, 0x6d, 0x27, 0x55, 0x8f, 0x9c,
+	0x49, 0xdd, 0xfd, 0x15, 0x9c, 0xb1, 0x48, 0x1d, 0xb9, 0xbe, 0xc3, 0x69, 0x18, 0xaa, 0x57, 0xa0,
+	0x82, 0x93, 0x2e, 0x6a, 0x40, 0x59, 0xd7, 0x4e, 0xaa, 0x58, 0xaa, 0xca, 0xba, 0x44, 0x1b, 0x7a,
+	0x5b, 0x60, 0xc4, 0xd1, 0x18, 0x9d, 0x72, 0x36, 0x6d, 0xfd, 0xa7, 0x08, 0xc6, 0xbe, 0x17, 0x85,
+	0x42, 0x3f, 0x83, 0xef, 0x2c, 0xf8, 0xcf, 0xe1, 0x06, 0x51, 0x5f, 0x49, 0xe2, 0xcb, 0x37, 0x45,
+	0x95, 0xa4, 0xfa, 0x00, 0xee, 0xe5, 0xba, 0x4b, 0xc1, 0x71, 0xf9, 0xda, 0x2b, 0x49, 0x9f, 0x66,
+	0x01, 0xd7, 0xc9, 0x6b, 0x23, 0xe8, 0x18, 0xb6, 0x18, 0xb7, 0x26, 0x34, 0x14, 0xf1, 0x4b, 0xa4,
+	0xbf, 0x5e, 0xb9, 0x9f, 0xf2, 0xa7, 0x59, 0xa0, 0xbe, 0x86, 0xe3, 0xd5, 0xae, 0xfa, 0x40, 0x0f,
+	0xa0, 0xc8, 0xc9, 0x69, 0x52, 0x5e, 0xe7, 0x26, 0x09, 0x26, 0xa7, 0x62, 0xc5, 0x85, 0x62, 0xa0,
+	0x5f, 0x02, 0xd8, 0x6e, 0x18, 0x10, 0x61, 0x4d, 0x28, 0xd7, 0x87, 0x9d, 0xbb, 0xc5, 0x7e, 0x8a,
+	0x5a, 0xf1, 0x92, 0x61, 0xa3, 0xc7, 0x50, 0xb5, 0x48, 0x22, 0xd7, 0xd2, 0xc5, 0xff, 0xd1, 0xfd,
+	0xae, 0x76, 0x51, 0x97, 0x2e, 0x16, 0xe7, 0x3b, 0x95, 0xc4, 0x82, 0x2b, 0x16, 0xd1, 0xf2, 0x7d,
+	0x0c, 0x5b, 0xf2, 0x9f, 0x3a, 0xb2, 0xe9, 0x29, 0x89, 0x3c, 0x11, 0xcb, 0xe4, 0x82, 0x67, 0x45,
+	0x7e, 0x7a, 0xfa, 0x1a, 0xa7, 0xd7, 0x55, 0x13, 0x19, 0x1b, 0xfa, 0x35, 0xdc, 0xa0, 0xbe, 0xc5,
+	0xe7, 0x4a, 0xac, 0xc9, 0x0a, 0x2b, 0x17, 0x6f, 0x76, 0x90, 0x82, 0x57, 0x36, 0x5b, 0xa7, 0xaf,
+	0xd9, 0x5b, 0xff, 0x28, 0x00, 0xc4, 0x2f, 0xf5, 0xbb, 0x15, 0x20, 0x82, 0xa2, 0x4d, 0x04, 0x51,
+	0x9a, 0xab, 0x61, 0xd5, 0x46, 0x5f, 0x00, 0x08, 0x3a, 0x0d, 0x3c, 0x22, 0x5c, 0xdf, 0xd1, 0xb2,
+	0xb9, 0xec, 0x3a, 0xc8, 0xa0, 0xd1, 0x1e, 0x94, 0xf4, 0x27, 0xa8, 0x78, 0x25, 0x4f, 0x23, 0x5b,
+	0x7f, 0x29, 0x00, 0xc4, 0xdb, 0xfc, 0xbf, 0xde, 0x5b, 0xcf, 0x7c, 0xf5, 0xed, 0xf6, 0xda, 0xdf,
+	0xbf, 0xdd, 0x5e, 0xfb, 0xfd, 0x62, 0xbb, 0xf0, 0x6a, 0xb1, 0x5d, 0xf8, 0xdb, 0x62, 0xbb, 0xf0,
+	0xcf, 0xc5, 0x76, 0x61, 0x5c, 0x52, 0x75, 0xdf, 0x0f, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xae,
+	0x88, 0xf9, 0x3c, 0x5a, 0x14, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/specs.proto b/vendor/github.com/docker/swarmkit/api/specs.proto
index c14ebeb..8955027 100644
--- a/vendor/github.com/docker/swarmkit/api/specs.proto
+++ b/vendor/github.com/docker/swarmkit/api/specs.proto
@@ -2,7 +2,7 @@
 
 package docker.swarmkit.v1;
 
-import "types.proto";
+import "github.com/docker/swarmkit/api/types.proto";
 import "gogoproto/gogo.proto";
 import "google/protobuf/duration.proto";
 import "google/protobuf/any.proto";
@@ -128,6 +128,21 @@
 	// using the same reconciliation-based mechanism that performs rolling
 	// updates.
 	uint64 force_update = 9;
+
+	// ResourceReferences provides a generic way to specify resources that
+	// are used by this task, and should be sent down to agents along with
+	// the task. Inside the runtime field there may be more specific
+	// information about how to use the resource, but ResourceReferences
+	// establishes the relationship at the store level, and instructs the
+	// dispatcher to send the related objects.
+	//
+	// ResourceReferences is a list of ResourceReferences used by the task.
+	repeated ResourceReference resource_references = 11 [(gogoproto.nullable) = false];
+}
+
+message ResourceReference {
+	string resource_id = 1;
+	ResourceType resource_type = 2;
 }
 
 message GenericRuntimeSpec {
diff --git a/vendor/github.com/docker/swarmkit/api/types.pb.go b/vendor/github.com/docker/swarmkit/api/types.pb.go
index d41e761..9ce04eb 100644
--- a/vendor/github.com/docker/swarmkit/api/types.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/types.pb.go
@@ -1,222 +1,7 @@
 // Code generated by protoc-gen-gogo.
-// source: types.proto
+// source: github.com/docker/swarmkit/api/types.proto
 // DO NOT EDIT!
 
-/*
-	Package api is a generated protocol buffer package.
-
-	It is generated from these files:
-		types.proto
-		specs.proto
-		objects.proto
-		control.proto
-		dispatcher.proto
-		ca.proto
-		snapshot.proto
-		raft.proto
-		health.proto
-		resource.proto
-		logbroker.proto
-		watch.proto
-
-	It has these top-level messages:
-		Version
-		IndexEntry
-		Annotations
-		NamedGenericResource
-		DiscreteGenericResource
-		GenericResource
-		Resources
-		ResourceRequirements
-		Platform
-		PluginDescription
-		EngineDescription
-		NodeDescription
-		NodeTLSInfo
-		RaftMemberStatus
-		NodeStatus
-		Image
-		Mount
-		RestartPolicy
-		UpdateConfig
-		UpdateStatus
-		ContainerStatus
-		PortStatus
-		TaskStatus
-		NetworkAttachmentConfig
-		IPAMConfig
-		PortConfig
-		Driver
-		IPAMOptions
-		Peer
-		WeightedPeer
-		IssuanceStatus
-		AcceptancePolicy
-		ExternalCA
-		CAConfig
-		OrchestrationConfig
-		TaskDefaults
-		DispatcherConfig
-		RaftConfig
-		EncryptionConfig
-		SpreadOver
-		PlacementPreference
-		Placement
-		JoinTokens
-		RootCA
-		Certificate
-		EncryptionKey
-		ManagerStatus
-		FileTarget
-		SecretReference
-		ConfigReference
-		BlacklistedCertificate
-		HealthConfig
-		MaybeEncryptedRecord
-		RootRotation
-		Privileges
-		NodeSpec
-		ServiceSpec
-		ReplicatedService
-		GlobalService
-		TaskSpec
-		GenericRuntimeSpec
-		NetworkAttachmentSpec
-		ContainerSpec
-		EndpointSpec
-		NetworkSpec
-		ClusterSpec
-		SecretSpec
-		ConfigSpec
-		Meta
-		Node
-		Service
-		Endpoint
-		Task
-		NetworkAttachment
-		Network
-		Cluster
-		Secret
-		Config
-		Resource
-		Extension
-		GetNodeRequest
-		GetNodeResponse
-		ListNodesRequest
-		ListNodesResponse
-		UpdateNodeRequest
-		UpdateNodeResponse
-		RemoveNodeRequest
-		RemoveNodeResponse
-		GetTaskRequest
-		GetTaskResponse
-		RemoveTaskRequest
-		RemoveTaskResponse
-		ListTasksRequest
-		ListTasksResponse
-		CreateServiceRequest
-		CreateServiceResponse
-		GetServiceRequest
-		GetServiceResponse
-		UpdateServiceRequest
-		UpdateServiceResponse
-		RemoveServiceRequest
-		RemoveServiceResponse
-		ListServicesRequest
-		ListServicesResponse
-		CreateNetworkRequest
-		CreateNetworkResponse
-		GetNetworkRequest
-		GetNetworkResponse
-		RemoveNetworkRequest
-		RemoveNetworkResponse
-		ListNetworksRequest
-		ListNetworksResponse
-		GetClusterRequest
-		GetClusterResponse
-		ListClustersRequest
-		ListClustersResponse
-		KeyRotation
-		UpdateClusterRequest
-		UpdateClusterResponse
-		GetSecretRequest
-		GetSecretResponse
-		UpdateSecretRequest
-		UpdateSecretResponse
-		ListSecretsRequest
-		ListSecretsResponse
-		CreateSecretRequest
-		CreateSecretResponse
-		RemoveSecretRequest
-		RemoveSecretResponse
-		GetConfigRequest
-		GetConfigResponse
-		UpdateConfigRequest
-		UpdateConfigResponse
-		ListConfigsRequest
-		ListConfigsResponse
-		CreateConfigRequest
-		CreateConfigResponse
-		RemoveConfigRequest
-		RemoveConfigResponse
-		SessionRequest
-		SessionMessage
-		HeartbeatRequest
-		HeartbeatResponse
-		UpdateTaskStatusRequest
-		UpdateTaskStatusResponse
-		TasksRequest
-		TasksMessage
-		AssignmentsRequest
-		Assignment
-		AssignmentChange
-		AssignmentsMessage
-		NodeCertificateStatusRequest
-		NodeCertificateStatusResponse
-		IssueNodeCertificateRequest
-		IssueNodeCertificateResponse
-		GetRootCACertificateRequest
-		GetRootCACertificateResponse
-		GetUnlockKeyRequest
-		GetUnlockKeyResponse
-		StoreSnapshot
-		ClusterSnapshot
-		Snapshot
-		RaftMember
-		JoinRequest
-		JoinResponse
-		LeaveRequest
-		LeaveResponse
-		ProcessRaftMessageRequest
-		ProcessRaftMessageResponse
-		ResolveAddressRequest
-		ResolveAddressResponse
-		InternalRaftRequest
-		StoreAction
-		HealthCheckRequest
-		HealthCheckResponse
-		AttachNetworkRequest
-		AttachNetworkResponse
-		DetachNetworkRequest
-		DetachNetworkResponse
-		LogSubscriptionOptions
-		LogSelector
-		LogContext
-		LogAttr
-		LogMessage
-		SubscribeLogsRequest
-		SubscribeLogsMessage
-		ListenSubscriptionsRequest
-		SubscriptionMessage
-		PublishLogsMessage
-		PublishLogsResponse
-		Object
-		SelectBySlot
-		SelectByCustom
-		SelectBy
-		WatchRequest
-		WatchMessage
-*/
 package api
 
 import proto "github.com/gogo/protobuf/proto"
@@ -245,11 +30,29 @@
 var _ = math.Inf
 var _ = time.Kitchen
 
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+type ResourceType int32
+
+const (
+	ResourceType_TASK   ResourceType = 0
+	ResourceType_SECRET ResourceType = 1
+	ResourceType_CONFIG ResourceType = 2
+)
+
+var ResourceType_name = map[int32]string{
+	0: "TASK",
+	1: "SECRET",
+	2: "CONFIG",
+}
+var ResourceType_value = map[string]int32{
+	"TASK":   0,
+	"SECRET": 1,
+	"CONFIG": 2,
+}
+
+func (x ResourceType) String() string {
+	return proto.EnumName(ResourceType_name, int32(x))
+}
+func (ResourceType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{0} }
 
 // TaskState enumerates the states that a task progresses through within an
 // agent. States are designed to be monotonically increasing, such that if two
@@ -306,7 +109,7 @@
 func (x TaskState) String() string {
 	return proto.EnumName(TaskState_name, int32(x))
 }
-func (TaskState) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{0} }
+func (TaskState) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{1} }
 
 type NodeRole int32
 
@@ -327,7 +130,7 @@
 func (x NodeRole) String() string {
 	return proto.EnumName(NodeRole_name, int32(x))
 }
-func (NodeRole) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{1} }
+func (NodeRole) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{2} }
 
 type RaftMemberStatus_Reachability int32
 
@@ -416,6 +219,36 @@
 }
 func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 0} }
 
+// Consistency indicates the tolerable level of file system consistency
+type Mount_MountConsistency int32
+
+const (
+	MountConsistencyDefault   Mount_MountConsistency = 0
+	MountConsistencyFull      Mount_MountConsistency = 1
+	MountConsistencyCached    Mount_MountConsistency = 2
+	MountConsistencyDelegated Mount_MountConsistency = 3
+)
+
+var Mount_MountConsistency_name = map[int32]string{
+	0: "DEFAULT",
+	1: "CONSISTENT",
+	2: "CACHED",
+	3: "DELEGATED",
+}
+var Mount_MountConsistency_value = map[string]int32{
+	"DEFAULT":    0,
+	"CONSISTENT": 1,
+	"CACHED":     2,
+	"DELEGATED":  3,
+}
+
+func (x Mount_MountConsistency) String() string {
+	return proto.EnumName(Mount_MountConsistency_name, int32(x))
+}
+func (Mount_MountConsistency) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptorTypes, []int{16, 1}
+}
+
 type Mount_BindOptions_MountPropagation int32
 
 const (
@@ -1068,7 +901,8 @@
 	// Target path in container
 	Target string `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"`
 	// ReadOnly should be set to true if the mount should not be writable.
-	ReadOnly bool `protobuf:"varint,4,opt,name=readonly,proto3" json:"readonly,omitempty"`
+	ReadOnly    bool                   `protobuf:"varint,4,opt,name=readonly,proto3" json:"readonly,omitempty"`
+	Consistency Mount_MountConsistency `protobuf:"varint,8,opt,name=consistency,proto3,enum=docker.swarmkit.v1.Mount_MountConsistency" json:"consistency,omitempty"`
 	// BindOptions configures properties of a bind mount type.
 	//
 	// For mounts of type bind, the source must be an absolute host path.
@@ -1267,6 +1101,13 @@
 	// HostPorts provides a list of ports allocated at the host
 	// level.
 	PortStatus *PortStatus `protobuf:"bytes,6,opt,name=port_status,json=portStatus" json:"port_status,omitempty"`
+	// AppliedBy gives the node ID of the manager that applied this task
+	// status update to the Task object.
+	AppliedBy string `protobuf:"bytes,7,opt,name=applied_by,json=appliedBy,proto3" json:"applied_by,omitempty"`
+	// AppliedAt gives a timestamp of when this status update was applied to
+	// the Task object.
+	// Note: can't use stdtime because this field is nullable.
+	AppliedAt *google_protobuf.Timestamp `protobuf:"bytes,8,opt,name=applied_at,json=appliedAt" json:"applied_at,omitempty"`
 }
 
 func (m *TaskStatus) Reset()                    { *m = TaskStatus{} }
@@ -2311,11 +2152,13 @@
 	proto.RegisterType((*Privileges)(nil), "docker.swarmkit.v1.Privileges")
 	proto.RegisterType((*Privileges_CredentialSpec)(nil), "docker.swarmkit.v1.Privileges.CredentialSpec")
 	proto.RegisterType((*Privileges_SELinuxContext)(nil), "docker.swarmkit.v1.Privileges.SELinuxContext")
+	proto.RegisterEnum("docker.swarmkit.v1.ResourceType", ResourceType_name, ResourceType_value)
 	proto.RegisterEnum("docker.swarmkit.v1.TaskState", TaskState_name, TaskState_value)
 	proto.RegisterEnum("docker.swarmkit.v1.NodeRole", NodeRole_name, NodeRole_value)
 	proto.RegisterEnum("docker.swarmkit.v1.RaftMemberStatus_Reachability", RaftMemberStatus_Reachability_name, RaftMemberStatus_Reachability_value)
 	proto.RegisterEnum("docker.swarmkit.v1.NodeStatus_State", NodeStatus_State_name, NodeStatus_State_value)
 	proto.RegisterEnum("docker.swarmkit.v1.Mount_MountType", Mount_MountType_name, Mount_MountType_value)
+	proto.RegisterEnum("docker.swarmkit.v1.Mount_MountConsistency", Mount_MountConsistency_name, Mount_MountConsistency_value)
 	proto.RegisterEnum("docker.swarmkit.v1.Mount_BindOptions_MountPropagation", Mount_BindOptions_MountPropagation_name, Mount_BindOptions_MountPropagation_value)
 	proto.RegisterEnum("docker.swarmkit.v1.RestartPolicy_RestartCondition", RestartPolicy_RestartCondition_name, RestartPolicy_RestartCondition_value)
 	proto.RegisterEnum("docker.swarmkit.v1.UpdateConfig_FailureAction", UpdateConfig_FailureAction_name, UpdateConfig_FailureAction_value)
@@ -2867,6 +2710,10 @@
 		m.PortStatus = &PortStatus{}
 		github_com_docker_swarmkit_api_deepcopy.Copy(m.PortStatus, o.PortStatus)
 	}
+	if o.AppliedAt != nil {
+		m.AppliedAt = &google_protobuf.Timestamp{}
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.AppliedAt, o.AppliedAt)
+	}
 	if o.RuntimeStatus != nil {
 		switch o.RuntimeStatus.(type) {
 		case *TaskStatus_Container:
@@ -4345,6 +4192,11 @@
 		}
 		i += n12
 	}
+	if m.Consistency != 0 {
+		dAtA[i] = 0x40
+		i++
+		i = encodeVarintTypes(dAtA, i, uint64(m.Consistency))
+	}
 	return i, nil
 }
 
@@ -4730,6 +4582,22 @@
 		}
 		i += n22
 	}
+	if len(m.AppliedBy) > 0 {
+		dAtA[i] = 0x3a
+		i++
+		i = encodeVarintTypes(dAtA, i, uint64(len(m.AppliedBy)))
+		i += copy(dAtA[i:], m.AppliedBy)
+	}
+	if m.AppliedAt != nil {
+		dAtA[i] = 0x42
+		i++
+		i = encodeVarintTypes(dAtA, i, uint64(m.AppliedAt.Size()))
+		n23, err := m.AppliedAt.MarshalTo(dAtA[i:])
+		if err != nil {
+			return 0, err
+		}
+		i += n23
+	}
 	return i, nil
 }
 
@@ -4739,11 +4607,11 @@
 		dAtA[i] = 0x2a
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Container.Size()))
-		n23, err := m.Container.MarshalTo(dAtA[i:])
+		n24, err := m.Container.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n23
+		i += n24
 	}
 	return i, nil
 }
@@ -4980,11 +4848,11 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Driver.Size()))
-		n24, err := m.Driver.MarshalTo(dAtA[i:])
+		n25, err := m.Driver.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n24
+		i += n25
 	}
 	if len(m.Configs) > 0 {
 		for _, msg := range m.Configs {
@@ -5050,11 +4918,11 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Peer.Size()))
-		n25, err := m.Peer.MarshalTo(dAtA[i:])
+		n26, err := m.Peer.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n25
+		i += n26
 	}
 	if m.Weight != 0 {
 		dAtA[i] = 0x10
@@ -5157,11 +5025,11 @@
 		dAtA[i] = 0x1a
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Secret.Size()))
-		n26, err := m.Secret.MarshalTo(dAtA[i:])
+		n27, err := m.Secret.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n26
+		i += n27
 	}
 	return i, nil
 }
@@ -5267,11 +5135,11 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.NodeCertExpiry.Size()))
-		n27, err := m.NodeCertExpiry.MarshalTo(dAtA[i:])
+		n28, err := m.NodeCertExpiry.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n27
+		i += n28
 	}
 	if len(m.ExternalCAs) > 0 {
 		for _, msg := range m.ExternalCAs {
@@ -5347,11 +5215,11 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.LogDriver.Size()))
-		n28, err := m.LogDriver.MarshalTo(dAtA[i:])
+		n29, err := m.LogDriver.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n28
+		i += n29
 	}
 	return i, nil
 }
@@ -5375,11 +5243,11 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.HeartbeatPeriod.Size()))
-		n29, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:])
+		n30, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n29
+		i += n30
 	}
 	return i, nil
 }
@@ -5495,11 +5363,11 @@
 	var l int
 	_ = l
 	if m.Preference != nil {
-		nn30, err := m.Preference.MarshalTo(dAtA[i:])
+		nn31, err := m.Preference.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += nn30
+		i += nn31
 	}
 	return i, nil
 }
@@ -5510,11 +5378,11 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Spread.Size()))
-		n31, err := m.Spread.MarshalTo(dAtA[i:])
+		n32, err := m.Spread.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n31
+		i += n32
 	}
 	return i, nil
 }
@@ -5641,20 +5509,20 @@
 	dAtA[i] = 0x22
 	i++
 	i = encodeVarintTypes(dAtA, i, uint64(m.JoinTokens.Size()))
-	n32, err := m.JoinTokens.MarshalTo(dAtA[i:])
+	n33, err := m.JoinTokens.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n32
+	i += n33
 	if m.RootRotation != nil {
 		dAtA[i] = 0x2a
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.RootRotation.Size()))
-		n33, err := m.RootRotation.MarshalTo(dAtA[i:])
+		n34, err := m.RootRotation.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n33
+		i += n34
 	}
 	if m.LastForcedRotation != 0 {
 		dAtA[i] = 0x30
@@ -5693,11 +5561,11 @@
 	dAtA[i] = 0x1a
 	i++
 	i = encodeVarintTypes(dAtA, i, uint64(m.Status.Size()))
-	n34, err := m.Status.MarshalTo(dAtA[i:])
+	n35, err := m.Status.MarshalTo(dAtA[i:])
 	if err != nil {
 		return 0, err
 	}
-	i += n34
+	i += n35
 	if len(m.Certificate) > 0 {
 		dAtA[i] = 0x22
 		i++
@@ -5866,11 +5734,11 @@
 		i += copy(dAtA[i:], m.SecretName)
 	}
 	if m.Target != nil {
-		nn35, err := m.Target.MarshalTo(dAtA[i:])
+		nn36, err := m.Target.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += nn35
+		i += nn36
 	}
 	return i, nil
 }
@@ -5881,11 +5749,11 @@
 		dAtA[i] = 0x1a
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.File.Size()))
-		n36, err := m.File.MarshalTo(dAtA[i:])
+		n37, err := m.File.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n36
+		i += n37
 	}
 	return i, nil
 }
@@ -5917,11 +5785,11 @@
 		i += copy(dAtA[i:], m.ConfigName)
 	}
 	if m.Target != nil {
-		nn37, err := m.Target.MarshalTo(dAtA[i:])
+		nn38, err := m.Target.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += nn37
+		i += nn38
 	}
 	return i, nil
 }
@@ -5932,11 +5800,11 @@
 		dAtA[i] = 0x1a
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.File.Size()))
-		n38, err := m.File.MarshalTo(dAtA[i:])
+		n39, err := m.File.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n38
+		i += n39
 	}
 	return i, nil
 }
@@ -5959,11 +5827,11 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Expiry.Size()))
-		n39, err := m.Expiry.MarshalTo(dAtA[i:])
+		n40, err := m.Expiry.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n39
+		i += n40
 	}
 	return i, nil
 }
@@ -6002,21 +5870,21 @@
 		dAtA[i] = 0x12
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Interval.Size()))
-		n40, err := m.Interval.MarshalTo(dAtA[i:])
+		n41, err := m.Interval.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n40
+		i += n41
 	}
 	if m.Timeout != nil {
 		dAtA[i] = 0x1a
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.Timeout.Size()))
-		n41, err := m.Timeout.MarshalTo(dAtA[i:])
+		n42, err := m.Timeout.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n41
+		i += n42
 	}
 	if m.Retries != 0 {
 		dAtA[i] = 0x20
@@ -6027,11 +5895,11 @@
 		dAtA[i] = 0x2a
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.StartPeriod.Size()))
-		n42, err := m.StartPeriod.MarshalTo(dAtA[i:])
+		n43, err := m.StartPeriod.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n42
+		i += n43
 	}
 	return i, nil
 }
@@ -6126,21 +5994,21 @@
 		dAtA[i] = 0xa
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.CredentialSpec.Size()))
-		n43, err := m.CredentialSpec.MarshalTo(dAtA[i:])
+		n44, err := m.CredentialSpec.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n43
+		i += n44
 	}
 	if m.SELinuxContext != nil {
 		dAtA[i] = 0x12
 		i++
 		i = encodeVarintTypes(dAtA, i, uint64(m.SELinuxContext.Size()))
-		n44, err := m.SELinuxContext.MarshalTo(dAtA[i:])
+		n45, err := m.SELinuxContext.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += n44
+		i += n45
 	}
 	return i, nil
 }
@@ -6161,11 +6029,11 @@
 	var l int
 	_ = l
 	if m.Source != nil {
-		nn45, err := m.Source.MarshalTo(dAtA[i:])
+		nn46, err := m.Source.MarshalTo(dAtA[i:])
 		if err != nil {
 			return 0, err
 		}
-		i += nn45
+		i += nn46
 	}
 	return i, nil
 }
@@ -6567,6 +6435,9 @@
 		l = m.TmpfsOptions.Size()
 		n += 1 + l + sovTypes(uint64(l))
 	}
+	if m.Consistency != 0 {
+		n += 1 + sovTypes(uint64(m.Consistency))
+	}
 	return n
 }
 
@@ -6730,6 +6601,14 @@
 		l = m.PortStatus.Size()
 		n += 1 + l + sovTypes(uint64(l))
 	}
+	l = len(m.AppliedBy)
+	if l > 0 {
+		n += 1 + l + sovTypes(uint64(l))
+	}
+	if m.AppliedAt != nil {
+		l = m.AppliedAt.Size()
+		n += 1 + l + sovTypes(uint64(l))
+	}
 	return n
 }
 
@@ -7659,6 +7538,7 @@
 		`BindOptions:` + strings.Replace(fmt.Sprintf("%v", this.BindOptions), "Mount_BindOptions", "Mount_BindOptions", 1) + `,`,
 		`VolumeOptions:` + strings.Replace(fmt.Sprintf("%v", this.VolumeOptions), "Mount_VolumeOptions", "Mount_VolumeOptions", 1) + `,`,
 		`TmpfsOptions:` + strings.Replace(fmt.Sprintf("%v", this.TmpfsOptions), "Mount_TmpfsOptions", "Mount_TmpfsOptions", 1) + `,`,
+		`Consistency:` + fmt.Sprintf("%v", this.Consistency) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -7780,6 +7660,8 @@
 		`Err:` + fmt.Sprintf("%v", this.Err) + `,`,
 		`RuntimeStatus:` + fmt.Sprintf("%v", this.RuntimeStatus) + `,`,
 		`PortStatus:` + strings.Replace(fmt.Sprintf("%v", this.PortStatus), "PortStatus", "PortStatus", 1) + `,`,
+		`AppliedBy:` + fmt.Sprintf("%v", this.AppliedBy) + `,`,
+		`AppliedAt:` + strings.Replace(fmt.Sprintf("%v", this.AppliedAt), "Timestamp", "google_protobuf.Timestamp", 1) + `,`,
 		`}`,
 	}, "")
 	return s
@@ -10623,6 +10505,25 @@
 				return err
 			}
 			iNdEx = postIndex
+		case 8:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Consistency", wireType)
+			}
+			m.Consistency = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTypes
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.Consistency |= (Mount_MountConsistency(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
 			skippy, err := skipTypes(dAtA[iNdEx:])
@@ -11924,6 +11825,68 @@
 				return err
 			}
 			iNdEx = postIndex
+		case 7:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AppliedBy", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTypes
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthTypes
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.AppliedBy = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field AppliedAt", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowTypes
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthTypes
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if m.AppliedAt == nil {
+				m.AppliedAt = &google_protobuf.Timestamp{}
+			}
+			if err := m.AppliedAt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipTypes(dAtA[iNdEx:])
@@ -17058,310 +17021,322 @@
 	ErrIntOverflowTypes   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("types.proto", fileDescriptorTypes) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/types.proto", fileDescriptorTypes) }
 
 var fileDescriptorTypes = []byte{
-	// 4822 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0x49,
-	0x56, 0xbf, 0xeb, 0xd3, 0x55, 0xaf, 0xca, 0x76, 0x3a, 0xda, 0xdb, 0xe3, 0xae, 0xed, 0xb1, 0x6b,
-	0x72, 0xa6, 0x77, 0x66, 0x67, 0xe7, 0x5f, 0xd3, 0x1f, 0xbb, 0xab, 0x9e, 0x99, 0xff, 0x7c, 0xd4,
-	0x97, 0xdb, 0xb5, 0x6d, 0x57, 0x95, 0xa2, 0xca, 0xdd, 0x3b, 0x48, 0x90, 0x4a, 0x67, 0x86, 0xcb,
-	0x39, 0xce, 0xca, 0x28, 0x32, 0xb3, 0xec, 0x2e, 0x16, 0x44, 0x8b, 0x03, 0x20, 0x9f, 0xe0, 0xb6,
-	0x12, 0x32, 0x17, 0x38, 0x21, 0x24, 0x0e, 0x20, 0x21, 0xb8, 0x30, 0x48, 0x1c, 0xe6, 0xc6, 0x02,
-	0x12, 0x5a, 0x81, 0x64, 0x18, 0x1f, 0xb8, 0x21, 0xb8, 0xac, 0xb8, 0x80, 0x84, 0xe2, 0x23, 0xb3,
-	0xb2, 0xaa, 0xd3, 0x76, 0x0f, 0xb3, 0x17, 0x3b, 0xe3, 0xbd, 0xdf, 0x7b, 0xf1, 0xe2, 0x45, 0xc4,
-	0x8b, 0xf7, 0x22, 0x0a, 0x0a, 0xfe, 0x64, 0x44, 0xbc, 0xca, 0xc8, 0xa5, 0x3e, 0x45, 0xc8, 0xa4,
-	0xc6, 0x11, 0x71, 0x2b, 0xde, 0x89, 0xee, 0x0e, 0x8f, 0x2c, 0xbf, 0x72, 0x7c, 0xaf, 0xb4, 0x39,
-	0xa0, 0x74, 0x60, 0x93, 0x77, 0x39, 0x62, 0x7f, 0x7c, 0xf0, 0xae, 0x6f, 0x0d, 0x89, 0xe7, 0xeb,
-	0xc3, 0x91, 0x10, 0x2a, 0x6d, 0xcc, 0x03, 0xcc, 0xb1, 0xab, 0xfb, 0x16, 0x75, 0x24, 0x7f, 0x6d,
-	0x40, 0x07, 0x94, 0x7f, 0xbe, 0xcb, 0xbe, 0x04, 0x55, 0xdd, 0x84, 0xc5, 0x27, 0xc4, 0xf5, 0x2c,
-	0xea, 0xa0, 0x35, 0xc8, 0x58, 0x8e, 0x49, 0x9e, 0xad, 0x27, 0xca, 0x89, 0xb7, 0xd2, 0x58, 0x34,
-	0xd4, 0xbb, 0x00, 0x2d, 0xf6, 0xd1, 0x74, 0x7c, 0x77, 0x82, 0x14, 0x48, 0x1d, 0x91, 0x09, 0x47,
-	0xe4, 0x31, 0xfb, 0x64, 0x94, 0x63, 0xdd, 0x5e, 0x4f, 0x0a, 0xca, 0xb1, 0x6e, 0xab, 0x5f, 0x26,
-	0xa0, 0x50, 0x75, 0x1c, 0xea, 0xf3, 0xde, 0x3d, 0x84, 0x20, 0xed, 0xe8, 0x43, 0x22, 0x85, 0xf8,
-	0x37, 0xaa, 0x43, 0xd6, 0xd6, 0xf7, 0x89, 0xed, 0xad, 0x27, 0xcb, 0xa9, 0xb7, 0x0a, 0xf7, 0xbf,
-	0x53, 0x79, 0x71, 0xc8, 0x95, 0x88, 0x92, 0xca, 0x0e, 0x47, 0x73, 0x23, 0xb0, 0x14, 0x45, 0x1f,
-	0xc1, 0xa2, 0xe5, 0x98, 0x96, 0x41, 0xbc, 0xf5, 0x34, 0xd7, 0xb2, 0x11, 0xa7, 0x65, 0x6a, 0x7d,
-	0x2d, 0xfd, 0xc5, 0xf9, 0xe6, 0x02, 0x0e, 0x84, 0x4a, 0xef, 0x41, 0x21, 0xa2, 0x36, 0x66, 0x6c,
-	0x6b, 0x90, 0x39, 0xd6, 0xed, 0x31, 0x91, 0xa3, 0x13, 0x8d, 0xf7, 0x93, 0x0f, 0x13, 0xea, 0x27,
-	0xb0, 0xd6, 0xd6, 0x87, 0xc4, 0x7c, 0x44, 0x1c, 0xe2, 0x5a, 0x06, 0x26, 0x1e, 0x1d, 0xbb, 0x06,
-	0x61, 0x63, 0x3d, 0xb2, 0x1c, 0x33, 0x18, 0x2b, 0xfb, 0x8e, 0xd7, 0xa2, 0xd6, 0xe1, 0x95, 0x86,
-	0xe5, 0x19, 0x2e, 0xf1, 0xc9, 0x57, 0x56, 0x92, 0x0a, 0x94, 0x9c, 0x27, 0x60, 0x65, 0x5e, 0xfa,
-	0x17, 0xe0, 0x06, 0x73, 0xb1, 0xa9, 0xb9, 0x92, 0xa2, 0x79, 0x23, 0x62, 0x70, 0x65, 0x85, 0xfb,
-	0x6f, 0xc5, 0x79, 0x28, 0x6e, 0x24, 0xdb, 0x0b, 0x78, 0x95, 0xab, 0x09, 0x08, 0xbd, 0x11, 0x31,
-	0x90, 0x01, 0x37, 0x4d, 0x69, 0xf4, 0x9c, 0xfa, 0x24, 0x57, 0x1f, 0x3b, 0x8d, 0x97, 0x0c, 0x73,
-	0x7b, 0x01, 0xaf, 0x05, 0xca, 0xa2, 0x9d, 0xd4, 0x00, 0x72, 0x81, 0x6e, 0xf5, 0xc7, 0x09, 0xc8,
-	0x07, 0x4c, 0x0f, 0x7d, 0x1b, 0xf2, 0x8e, 0xee, 0x50, 0xcd, 0x18, 0x8d, 0x3d, 0x3e, 0xa0, 0x54,
-	0xad, 0x78, 0x71, 0xbe, 0x99, 0x6b, 0xeb, 0x0e, 0xad, 0x77, 0xf7, 0x3c, 0x9c, 0x63, 0xec, 0xfa,
-	0x68, 0xec, 0xa1, 0xd7, 0xa0, 0x38, 0x24, 0x43, 0xea, 0x4e, 0xb4, 0xfd, 0x89, 0x4f, 0x3c, 0xe9,
-	0xb6, 0x82, 0xa0, 0xd5, 0x18, 0x09, 0x7d, 0x08, 0x8b, 0x03, 0x61, 0xd2, 0x7a, 0x8a, 0x2f, 0x9f,
-	0xd7, 0xe3, 0xac, 0x9f, 0xb3, 0x1a, 0x07, 0x32, 0xea, 0xef, 0x24, 0x60, 0x2d, 0xa4, 0x92, 0x5f,
-	0x1e, 0x5b, 0x2e, 0x19, 0x12, 0xc7, 0xf7, 0xd0, 0xf7, 0x20, 0x6b, 0x5b, 0x43, 0xcb, 0xf7, 0xa4,
-	0xcf, 0x5f, 0x8d, 0x53, 0x1b, 0x0e, 0x0a, 0x4b, 0x30, 0xaa, 0x42, 0xd1, 0x25, 0x1e, 0x71, 0x8f,
-	0xc5, 0x8a, 0x97, 0x1e, 0xbd, 0x46, 0x78, 0x46, 0x44, 0xdd, 0x82, 0x5c, 0xd7, 0xd6, 0xfd, 0x03,
-	0xea, 0x0e, 0x91, 0x0a, 0x45, 0xdd, 0x35, 0x0e, 0x2d, 0x9f, 0x18, 0xfe, 0xd8, 0x0d, 0x76, 0xdf,
-	0x0c, 0x0d, 0xdd, 0x84, 0x24, 0x15, 0x1d, 0xe5, 0x6b, 0xd9, 0x8b, 0xf3, 0xcd, 0x64, 0xa7, 0x87,
-	0x93, 0xd4, 0x53, 0x3f, 0x80, 0xd5, 0xae, 0x3d, 0x1e, 0x58, 0x4e, 0x83, 0x78, 0x86, 0x6b, 0x8d,
-	0x98, 0x76, 0xb6, 0x2a, 0x59, 0x8c, 0x0a, 0x56, 0x25, 0xfb, 0x0e, 0xb7, 0x76, 0x72, 0xba, 0xb5,
-	0xd5, 0xdf, 0x4a, 0xc2, 0x6a, 0xd3, 0x19, 0x58, 0x0e, 0x89, 0x4a, 0xdf, 0x81, 0x65, 0xc2, 0x89,
-	0xda, 0xb1, 0x08, 0x37, 0x52, 0xcf, 0x92, 0xa0, 0x06, 0x31, 0xa8, 0x35, 0x17, 0x17, 0xee, 0xc5,
-	0x0d, 0xff, 0x05, 0xed, 0xb1, 0xd1, 0xa1, 0x09, 0x8b, 0x23, 0x3e, 0x08, 0x4f, 0x4e, 0xef, 0x9d,
-	0x38, 0x5d, 0x2f, 0x8c, 0x33, 0x08, 0x12, 0x52, 0xf6, 0xeb, 0x04, 0x89, 0x3f, 0x4e, 0xc2, 0x4a,
-	0x9b, 0x9a, 0x33, 0x7e, 0x28, 0x41, 0xee, 0x90, 0x7a, 0x7e, 0x24, 0x20, 0x86, 0x6d, 0xf4, 0x10,
-	0x72, 0x23, 0x39, 0x7d, 0x72, 0xf6, 0x6f, 0xc7, 0x9b, 0x2c, 0x30, 0x38, 0x44, 0xa3, 0x0f, 0x20,
-	0x1f, 0x6c, 0x19, 0x36, 0xda, 0x97, 0x58, 0x38, 0x53, 0x3c, 0xfa, 0x10, 0xb2, 0x62, 0x12, 0xd6,
-	0xd3, 0x5c, 0xf2, 0xce, 0x4b, 0xf9, 0x1c, 0x4b, 0x21, 0xf4, 0x08, 0x72, 0xbe, 0xed, 0x69, 0x96,
-	0x73, 0x40, 0xd7, 0x33, 0x5c, 0xc1, 0x66, 0x6c, 0x90, 0xa1, 0x26, 0xe9, 0xef, 0xf4, 0x5a, 0xce,
-	0x01, 0xad, 0x15, 0x2e, 0xce, 0x37, 0x17, 0x65, 0x03, 0x2f, 0xfa, 0xb6, 0xc7, 0x3e, 0xd4, 0xdf,
-	0x4d, 0x40, 0x21, 0x82, 0x42, 0xaf, 0x02, 0xf8, 0xee, 0xd8, 0xf3, 0x35, 0x97, 0x52, 0x9f, 0x3b,
-	0xab, 0x88, 0xf3, 0x9c, 0x82, 0x29, 0xf5, 0x51, 0x05, 0x6e, 0x18, 0xc4, 0xf5, 0x35, 0xcb, 0xf3,
-	0xc6, 0xc4, 0xd5, 0xbc, 0xf1, 0xfe, 0x67, 0xc4, 0xf0, 0xb9, 0xe3, 0x8a, 0x78, 0x95, 0xb1, 0x5a,
-	0x9c, 0xd3, 0x13, 0x0c, 0xf4, 0x00, 0x6e, 0x46, 0xf1, 0xa3, 0xf1, 0xbe, 0x6d, 0x19, 0x1a, 0x9b,
-	0xcc, 0x14, 0x17, 0xb9, 0x31, 0x15, 0xe9, 0x72, 0xde, 0x63, 0x32, 0x51, 0x7f, 0x9a, 0x00, 0x05,
-	0xeb, 0x07, 0xfe, 0x2e, 0x19, 0xee, 0x13, 0xb7, 0xe7, 0xeb, 0xfe, 0xd8, 0x43, 0x37, 0x21, 0x6b,
-	0x13, 0xdd, 0x24, 0x2e, 0x37, 0x2a, 0x87, 0x65, 0x0b, 0xed, 0xb1, 0x1d, 0xac, 0x1b, 0x87, 0xfa,
-	0xbe, 0x65, 0x5b, 0xfe, 0x84, 0x9b, 0xb2, 0x1c, 0xbf, 0x84, 0xe7, 0x75, 0x56, 0x70, 0x44, 0x10,
-	0xcf, 0xa8, 0x41, 0xeb, 0xb0, 0x38, 0x24, 0x9e, 0xa7, 0x0f, 0x08, 0xb7, 0x34, 0x8f, 0x83, 0xa6,
-	0xfa, 0x01, 0x14, 0xa3, 0x72, 0xa8, 0x00, 0x8b, 0x7b, 0xed, 0xc7, 0xed, 0xce, 0xd3, 0xb6, 0xb2,
-	0x80, 0x56, 0xa0, 0xb0, 0xd7, 0xc6, 0xcd, 0x6a, 0x7d, 0xbb, 0x5a, 0xdb, 0x69, 0x2a, 0x09, 0xb4,
-	0x04, 0xf9, 0x69, 0x33, 0xa9, 0xfe, 0x69, 0x02, 0x80, 0xb9, 0x5b, 0x0e, 0xea, 0x7d, 0xc8, 0x78,
-	0xbe, 0xee, 0x8b, 0x55, 0xb9, 0x7c, 0xff, 0x8d, 0xcb, 0xe6, 0x50, 0xda, 0xcb, 0xfe, 0x11, 0x2c,
-	0x44, 0xa2, 0x16, 0x26, 0x67, 0x2c, 0x64, 0x01, 0x42, 0x37, 0x4d, 0x57, 0x1a, 0xce, 0xbf, 0xd5,
-	0x0f, 0x20, 0xc3, 0xa5, 0x67, 0xcd, 0xcd, 0x41, 0xba, 0xc1, 0xbe, 0x12, 0x28, 0x0f, 0x19, 0xdc,
-	0xac, 0x36, 0x3e, 0x55, 0x92, 0x48, 0x81, 0x62, 0xa3, 0xd5, 0xab, 0x77, 0xda, 0xed, 0x66, 0xbd,
-	0xdf, 0x6c, 0x28, 0x29, 0xf5, 0x0e, 0x64, 0x5a, 0x43, 0xa6, 0xf9, 0x36, 0x5b, 0xf2, 0x07, 0xc4,
-	0x25, 0x8e, 0x11, 0xec, 0xa4, 0x29, 0x41, 0xfd, 0x49, 0x1e, 0x32, 0xbb, 0x74, 0xec, 0xf8, 0xe8,
-	0x7e, 0x24, 0x6c, 0x2d, 0xc7, 0x67, 0x08, 0x1c, 0x58, 0xe9, 0x4f, 0x46, 0x44, 0x86, 0xb5, 0x9b,
-	0x90, 0x15, 0x9b, 0x43, 0x0e, 0x47, 0xb6, 0x18, 0xdd, 0xd7, 0xdd, 0x01, 0xf1, 0xe5, 0x78, 0x64,
-	0x0b, 0xbd, 0xc5, 0x4e, 0x2c, 0xdd, 0xa4, 0x8e, 0x3d, 0xe1, 0x7b, 0x28, 0x27, 0x8e, 0x25, 0x4c,
-	0x74, 0xb3, 0xe3, 0xd8, 0x13, 0x1c, 0x72, 0xd1, 0x36, 0x14, 0xf7, 0x2d, 0xc7, 0xd4, 0xe8, 0x48,
-	0x04, 0xf9, 0xcc, 0xe5, 0x3b, 0x4e, 0x58, 0x55, 0xb3, 0x1c, 0xb3, 0x23, 0xc0, 0xb8, 0xb0, 0x3f,
-	0x6d, 0xa0, 0x36, 0x2c, 0x1f, 0x53, 0x7b, 0x3c, 0x24, 0xa1, 0xae, 0x2c, 0xd7, 0xf5, 0xe6, 0xe5,
-	0xba, 0x9e, 0x70, 0x7c, 0xa0, 0x6d, 0xe9, 0x38, 0xda, 0x44, 0x8f, 0x61, 0xc9, 0x1f, 0x8e, 0x0e,
-	0xbc, 0x50, 0xdd, 0x22, 0x57, 0xf7, 0xad, 0x2b, 0x1c, 0xc6, 0xe0, 0x81, 0xb6, 0xa2, 0x1f, 0x69,
-	0x95, 0x7e, 0x23, 0x05, 0x85, 0x88, 0xe5, 0xa8, 0x07, 0x85, 0x91, 0x4b, 0x47, 0xfa, 0x80, 0x1f,
-	0x54, 0x72, 0x2e, 0xee, 0xbd, 0xd4, 0xa8, 0x2b, 0xdd, 0xa9, 0x20, 0x8e, 0x6a, 0x51, 0xcf, 0x92,
-	0x50, 0x88, 0x30, 0xd1, 0xdb, 0x90, 0xc3, 0x5d, 0xdc, 0x7a, 0x52, 0xed, 0x37, 0x95, 0x85, 0xd2,
-	0xed, 0xd3, 0xb3, 0xf2, 0x3a, 0xd7, 0x16, 0x55, 0xd0, 0x75, 0xad, 0x63, 0xb6, 0xf4, 0xde, 0x82,
-	0xc5, 0x00, 0x9a, 0x28, 0x7d, 0xf3, 0xf4, 0xac, 0xfc, 0xca, 0x3c, 0x34, 0x82, 0xc4, 0xbd, 0xed,
-	0x2a, 0x6e, 0x36, 0x94, 0x64, 0x3c, 0x12, 0xf7, 0x0e, 0x75, 0x97, 0x98, 0xe8, 0x5b, 0x90, 0x95,
-	0xc0, 0x54, 0xa9, 0x74, 0x7a, 0x56, 0xbe, 0x39, 0x0f, 0x9c, 0xe2, 0x70, 0x6f, 0xa7, 0xfa, 0xa4,
-	0xa9, 0xa4, 0xe3, 0x71, 0xb8, 0x67, 0xeb, 0xc7, 0x04, 0xbd, 0x01, 0x19, 0x01, 0xcb, 0x94, 0x6e,
-	0x9d, 0x9e, 0x95, 0xbf, 0xf1, 0x82, 0x3a, 0x86, 0x2a, 0xad, 0xff, 0xf6, 0x1f, 0x6c, 0x2c, 0xfc,
-	0xe5, 0x1f, 0x6e, 0x28, 0xf3, 0xec, 0xd2, 0x7f, 0x27, 0x60, 0x69, 0x66, 0xca, 0x91, 0x0a, 0x59,
-	0x87, 0x1a, 0x74, 0x24, 0xce, 0xaf, 0x5c, 0x0d, 0x2e, 0xce, 0x37, 0xb3, 0x6d, 0x5a, 0xa7, 0xa3,
-	0x09, 0x96, 0x1c, 0xf4, 0x78, 0xee, 0x04, 0x7e, 0xf0, 0x92, 0xeb, 0x29, 0xf6, 0x0c, 0xfe, 0x18,
-	0x96, 0x4c, 0xd7, 0x3a, 0x26, 0xae, 0x66, 0x50, 0xe7, 0xc0, 0x1a, 0xc8, 0xb3, 0xa9, 0x14, 0x9b,
-	0x26, 0x72, 0x20, 0x2e, 0x0a, 0x81, 0x3a, 0xc7, 0x7f, 0x8d, 0xd3, 0xb7, 0xf4, 0x04, 0x8a, 0xd1,
-	0x15, 0xca, 0x8e, 0x13, 0xcf, 0xfa, 0x15, 0x22, 0xf3, 0x41, 0x9e, 0x3d, 0xe2, 0x3c, 0xa3, 0x88,
-	0x6c, 0xf0, 0x4d, 0x48, 0x0f, 0xa9, 0x29, 0xf4, 0x2c, 0xd5, 0x6e, 0xb0, 0x24, 0xe0, 0x9f, 0xce,
-	0x37, 0x0b, 0xd4, 0xab, 0x6c, 0x59, 0x36, 0xd9, 0xa5, 0x26, 0xc1, 0x1c, 0xa0, 0x1e, 0x43, 0x9a,
-	0x85, 0x0a, 0xf4, 0x4d, 0x48, 0xd7, 0x5a, 0xed, 0x86, 0xb2, 0x50, 0x5a, 0x3d, 0x3d, 0x2b, 0x2f,
-	0x71, 0x97, 0x30, 0x06, 0x5b, 0xbb, 0x68, 0x13, 0xb2, 0x4f, 0x3a, 0x3b, 0x7b, 0xbb, 0x6c, 0x79,
-	0xdd, 0x38, 0x3d, 0x2b, 0xaf, 0x84, 0x6c, 0xe1, 0x34, 0xf4, 0x2a, 0x64, 0xfa, 0xbb, 0xdd, 0xad,
-	0x9e, 0x92, 0x2c, 0xa1, 0xd3, 0xb3, 0xf2, 0x72, 0xc8, 0xe7, 0x36, 0x97, 0x56, 0xe5, 0xac, 0xe6,
-	0x43, 0xba, 0xfa, 0xb3, 0x24, 0x2c, 0x61, 0x56, 0xf1, 0xb9, 0x7e, 0x97, 0xda, 0x96, 0x31, 0x41,
-	0x5d, 0xc8, 0x1b, 0xd4, 0x31, 0xad, 0xc8, 0x9e, 0xba, 0x7f, 0xc9, 0xa9, 0x3f, 0x95, 0x0a, 0x5a,
-	0xf5, 0x40, 0x12, 0x4f, 0x95, 0xa0, 0x77, 0x21, 0x63, 0x12, 0x5b, 0x9f, 0xc8, 0xf4, 0xe3, 0x56,
-	0x45, 0xd4, 0x94, 0x95, 0xa0, 0xa6, 0xac, 0x34, 0x64, 0x4d, 0x89, 0x05, 0x8e, 0xa7, 0xd9, 0xfa,
-	0x33, 0x4d, 0xf7, 0x7d, 0x32, 0x1c, 0xf9, 0x22, 0xf7, 0x48, 0xe3, 0xc2, 0x50, 0x7f, 0x56, 0x95,
-	0x24, 0x74, 0x0f, 0xb2, 0x27, 0x96, 0x63, 0xd2, 0x13, 0x99, 0x5e, 0x5c, 0xa1, 0x54, 0x02, 0xd5,
-	0x53, 0x76, 0xea, 0xce, 0x99, 0xc9, 0xfc, 0xdd, 0xee, 0xb4, 0x9b, 0x81, 0xbf, 0x25, 0xbf, 0xe3,
-	0xb4, 0xa9, 0xc3, 0xf6, 0x0a, 0x74, 0xda, 0xda, 0x56, 0xb5, 0xb5, 0xb3, 0x87, 0x99, 0xcf, 0xd7,
-	0x4e, 0xcf, 0xca, 0x4a, 0x08, 0xd9, 0xd2, 0x2d, 0x9b, 0xe5, 0xbb, 0xb7, 0x20, 0x55, 0x6d, 0x7f,
-	0xaa, 0x24, 0x4b, 0xca, 0xe9, 0x59, 0xb9, 0x18, 0xb2, 0xab, 0xce, 0x64, 0xba, 0x8d, 0xe6, 0xfb,
-	0x55, 0xff, 0x36, 0x05, 0xc5, 0xbd, 0x91, 0xa9, 0xfb, 0x44, 0xac, 0x49, 0x54, 0x86, 0xc2, 0x48,
-	0x77, 0x75, 0xdb, 0x26, 0xb6, 0xe5, 0x0d, 0x65, 0xb5, 0x1c, 0x25, 0xa1, 0xf7, 0x5e, 0xd6, 0x8d,
-	0xb5, 0x1c, 0x5b, 0x67, 0x3f, 0xfe, 0x97, 0xcd, 0x44, 0xe0, 0xd0, 0x3d, 0x58, 0x3e, 0x10, 0xd6,
-	0x6a, 0xba, 0xc1, 0x27, 0x36, 0xc5, 0x27, 0xb6, 0x12, 0x37, 0xb1, 0x51, 0xb3, 0x2a, 0x72, 0x90,
-	0x55, 0x2e, 0x85, 0x97, 0x0e, 0xa2, 0x4d, 0xf4, 0x00, 0x16, 0x87, 0xd4, 0xb1, 0x7c, 0xea, 0x5e,
-	0x3f, 0x0b, 0x01, 0x12, 0xbd, 0x0d, 0xab, 0x6c, 0x72, 0x03, 0x7b, 0x38, 0x9b, 0x9f, 0x58, 0x49,
-	0xbc, 0x32, 0xd4, 0x9f, 0xc9, 0x0e, 0x31, 0x23, 0xa3, 0x1a, 0x64, 0xa8, 0xcb, 0x52, 0xa2, 0x2c,
-	0x37, 0xf7, 0x9d, 0x6b, 0xcd, 0x15, 0x8d, 0x0e, 0x93, 0xc1, 0x42, 0x54, 0xfd, 0x3e, 0x2c, 0xcd,
-	0x0c, 0x82, 0x65, 0x02, 0xdd, 0xea, 0x5e, 0xaf, 0xa9, 0x2c, 0xa0, 0x22, 0xe4, 0xea, 0x9d, 0x76,
-	0xbf, 0xd5, 0xde, 0x63, 0xa9, 0x4c, 0x11, 0x72, 0xb8, 0xb3, 0xb3, 0x53, 0xab, 0xd6, 0x1f, 0x2b,
-	0x49, 0xb5, 0x02, 0x85, 0x88, 0x36, 0xb4, 0x0c, 0xd0, 0xeb, 0x77, 0xba, 0xda, 0x56, 0x0b, 0xf7,
-	0xfa, 0x22, 0x11, 0xea, 0xf5, 0xab, 0xb8, 0x2f, 0x09, 0x09, 0xf5, 0x3f, 0x92, 0xc1, 0x8c, 0xca,
-	0xdc, 0xa7, 0x36, 0x9b, 0xfb, 0x5c, 0x61, 0xbc, 0xcc, 0x7e, 0xa6, 0x8d, 0x30, 0x07, 0x7a, 0x0f,
-	0x80, 0x2f, 0x1c, 0x62, 0x6a, 0xba, 0x2f, 0x27, 0xbe, 0xf4, 0x82, 0x93, 0xfb, 0xc1, 0xa5, 0x0d,
-	0xce, 0x4b, 0x74, 0xd5, 0x47, 0x1f, 0x42, 0xd1, 0xa0, 0xc3, 0x91, 0x4d, 0xa4, 0x70, 0xea, 0x5a,
-	0xe1, 0x42, 0x88, 0xaf, 0xfa, 0xd1, 0xec, 0x2b, 0x3d, 0x9b, 0x1f, 0xfe, 0x66, 0x22, 0xf0, 0x4c,
-	0x4c, 0xc2, 0x55, 0x84, 0xdc, 0x5e, 0xb7, 0x51, 0xed, 0xb7, 0xda, 0x8f, 0x94, 0x04, 0x02, 0xc8,
-	0x72, 0x57, 0x37, 0x94, 0x24, 0x4b, 0x14, 0xeb, 0x9d, 0xdd, 0xee, 0x4e, 0x93, 0xa7, 0x5c, 0x68,
-	0x0d, 0x94, 0xc0, 0xd9, 0x1a, 0x77, 0x64, 0xb3, 0xa1, 0xa4, 0xd1, 0x0d, 0x58, 0x09, 0xa9, 0x52,
-	0x32, 0x83, 0x6e, 0x02, 0x0a, 0x89, 0x53, 0x15, 0x59, 0xf5, 0xd7, 0x60, 0xa5, 0x4e, 0x1d, 0x5f,
-	0xb7, 0x9c, 0x30, 0x89, 0xbe, 0xcf, 0x06, 0x2d, 0x49, 0x9a, 0x25, 0x2f, 0x3b, 0x6a, 0x2b, 0x17,
-	0xe7, 0x9b, 0x85, 0x10, 0xda, 0x6a, 0xb0, 0x91, 0x06, 0x0d, 0x93, 0xed, 0xdf, 0x91, 0x65, 0x72,
-	0xe7, 0x66, 0x6a, 0x8b, 0x17, 0xe7, 0x9b, 0xa9, 0x6e, 0xab, 0x81, 0x19, 0x0d, 0x7d, 0x13, 0xf2,
-	0xe4, 0x99, 0xe5, 0x6b, 0x06, 0x8b, 0xe1, 0xcc, 0x81, 0x19, 0x9c, 0x63, 0x84, 0x3a, 0x0b, 0xd9,
-	0x35, 0x80, 0x2e, 0x75, 0x7d, 0xd9, 0xf3, 0x77, 0x21, 0x33, 0xa2, 0x2e, 0x2f, 0xcf, 0x2f, 0xbd,
-	0x34, 0x62, 0x70, 0xb1, 0x50, 0xb1, 0x00, 0xab, 0x7f, 0x95, 0x04, 0xe8, 0xeb, 0xde, 0x91, 0x54,
-	0xf2, 0x10, 0xf2, 0xe1, 0x05, 0x9c, 0xac, 0xf3, 0xaf, 0x9c, 0xed, 0x10, 0x8c, 0x1e, 0x04, 0x8b,
-	0x4d, 0x94, 0x07, 0xb1, 0x75, 0x5a, 0xd0, 0x51, 0x5c, 0x86, 0x3d, 0x5b, 0x03, 0xb0, 0x23, 0x91,
-	0xb8, 0xae, 0x9c, 0x79, 0xf6, 0x89, 0xea, 0xfc, 0x58, 0x10, 0x4e, 0x93, 0x09, 0x66, 0xec, 0xcd,
-	0xc6, 0xdc, 0x8c, 0x6c, 0x2f, 0xe0, 0xa9, 0x1c, 0xfa, 0x18, 0x0a, 0x6c, 0xdc, 0x9a, 0xc7, 0x79,
-	0x32, 0xb7, 0xbc, 0xd4, 0x55, 0x42, 0x03, 0x86, 0x51, 0xf8, 0x5d, 0x53, 0x60, 0xd9, 0x1d, 0x3b,
-	0x6c, 0xd8, 0x52, 0x87, 0xfa, 0x27, 0x49, 0x78, 0xa5, 0x4d, 0xfc, 0x13, 0xea, 0x1e, 0x55, 0x7d,
-	0x5f, 0x37, 0x0e, 0x87, 0xc4, 0x91, 0x4e, 0x8e, 0x64, 0xd6, 0x89, 0x99, 0xcc, 0x7a, 0x1d, 0x16,
-	0x75, 0xdb, 0xd2, 0x3d, 0x22, 0xd2, 0x91, 0x3c, 0x0e, 0x9a, 0x2c, 0xff, 0x67, 0xd5, 0x04, 0xf1,
-	0x3c, 0x22, 0x0a, 0xfc, 0x3c, 0x9e, 0x12, 0xd0, 0x8f, 0xe0, 0xa6, 0x4c, 0x3c, 0xf4, 0xb0, 0x2b,
-	0x96, 0xd9, 0x06, 0x37, 0x85, 0xcd, 0xd8, 0xf2, 0x26, 0xde, 0x38, 0x99, 0x99, 0x4c, 0xc9, 0x9d,
-	0x91, 0x2f, 0xf3, 0x9c, 0x35, 0x33, 0x86, 0x55, 0x7a, 0x04, 0xb7, 0x2e, 0x15, 0xf9, 0x4a, 0x17,
-	0x08, 0xff, 0x90, 0x04, 0x68, 0x75, 0xab, 0xbb, 0xd2, 0x49, 0x0d, 0xc8, 0x1e, 0xe8, 0x43, 0xcb,
-	0x9e, 0x5c, 0x15, 0xa7, 0xa6, 0xf8, 0x4a, 0x55, 0xb8, 0x63, 0x8b, 0xcb, 0x60, 0x29, 0xcb, 0x8b,
-	0x9b, 0xf1, 0xbe, 0x43, 0xfc, 0xb0, 0xb8, 0xe1, 0x2d, 0x66, 0x86, 0xab, 0x3b, 0xe1, 0x02, 0x13,
-	0x0d, 0x36, 0x01, 0x03, 0xdd, 0x27, 0x27, 0xfa, 0x24, 0x08, 0x2e, 0xb2, 0x89, 0xb6, 0xf9, 0x35,
-	0x1d, 0x71, 0x8f, 0x89, 0xb9, 0x9e, 0xe1, 0x4e, 0xbd, 0xce, 0x1e, 0x2c, 0xe1, 0xc2, 0x77, 0xa1,
-	0x74, 0xe9, 0x03, 0x9e, 0xd8, 0x4c, 0x59, 0x5f, 0xc9, 0x47, 0x77, 0x61, 0x69, 0x66, 0x9c, 0x2f,
-	0x54, 0x95, 0xad, 0xee, 0x93, 0xef, 0x2a, 0x69, 0xf9, 0xf5, 0x7d, 0x25, 0xab, 0xfe, 0x51, 0x4a,
-	0x84, 0x03, 0xe9, 0xd5, 0xf8, 0xeb, 0xe9, 0x1c, 0xdf, 0xc4, 0x06, 0xb5, 0xe5, 0x36, 0x7d, 0xf3,
-	0xea, 0x28, 0xc1, 0xaa, 0x14, 0x0e, 0xc7, 0xa1, 0x20, 0xda, 0x84, 0x82, 0x58, 0xc5, 0x1a, 0xdb,
-	0x16, 0xdc, 0xad, 0x4b, 0x18, 0x04, 0x89, 0x49, 0xa2, 0x3b, 0xb0, 0xcc, 0x6f, 0x21, 0xbc, 0x43,
-	0x62, 0x0a, 0x4c, 0x9a, 0x63, 0x96, 0x42, 0x2a, 0x87, 0xed, 0x42, 0x51, 0x12, 0x34, 0x9e, 0xa1,
-	0x66, 0xb8, 0x41, 0x6f, 0x5f, 0x67, 0x90, 0x10, 0xe1, 0x89, 0x6b, 0x61, 0x34, 0x6d, 0xa8, 0x0d,
-	0xc8, 0x05, 0xc6, 0xa2, 0x75, 0x48, 0xf5, 0xeb, 0x5d, 0x65, 0xa1, 0xb4, 0x72, 0x7a, 0x56, 0x2e,
-	0x04, 0xe4, 0x7e, 0xbd, 0xcb, 0x38, 0x7b, 0x8d, 0xae, 0x92, 0x98, 0xe5, 0xec, 0x35, 0xba, 0xa5,
-	0x34, 0xcb, 0x94, 0xd4, 0x03, 0x28, 0x44, 0x7a, 0x40, 0xaf, 0xc3, 0x62, 0xab, 0xfd, 0x08, 0x37,
-	0x7b, 0x3d, 0x65, 0xa1, 0x74, 0xf3, 0xf4, 0xac, 0x8c, 0x22, 0xdc, 0x96, 0x33, 0x60, 0xf3, 0x83,
-	0x5e, 0x85, 0xf4, 0x76, 0x87, 0x9d, 0xc0, 0x22, 0x25, 0x8e, 0x20, 0xb6, 0xa9, 0xe7, 0x97, 0x6e,
-	0xc8, 0x14, 0x2c, 0xaa, 0x58, 0xfd, 0xbd, 0x04, 0x64, 0xc5, 0x66, 0x8a, 0x9d, 0xa8, 0x2a, 0x2c,
-	0x06, 0xf5, 0xaa, 0x28, 0x57, 0xde, 0xbc, 0xbc, 0xb4, 0xa8, 0xc8, 0x4a, 0x40, 0x2c, 0xbf, 0x40,
-	0xae, 0xf4, 0x3e, 0x14, 0xa3, 0x8c, 0xaf, 0xb4, 0xf8, 0x7e, 0x04, 0x05, 0xb6, 0xbe, 0x83, 0x12,
-	0xe3, 0x3e, 0x64, 0x45, 0x40, 0x08, 0x4f, 0x84, 0xcb, 0xeb, 0x1c, 0x89, 0x44, 0x0f, 0x61, 0x51,
-	0xd4, 0x46, 0xc1, 0x35, 0xe5, 0xc6, 0xd5, 0xbb, 0x08, 0x07, 0x70, 0xf5, 0x63, 0x48, 0x77, 0x09,
-	0x71, 0x99, 0xef, 0x1d, 0x6a, 0x92, 0xe9, 0x21, 0x2a, 0xcb, 0x3a, 0x93, 0xb4, 0x1a, 0xac, 0xac,
-	0x33, 0x49, 0xcb, 0x0c, 0x2f, 0x62, 0x92, 0x91, 0x8b, 0x98, 0x3e, 0x14, 0x9f, 0x12, 0x6b, 0x70,
-	0xe8, 0x13, 0x93, 0x2b, 0x7a, 0x07, 0xd2, 0x23, 0x12, 0x1a, 0xbf, 0x1e, 0xbb, 0xc0, 0x08, 0x71,
-	0x31, 0x47, 0xb1, 0x38, 0x72, 0xc2, 0xa5, 0xe5, 0xdd, 0xba, 0x6c, 0xa9, 0x7f, 0x9f, 0x84, 0xe5,
-	0x96, 0xe7, 0x8d, 0x75, 0xc7, 0x08, 0xf2, 0xab, 0x8f, 0x66, 0xf3, 0xab, 0xd8, 0x47, 0x88, 0x59,
-	0x91, 0xd9, 0xfb, 0x25, 0x79, 0xc6, 0x25, 0xc3, 0x33, 0x4e, 0xfd, 0xf7, 0x44, 0x70, 0x89, 0x74,
-	0x27, 0xb2, 0xdd, 0x4b, 0xeb, 0xa7, 0x67, 0xe5, 0xb5, 0xa8, 0x26, 0xb2, 0xe7, 0x1c, 0x39, 0xf4,
-	0xc4, 0x41, 0xaf, 0x41, 0x06, 0x37, 0xdb, 0xcd, 0xa7, 0x4a, 0x42, 0x2c, 0xcf, 0x19, 0x10, 0x26,
-	0x0e, 0x39, 0x61, 0x9a, 0xba, 0xcd, 0x76, 0x83, 0xe5, 0x43, 0xc9, 0x18, 0x4d, 0x5d, 0xe2, 0x98,
-	0x96, 0x33, 0x40, 0xaf, 0x43, 0xb6, 0xd5, 0xeb, 0xed, 0xf1, 0x32, 0xff, 0x95, 0xd3, 0xb3, 0xf2,
-	0x8d, 0x19, 0x14, 0xbf, 0x40, 0x34, 0x19, 0x88, 0x15, 0x23, 0x2c, 0x53, 0x8a, 0x01, 0xb1, 0x2c,
-	0x57, 0x80, 0x70, 0xa7, 0x5f, 0xed, 0xb3, 0x0a, 0xff, 0x45, 0x10, 0xa6, 0xec, 0xaf, 0xdc, 0x6e,
-	0xff, 0x9c, 0x04, 0xa5, 0x6a, 0x18, 0x64, 0xe4, 0x33, 0xbe, 0xac, 0xff, 0xfa, 0x90, 0x1b, 0xb1,
-	0x2f, 0x8b, 0x04, 0xb9, 0xcc, 0xc3, 0xd8, 0x67, 0xb4, 0x39, 0xb9, 0x0a, 0xa6, 0x36, 0xa9, 0x9a,
-	0x43, 0xcb, 0xf3, 0x2c, 0xea, 0x08, 0x1a, 0x0e, 0x35, 0x95, 0xfe, 0x33, 0x01, 0x37, 0x62, 0x10,
-	0xe8, 0x2e, 0xa4, 0x5d, 0x6a, 0x07, 0x73, 0x78, 0xfb, 0xb2, 0xfb, 0x41, 0x26, 0x8a, 0x39, 0x12,
-	0x6d, 0x00, 0xe8, 0x63, 0x9f, 0xea, 0xbc, 0x7f, 0x3e, 0x7b, 0x39, 0x1c, 0xa1, 0xa0, 0xa7, 0x90,
-	0xf5, 0x88, 0xe1, 0x92, 0x20, 0xe3, 0xfd, 0xf8, 0xff, 0x6a, 0x7d, 0xa5, 0xc7, 0xd5, 0x60, 0xa9,
-	0xae, 0x54, 0x81, 0xac, 0xa0, 0xb0, 0x65, 0x6f, 0xea, 0xbe, 0x2e, 0x6f, 0x8f, 0xf9, 0x37, 0x5b,
-	0x4d, 0xba, 0x3d, 0x08, 0x56, 0x93, 0x6e, 0x0f, 0xd4, 0xbf, 0x49, 0x02, 0x34, 0x9f, 0xf9, 0xc4,
-	0x75, 0x74, 0xbb, 0x5e, 0x45, 0xcd, 0x48, 0xf4, 0x17, 0xa3, 0xfd, 0x76, 0xec, 0x95, 0x78, 0x28,
-	0x51, 0xa9, 0x57, 0x63, 0xe2, 0xff, 0x2d, 0x48, 0x8d, 0x5d, 0xf9, 0x32, 0x2a, 0xb2, 0xd5, 0x3d,
-	0xbc, 0x83, 0x19, 0x0d, 0x35, 0xa7, 0x61, 0x2b, 0x75, 0xf9, 0xfb, 0x67, 0xa4, 0x83, 0xd8, 0xd0,
-	0xc5, 0x76, 0xbe, 0xa1, 0x6b, 0x06, 0x91, 0x27, 0x47, 0x51, 0xec, 0xfc, 0x7a, 0xb5, 0x4e, 0x5c,
-	0x1f, 0x67, 0x0d, 0x9d, 0xfd, 0xff, 0x5a, 0xf1, 0xed, 0x1d, 0x80, 0xe9, 0xd0, 0xd0, 0x06, 0x64,
-	0xea, 0x5b, 0xbd, 0xde, 0x8e, 0xb2, 0x20, 0x02, 0xf8, 0x94, 0xc5, 0xc9, 0xea, 0x5f, 0x24, 0x21,
-	0x57, 0xaf, 0xca, 0x63, 0xb5, 0x0e, 0x0a, 0x8f, 0x4a, 0xfc, 0xce, 0x9d, 0x3c, 0x1b, 0x59, 0xee,
-	0x44, 0x06, 0x96, 0x2b, 0x4a, 0xcf, 0x65, 0x26, 0xc2, 0xac, 0x6e, 0x72, 0x01, 0x84, 0xa1, 0x48,
-	0xa4, 0x13, 0x34, 0x43, 0x0f, 0x62, 0xfc, 0xc6, 0xd5, 0xce, 0x12, 0x45, 0xc4, 0xb4, 0xed, 0xe1,
-	0x42, 0xa0, 0xa4, 0xae, 0x7b, 0xe8, 0x3d, 0x58, 0xf1, 0xac, 0x81, 0x63, 0x39, 0x03, 0x2d, 0x70,
-	0x1e, 0x7f, 0x00, 0xa8, 0xad, 0x5e, 0x9c, 0x6f, 0x2e, 0xf5, 0x04, 0x4b, 0xfa, 0x70, 0x49, 0x22,
-	0xeb, 0xdc, 0x95, 0xe8, 0xfb, 0xb0, 0x1c, 0x11, 0x65, 0x5e, 0x14, 0x6e, 0x57, 0x2e, 0xce, 0x37,
-	0x8b, 0xa1, 0xe4, 0x63, 0x32, 0xc1, 0xc5, 0x50, 0xf0, 0x31, 0xe1, 0xb7, 0x24, 0x07, 0xd4, 0x35,
-	0x88, 0xe6, 0xf2, 0x3d, 0xcd, 0x4f, 0xf0, 0x34, 0x2e, 0x70, 0x9a, 0xd8, 0xe6, 0xea, 0x13, 0xb8,
-	0xd1, 0x71, 0x8d, 0x43, 0xe2, 0xf9, 0xc2, 0x15, 0xd2, 0x8b, 0x1f, 0xc3, 0x6d, 0x5f, 0xf7, 0x8e,
-	0xb4, 0x43, 0xcb, 0xf3, 0xa9, 0x3b, 0xd1, 0x5c, 0xe2, 0x13, 0x87, 0xf1, 0x35, 0xfe, 0x6a, 0x28,
-	0xaf, 0xb1, 0x6e, 0x31, 0xcc, 0xb6, 0x80, 0xe0, 0x00, 0xb1, 0xc3, 0x00, 0x6a, 0x0b, 0x8a, 0xac,
-	0x98, 0x68, 0x90, 0x03, 0x7d, 0x6c, 0xfb, 0x6c, 0xf4, 0x60, 0xd3, 0x81, 0xf6, 0xd2, 0xc7, 0x54,
-	0xde, 0xa6, 0x03, 0xf1, 0xa9, 0xfe, 0x10, 0x94, 0x86, 0xe5, 0x8d, 0x74, 0xdf, 0x38, 0x0c, 0xee,
-	0xe7, 0x50, 0x03, 0x94, 0x43, 0xa2, 0xbb, 0xfe, 0x3e, 0xd1, 0x7d, 0x6d, 0x44, 0x5c, 0x8b, 0x9a,
-	0xd7, 0xcf, 0xf2, 0x4a, 0x28, 0xd2, 0xe5, 0x12, 0xea, 0x7f, 0x25, 0x00, 0xb0, 0x7e, 0x10, 0x64,
-	0x64, 0xdf, 0x81, 0x55, 0xcf, 0xd1, 0x47, 0xde, 0x21, 0xf5, 0x35, 0xcb, 0xf1, 0x89, 0x7b, 0xac,
-	0xdb, 0xf2, 0x9a, 0x45, 0x09, 0x18, 0x2d, 0x49, 0x47, 0xef, 0x00, 0x3a, 0x22, 0x64, 0xa4, 0x51,
-	0xdb, 0xd4, 0x02, 0xa6, 0x78, 0xd3, 0x4c, 0x63, 0x85, 0x71, 0x3a, 0xb6, 0xd9, 0x0b, 0xe8, 0xa8,
-	0x06, 0x1b, 0x6c, 0xf8, 0xc4, 0xf1, 0x5d, 0x8b, 0x78, 0xda, 0x01, 0x75, 0x35, 0xcf, 0xa6, 0x27,
-	0xda, 0x01, 0xb5, 0x6d, 0x7a, 0x42, 0xdc, 0xe0, 0x06, 0xab, 0x64, 0xd3, 0x41, 0x53, 0x80, 0xb6,
-	0xa8, 0xdb, 0xb3, 0xe9, 0xc9, 0x56, 0x80, 0x60, 0x69, 0xdb, 0x74, 0xcc, 0xbe, 0x65, 0x1c, 0x05,
-	0x69, 0x5b, 0x48, 0xed, 0x5b, 0xc6, 0x11, 0x7a, 0x1d, 0x96, 0x88, 0x4d, 0xf8, 0x45, 0x86, 0x40,
-	0x65, 0x38, 0xaa, 0x18, 0x10, 0x19, 0x48, 0xfd, 0x04, 0x94, 0xa6, 0x63, 0xb8, 0x93, 0x51, 0x64,
-	0xce, 0xdf, 0x01, 0xc4, 0x82, 0xa4, 0x66, 0x53, 0xe3, 0x48, 0x1b, 0xea, 0x8e, 0x3e, 0x60, 0x76,
-	0x89, 0xa7, 0x26, 0x85, 0x71, 0x76, 0xa8, 0x71, 0xb4, 0x2b, 0xe9, 0xea, 0x7b, 0x00, 0xbd, 0x91,
-	0x4b, 0x74, 0xb3, 0xc3, 0xb2, 0x09, 0xe6, 0x3a, 0xde, 0xd2, 0x4c, 0xf9, 0x54, 0x47, 0x5d, 0xb9,
-	0xd5, 0x15, 0xc1, 0x68, 0x84, 0x74, 0xf5, 0x17, 0xe1, 0x46, 0xd7, 0xd6, 0x0d, 0xfe, 0x6c, 0xdd,
-	0x0d, 0xdf, 0x4e, 0xd0, 0x43, 0xc8, 0x0a, 0xa8, 0x9c, 0xc9, 0xd8, 0xed, 0x36, 0xed, 0x73, 0x7b,
-	0x01, 0x4b, 0x7c, 0xad, 0x08, 0x30, 0xd5, 0xa3, 0xfe, 0x59, 0x02, 0xf2, 0xa1, 0x7e, 0x54, 0x06,
-	0x56, 0xca, 0xb3, 0xe5, 0x6d, 0x39, 0xb2, 0xf6, 0xce, 0xe3, 0x28, 0x09, 0xb5, 0xa0, 0x30, 0x0a,
-	0xa5, 0xaf, 0xcc, 0xe7, 0x62, 0xac, 0xc6, 0x51, 0x59, 0xf4, 0x3e, 0xe4, 0x83, 0xb7, 0xd1, 0x20,
-	0xc2, 0x5e, 0xfd, 0x94, 0x3a, 0x85, 0xab, 0x1f, 0x01, 0xfc, 0x80, 0x5a, 0x4e, 0x9f, 0x1e, 0x11,
-	0x87, 0xbf, 0xf5, 0xb1, 0x9a, 0x90, 0x04, 0x5e, 0x94, 0x2d, 0x5e, 0x90, 0x8b, 0x29, 0x08, 0x9f,
-	0xbc, 0x44, 0x53, 0xfd, 0xeb, 0x24, 0x64, 0x31, 0xa5, 0x7e, 0xbd, 0x8a, 0xca, 0x90, 0x95, 0x71,
-	0x82, 0x9f, 0x3f, 0xb5, 0xfc, 0xc5, 0xf9, 0x66, 0x46, 0x04, 0x88, 0x8c, 0xc1, 0x23, 0x43, 0x24,
-	0x82, 0x27, 0x2f, 0x8b, 0xe0, 0xe8, 0x2e, 0x14, 0x25, 0x48, 0x3b, 0xd4, 0xbd, 0x43, 0x51, 0xa0,
-	0xd5, 0x96, 0x2f, 0xce, 0x37, 0x41, 0x20, 0xb7, 0x75, 0xef, 0x10, 0x83, 0x40, 0xb3, 0x6f, 0xd4,
-	0x84, 0xc2, 0x67, 0xd4, 0x72, 0x34, 0x9f, 0x0f, 0x42, 0x5e, 0xf9, 0xc5, 0xce, 0xe3, 0x74, 0xa8,
-	0xf2, 0xe1, 0x1b, 0x3e, 0x9b, 0x0e, 0xbe, 0x09, 0x4b, 0x2e, 0xa5, 0xbe, 0x08, 0x5b, 0x16, 0x75,
-	0xe4, 0x6d, 0x42, 0x39, 0xf6, 0x92, 0x99, 0x52, 0x1f, 0x4b, 0x1c, 0x2e, 0xba, 0x91, 0x16, 0xba,
-	0x0b, 0x6b, 0xb6, 0xee, 0xf9, 0x1a, 0x8f, 0x77, 0xe6, 0x54, 0x5b, 0x96, 0x6f, 0x35, 0xc4, 0x78,
-	0x5b, 0x9c, 0x15, 0x48, 0xa8, 0xff, 0x98, 0x80, 0x02, 0x1b, 0x8c, 0x75, 0x60, 0x19, 0x2c, 0xc9,
-	0xfb, 0xea, 0xb9, 0xc7, 0x2d, 0x48, 0x19, 0x9e, 0x2b, 0x9d, 0xca, 0x0f, 0xdf, 0x7a, 0x0f, 0x63,
-	0x46, 0x43, 0x9f, 0x40, 0x56, 0xde, 0x6a, 0x88, 0xb4, 0x43, 0xbd, 0x3e, 0x1d, 0x95, 0xbe, 0x91,
-	0x72, 0x7c, 0x2d, 0x4f, 0xad, 0x13, 0x87, 0x00, 0x8e, 0x92, 0xd0, 0x4d, 0x48, 0x1a, 0xc2, 0x5d,
-	0xf2, 0x97, 0x15, 0xf5, 0x36, 0x4e, 0x1a, 0x8e, 0xfa, 0x77, 0x09, 0x58, 0x9a, 0x6e, 0x78, 0xb6,
-	0x02, 0x6e, 0x43, 0xde, 0x1b, 0xef, 0x7b, 0x13, 0xcf, 0x27, 0xc3, 0xe0, 0x1d, 0x33, 0x24, 0xa0,
-	0x16, 0xe4, 0x75, 0x7b, 0x40, 0x5d, 0xcb, 0x3f, 0x1c, 0xca, 0x4a, 0x34, 0x3e, 0x55, 0x88, 0xea,
-	0xac, 0x54, 0x03, 0x11, 0x3c, 0x95, 0x0e, 0xce, 0x7d, 0xf1, 0xd8, 0xcd, 0xcf, 0xfd, 0xd7, 0xa0,
-	0x68, 0xeb, 0x43, 0x7e, 0xcd, 0xe3, 0x5b, 0x43, 0x31, 0x8e, 0x34, 0x2e, 0x48, 0x5a, 0xdf, 0x1a,
-	0x12, 0x55, 0x85, 0x7c, 0xa8, 0x0c, 0xad, 0x40, 0xa1, 0xda, 0xec, 0x69, 0xf7, 0xee, 0x3f, 0xd4,
-	0x1e, 0xd5, 0x77, 0x95, 0x05, 0x99, 0x9b, 0xfe, 0x79, 0x02, 0x96, 0x64, 0x38, 0x92, 0xf9, 0xfe,
-	0xeb, 0xb0, 0xe8, 0xea, 0x07, 0x7e, 0x50, 0x91, 0xa4, 0xc5, 0xaa, 0x66, 0x11, 0x9e, 0x55, 0x24,
-	0x8c, 0x15, 0x5f, 0x91, 0x44, 0x5e, 0xd6, 0x53, 0x57, 0xbe, 0xac, 0xa7, 0x7f, 0x2e, 0x2f, 0xeb,
-	0xea, 0xaf, 0x03, 0x6c, 0x59, 0x36, 0xe9, 0x8b, 0xbb, 0xa6, 0xb8, 0xfa, 0x92, 0xe5, 0x70, 0xf2,
-	0xc6, 0x31, 0xc8, 0xe1, 0x5a, 0x0d, 0xcc, 0x68, 0x8c, 0x35, 0xb0, 0x4c, 0xb9, 0x19, 0x39, 0xeb,
-	0x11, 0x63, 0x0d, 0x2c, 0x33, 0x7c, 0x4b, 0x4a, 0x5f, 0xf7, 0x96, 0x74, 0x96, 0x80, 0x15, 0x99,
-	0xbb, 0x86, 0xe1, 0xf7, 0xdb, 0x90, 0x17, 0x69, 0xec, 0xb4, 0xa0, 0xe3, 0xaf, 0xc9, 0x02, 0xd7,
-	0x6a, 0xe0, 0x9c, 0x60, 0xb7, 0x4c, 0xb4, 0x09, 0x05, 0x09, 0x8d, 0xfc, 0x0a, 0x07, 0x04, 0xa9,
-	0xcd, 0xcc, 0xff, 0x2e, 0xa4, 0x0f, 0x2c, 0x9b, 0xc8, 0x85, 0x1e, 0x1b, 0x00, 0xa6, 0x0e, 0xd8,
-	0x5e, 0xc0, 0x1c, 0x5d, 0xcb, 0x05, 0x97, 0x71, 0xdc, 0x3e, 0x59, 0x76, 0x46, 0xed, 0x13, 0x15,
-	0xe8, 0x9c, 0x7d, 0x02, 0xc7, 0xec, 0x13, 0x6c, 0x61, 0x9f, 0x84, 0x46, 0xed, 0x13, 0xa4, 0x9f,
-	0x8b, 0x7d, 0x3b, 0x70, 0xb3, 0x66, 0xeb, 0xc6, 0x91, 0x6d, 0x79, 0x3e, 0x31, 0xa3, 0x11, 0xe3,
-	0x3e, 0x64, 0x67, 0x92, 0xce, 0xab, 0x2e, 0x67, 0x25, 0x52, 0xfd, 0xb7, 0x04, 0x14, 0xb7, 0x89,
-	0x6e, 0xfb, 0x87, 0xd3, 0xab, 0x21, 0x9f, 0x78, 0xbe, 0x3c, 0xac, 0xf8, 0x37, 0xfa, 0x1e, 0xe4,
-	0xc2, 0x9c, 0xe4, 0xda, 0x57, 0xb2, 0x10, 0x8a, 0x1e, 0xc0, 0x22, 0xdb, 0x63, 0x74, 0x1c, 0x14,
-	0x3b, 0x57, 0x3d, 0xc0, 0x48, 0x24, 0x3b, 0x64, 0x5c, 0xc2, 0x93, 0x10, 0xbe, 0x94, 0x32, 0x38,
-	0x68, 0xa2, 0xff, 0x0f, 0x45, 0xfe, 0x7e, 0x10, 0xe4, 0x5c, 0x99, 0xeb, 0x74, 0x16, 0xc4, 0x13,
-	0xa0, 0xc8, 0xb7, 0xfe, 0x27, 0x01, 0x6b, 0xbb, 0xfa, 0x64, 0x9f, 0xc8, 0xb0, 0x41, 0x4c, 0x4c,
-	0x0c, 0xea, 0x9a, 0xa8, 0x1b, 0x0d, 0x37, 0x57, 0xbc, 0x28, 0xc6, 0x09, 0xc7, 0x47, 0x9d, 0xa0,
-	0x00, 0x4b, 0x46, 0x0a, 0xb0, 0x35, 0xc8, 0x38, 0xd4, 0x31, 0x88, 0x8c, 0x45, 0xa2, 0xa1, 0x5a,
-	0xd1, 0x50, 0x53, 0x0a, 0x1f, 0xfb, 0xf8, 0x53, 0x5d, 0x9b, 0xfa, 0x61, 0x6f, 0xe8, 0x13, 0x28,
-	0xf5, 0x9a, 0x75, 0xdc, 0xec, 0xd7, 0x3a, 0x3f, 0xd4, 0x7a, 0xd5, 0x9d, 0x5e, 0xf5, 0xfe, 0x5d,
-	0xad, 0xdb, 0xd9, 0xf9, 0xf4, 0xde, 0x83, 0xbb, 0xdf, 0x53, 0x12, 0xa5, 0xf2, 0xe9, 0x59, 0xf9,
-	0x76, 0xbb, 0x5a, 0xdf, 0x11, 0x3b, 0x66, 0x9f, 0x3e, 0xeb, 0xe9, 0xb6, 0xa7, 0xdf, 0xbf, 0xdb,
-	0xa5, 0xf6, 0x84, 0x61, 0xd8, 0xb2, 0x2e, 0x46, 0xcf, 0xab, 0xe8, 0x31, 0x9c, 0xb8, 0xf4, 0x18,
-	0x9e, 0x9e, 0xe6, 0xc9, 0x4b, 0x4e, 0xf3, 0x2d, 0x58, 0x33, 0x5c, 0xea, 0x79, 0x1a, 0xcb, 0xfe,
-	0x89, 0x39, 0x57, 0x5f, 0x7c, 0xe3, 0xe2, 0x7c, 0x73, 0xb5, 0xce, 0xf8, 0x3d, 0xce, 0x96, 0xea,
-	0x57, 0x8d, 0x08, 0x89, 0xf7, 0xa4, 0xfe, 0x7e, 0x8a, 0x25, 0x52, 0xd6, 0xb1, 0x65, 0x93, 0x01,
-	0xf1, 0xd0, 0x13, 0x58, 0x31, 0x5c, 0x62, 0xb2, 0xb4, 0x5e, 0xb7, 0xa3, 0xbf, 0xe6, 0xfc, 0x7f,
-	0xb1, 0x39, 0x4d, 0x28, 0x58, 0xa9, 0x87, 0x52, 0xbd, 0x11, 0x31, 0xf0, 0xb2, 0x31, 0xd3, 0x46,
-	0x9f, 0xc1, 0x8a, 0x47, 0x6c, 0xcb, 0x19, 0x3f, 0xd3, 0x0c, 0xea, 0xf8, 0xe4, 0x59, 0xf0, 0x6e,
-	0x75, 0x9d, 0xde, 0x5e, 0x73, 0x87, 0x49, 0xd5, 0x85, 0x50, 0x0d, 0x5d, 0x9c, 0x6f, 0x2e, 0xcf,
-	0xd2, 0xf0, 0xb2, 0xd4, 0x2c, 0xdb, 0xa5, 0x36, 0x2c, 0xcf, 0x5a, 0x83, 0xd6, 0xe4, 0xde, 0xe7,
-	0x21, 0x24, 0xd8, 0xdb, 0xe8, 0x36, 0xe4, 0x5c, 0x32, 0xb0, 0x3c, 0xdf, 0x15, 0x6e, 0x66, 0x9c,
-	0x90, 0xc2, 0x76, 0xbe, 0xf8, 0x29, 0x4e, 0xe9, 0x57, 0x61, 0xae, 0x47, 0xb6, 0x59, 0x4c, 0xcb,
-	0xd3, 0xf7, 0xa5, 0xca, 0x1c, 0x0e, 0x9a, 0x6c, 0x0d, 0x8e, 0xbd, 0x30, 0x51, 0xe3, 0xdf, 0x8c,
-	0xc6, 0x33, 0x0a, 0xf9, 0xc3, 0x24, 0x9e, 0x33, 0x04, 0xbf, 0x70, 0x4c, 0x47, 0x7e, 0xe1, 0xb8,
-	0x06, 0x19, 0x9b, 0x1c, 0x13, 0x5b, 0x9c, 0xe5, 0x58, 0x34, 0xde, 0xfe, 0x59, 0x0a, 0xf2, 0xe1,
-	0x1b, 0x0d, 0x3b, 0x09, 0xda, 0xcd, 0xa7, 0xc1, 0x5a, 0x0d, 0xe9, 0x6d, 0x72, 0x82, 0x5e, 0x9b,
-	0xde, 0x29, 0x7d, 0x22, 0x1e, 0xa5, 0x43, 0x76, 0x70, 0x9f, 0xf4, 0x06, 0xe4, 0xaa, 0xbd, 0x5e,
-	0xeb, 0x51, 0xbb, 0xd9, 0x50, 0x3e, 0x4f, 0x94, 0xbe, 0x71, 0x7a, 0x56, 0x5e, 0x0d, 0x41, 0x55,
-	0x4f, 0x2c, 0x25, 0x8e, 0xaa, 0xd7, 0x9b, 0xdd, 0x7e, 0xb3, 0xa1, 0x3c, 0x4f, 0xce, 0xa3, 0xf8,
-	0x1d, 0x09, 0xff, 0x69, 0x49, 0xbe, 0x8b, 0x9b, 0xdd, 0x2a, 0x66, 0x1d, 0x7e, 0x9e, 0x14, 0x57,
-	0x5d, 0xd3, 0x1e, 0x5d, 0x32, 0xd2, 0x5d, 0xd6, 0xe7, 0x46, 0xf0, 0x13, 0xab, 0xe7, 0x29, 0xf1,
-	0xf3, 0x83, 0xe9, 0x83, 0x13, 0xd1, 0xcd, 0x09, 0xeb, 0x8d, 0xbf, 0xf4, 0x71, 0x35, 0xa9, 0xb9,
-	0xde, 0x7a, 0x2c, 0x92, 0x30, 0x2d, 0x2a, 0x2c, 0xe2, 0xbd, 0x76, 0x9b, 0x81, 0x9e, 0xa7, 0xe7,
-	0x46, 0x87, 0xc7, 0x0e, 0xab, 0x7f, 0xd1, 0x1d, 0xc8, 0x05, 0x0f, 0x81, 0xca, 0xe7, 0xe9, 0x39,
-	0x83, 0xea, 0xc1, 0x2b, 0x26, 0xef, 0x70, 0x7b, 0xaf, 0xcf, 0x7f, 0x01, 0xf6, 0x3c, 0x33, 0xdf,
-	0xe1, 0xe1, 0xd8, 0x37, 0xe9, 0x89, 0xc3, 0x76, 0xa0, 0xbc, 0x55, 0xfb, 0x3c, 0x23, 0xae, 0x20,
-	0x42, 0x8c, 0xbc, 0x52, 0x7b, 0x03, 0x72, 0xb8, 0xf9, 0x03, 0xf1, 0x63, 0xb1, 0xe7, 0xd9, 0x39,
-	0x3d, 0x98, 0x7c, 0x46, 0x0c, 0xd9, 0x5b, 0x07, 0x77, 0xb7, 0xab, 0xdc, 0xe5, 0xf3, 0xa8, 0x8e,
-	0x3b, 0x3a, 0xd4, 0x1d, 0x62, 0x4e, 0x7f, 0x83, 0x11, 0xb2, 0xde, 0xfe, 0x25, 0xc8, 0x05, 0x79,
-	0x26, 0xda, 0x80, 0xec, 0xd3, 0x0e, 0x7e, 0xdc, 0xc4, 0xca, 0x82, 0xf0, 0x61, 0xc0, 0x79, 0x2a,
-	0x2a, 0x84, 0x32, 0x2c, 0xee, 0x56, 0xdb, 0xd5, 0x47, 0x4d, 0x1c, 0x5c, 0x78, 0x07, 0x00, 0x99,
-	0x2c, 0x95, 0x14, 0xd9, 0x41, 0xa8, 0xb3, 0xb6, 0xfe, 0xc5, 0x97, 0x1b, 0x0b, 0x3f, 0xfd, 0x72,
-	0x63, 0xe1, 0xf9, 0xc5, 0x46, 0xe2, 0x8b, 0x8b, 0x8d, 0xc4, 0x4f, 0x2e, 0x36, 0x12, 0xff, 0x7a,
-	0xb1, 0x91, 0xd8, 0xcf, 0xf2, 0x90, 0xfe, 0xe0, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x48, 0x1c,
-	0x30, 0x25, 0x28, 0x30, 0x00, 0x00,
+	// 5020 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x5a, 0x4d, 0x6c, 0x24, 0x49,
+	0x56, 0x76, 0xfd, 0xba, 0xea, 0x55, 0xd9, 0x4e, 0x47, 0x7b, 0x7b, 0xdc, 0xb5, 0xdd, 0x76, 0x4d,
+	0xce, 0xf4, 0xce, 0x6c, 0x6f, 0x53, 0xfd, 0xb7, 0xbb, 0xea, 0x99, 0x61, 0x77, 0xa6, 0xfe, 0x6c,
+	0xd7, 0xb6, 0x5d, 0x55, 0x8a, 0x2a, 0x77, 0xef, 0x22, 0x41, 0x2a, 0x9d, 0x19, 0x2e, 0xe7, 0x38,
+	0x2b, 0xa3, 0xc8, 0xcc, 0xb2, 0xbb, 0x58, 0x10, 0x2d, 0x0e, 0x80, 0x7c, 0x82, 0xdb, 0x22, 0x64,
+	0x2e, 0x70, 0x42, 0x48, 0x1c, 0x40, 0x42, 0x70, 0x1a, 0x24, 0x0e, 0x7b, 0x83, 0x05, 0x09, 0xad,
+	0x40, 0x32, 0xac, 0x0f, 0xdc, 0x56, 0x70, 0x59, 0x71, 0x01, 0x09, 0xc5, 0x4f, 0x66, 0xa5, 0xab,
+	0xd3, 0x76, 0x0f, 0xb3, 0x17, 0xbb, 0xe2, 0xbd, 0xef, 0xbd, 0x78, 0xf1, 0x22, 0xe2, 0xc5, 0x7b,
+	0x11, 0x09, 0xf7, 0x06, 0x96, 0x7f, 0x30, 0xde, 0xab, 0x18, 0x74, 0xf8, 0xc0, 0xa4, 0xc6, 0x21,
+	0x71, 0x1f, 0x78, 0xc7, 0xba, 0x3b, 0x3c, 0xb4, 0xfc, 0x07, 0xfa, 0xc8, 0x7a, 0xe0, 0x4f, 0x46,
+	0xc4, 0xab, 0x8c, 0x5c, 0xea, 0x53, 0x84, 0x04, 0xa0, 0x12, 0x00, 0x2a, 0x47, 0x8f, 0x4a, 0xeb,
+	0x03, 0x4a, 0x07, 0x36, 0x79, 0xc0, 0x11, 0x7b, 0xe3, 0xfd, 0x07, 0xbe, 0x35, 0x24, 0x9e, 0xaf,
+	0x0f, 0x47, 0x42, 0xa8, 0xb4, 0x36, 0x0b, 0x30, 0xc7, 0xae, 0xee, 0x5b, 0xd4, 0x91, 0xfc, 0x95,
+	0x01, 0x1d, 0x50, 0xfe, 0xf3, 0x01, 0xfb, 0x25, 0xa8, 0xea, 0x3a, 0xcc, 0x3f, 0x27, 0xae, 0x67,
+	0x51, 0x07, 0xad, 0x40, 0xc6, 0x72, 0x4c, 0xf2, 0x72, 0x35, 0x51, 0x4e, 0xbc, 0x9f, 0xc6, 0xa2,
+	0xa1, 0x3e, 0x04, 0x68, 0xb1, 0x1f, 0x4d, 0xc7, 0x77, 0x27, 0x48, 0x81, 0xd4, 0x21, 0x99, 0x70,
+	0x44, 0x1e, 0xb3, 0x9f, 0x8c, 0x72, 0xa4, 0xdb, 0xab, 0x49, 0x41, 0x39, 0xd2, 0x6d, 0xf5, 0x27,
+	0x09, 0x28, 0x54, 0x1d, 0x87, 0xfa, 0xbc, 0x77, 0x0f, 0x21, 0x48, 0x3b, 0xfa, 0x90, 0x48, 0x21,
+	0xfe, 0x1b, 0xd5, 0x21, 0x6b, 0xeb, 0x7b, 0xc4, 0xf6, 0x56, 0x93, 0xe5, 0xd4, 0xfb, 0x85, 0xc7,
+	0x5f, 0xab, 0xbc, 0x3e, 0xe4, 0x4a, 0x44, 0x49, 0x65, 0x9b, 0xa3, 0xb9, 0x11, 0x58, 0x8a, 0xa2,
+	0x6f, 0xc3, 0xbc, 0xe5, 0x98, 0x96, 0x41, 0xbc, 0xd5, 0x34, 0xd7, 0xb2, 0x16, 0xa7, 0x65, 0x6a,
+	0x7d, 0x2d, 0xfd, 0xc3, 0xb3, 0xf5, 0x39, 0x1c, 0x08, 0x95, 0x3e, 0x80, 0x42, 0x44, 0x6d, 0xcc,
+	0xd8, 0x56, 0x20, 0x73, 0xa4, 0xdb, 0x63, 0x22, 0x47, 0x27, 0x1a, 0x1f, 0x26, 0x9f, 0x26, 0xd4,
+	0x4f, 0x60, 0xa5, 0xad, 0x0f, 0x89, 0xb9, 0x49, 0x1c, 0xe2, 0x5a, 0x06, 0x26, 0x1e, 0x1d, 0xbb,
+	0x06, 0x61, 0x63, 0x3d, 0xb4, 0x1c, 0x33, 0x18, 0x2b, 0xfb, 0x1d, 0xaf, 0x45, 0xad, 0xc3, 0x5b,
+	0x0d, 0xcb, 0x33, 0x5c, 0xe2, 0x93, 0xcf, 0xad, 0x24, 0x15, 0x28, 0x39, 0x4b, 0xc0, 0xd2, 0xac,
+	0xf4, 0x2f, 0xc1, 0x0d, 0xe6, 0x62, 0x53, 0x73, 0x25, 0x45, 0xf3, 0x46, 0xc4, 0xe0, 0xca, 0x0a,
+	0x8f, 0xdf, 0x8f, 0xf3, 0x50, 0xdc, 0x48, 0xb6, 0xe6, 0xf0, 0x32, 0x57, 0x13, 0x10, 0x7a, 0x23,
+	0x62, 0x20, 0x03, 0x6e, 0x9a, 0xd2, 0xe8, 0x19, 0xf5, 0x49, 0xae, 0x3e, 0x76, 0x1a, 0x2f, 0x19,
+	0xe6, 0xd6, 0x1c, 0x5e, 0x09, 0x94, 0x45, 0x3b, 0xa9, 0x01, 0xe4, 0x02, 0xdd, 0xea, 0x0f, 0x12,
+	0x90, 0x0f, 0x98, 0x1e, 0xfa, 0x2a, 0xe4, 0x1d, 0xdd, 0xa1, 0x9a, 0x31, 0x1a, 0x7b, 0x7c, 0x40,
+	0xa9, 0x5a, 0xf1, 0xfc, 0x6c, 0x3d, 0xd7, 0xd6, 0x1d, 0x5a, 0xef, 0xee, 0x7a, 0x38, 0xc7, 0xd8,
+	0xf5, 0xd1, 0xd8, 0x43, 0x6f, 0x43, 0x71, 0x48, 0x86, 0xd4, 0x9d, 0x68, 0x7b, 0x13, 0x9f, 0x78,
+	0xd2, 0x6d, 0x05, 0x41, 0xab, 0x31, 0x12, 0xfa, 0x16, 0xcc, 0x0f, 0x84, 0x49, 0xab, 0x29, 0xbe,
+	0x7c, 0xde, 0x89, 0xb3, 0x7e, 0xc6, 0x6a, 0x1c, 0xc8, 0xa8, 0xbf, 0x97, 0x80, 0x95, 0x90, 0x4a,
+	0x7e, 0x75, 0x6c, 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0xdf, 0x80, 0xac, 0x6d, 0x0d, 0x2d, 0xdf,
+	0x93, 0x3e, 0xbf, 0x13, 0xa7, 0x36, 0x1c, 0x14, 0x96, 0x60, 0x54, 0x85, 0xa2, 0x4b, 0x3c, 0xe2,
+	0x1e, 0x89, 0x15, 0x2f, 0x3d, 0x7a, 0x8d, 0xf0, 0x05, 0x11, 0x75, 0x03, 0x72, 0x5d, 0x5b, 0xf7,
+	0xf7, 0xa9, 0x3b, 0x44, 0x2a, 0x14, 0x75, 0xd7, 0x38, 0xb0, 0x7c, 0x62, 0xf8, 0x63, 0x37, 0xd8,
+	0x7d, 0x17, 0x68, 0xe8, 0x26, 0x24, 0xa9, 0xe8, 0x28, 0x5f, 0xcb, 0x9e, 0x9f, 0xad, 0x27, 0x3b,
+	0x3d, 0x9c, 0xa4, 0x9e, 0xfa, 0x11, 0x2c, 0x77, 0xed, 0xf1, 0xc0, 0x72, 0x1a, 0xc4, 0x33, 0x5c,
+	0x6b, 0xc4, 0xb4, 0xb3, 0x55, 0xc9, 0x62, 0x54, 0xb0, 0x2a, 0xd9, 0xef, 0x70, 0x6b, 0x27, 0xa7,
+	0x5b, 0x5b, 0xfd, 0x9d, 0x24, 0x2c, 0x37, 0x9d, 0x81, 0xe5, 0x90, 0xa8, 0xf4, 0x5d, 0x58, 0x24,
+	0x9c, 0xa8, 0x1d, 0x89, 0x70, 0x23, 0xf5, 0x2c, 0x08, 0x6a, 0x10, 0x83, 0x5a, 0x33, 0x71, 0xe1,
+	0x51, 0xdc, 0xf0, 0x5f, 0xd3, 0x1e, 0x1b, 0x1d, 0x9a, 0x30, 0x3f, 0xe2, 0x83, 0xf0, 0xe4, 0xf4,
+	0xde, 0x8d, 0xd3, 0xf5, 0xda, 0x38, 0x83, 0x20, 0x21, 0x65, 0xbf, 0x48, 0x90, 0xf8, 0xb3, 0x24,
+	0x2c, 0xb5, 0xa9, 0x79, 0xc1, 0x0f, 0x25, 0xc8, 0x1d, 0x50, 0xcf, 0x8f, 0x04, 0xc4, 0xb0, 0x8d,
+	0x9e, 0x42, 0x6e, 0x24, 0xa7, 0x4f, 0xce, 0xfe, 0xed, 0x78, 0x93, 0x05, 0x06, 0x87, 0x68, 0xf4,
+	0x11, 0xe4, 0x83, 0x2d, 0xc3, 0x46, 0xfb, 0x06, 0x0b, 0x67, 0x8a, 0x47, 0xdf, 0x82, 0xac, 0x98,
+	0x84, 0xd5, 0x34, 0x97, 0xbc, 0xfb, 0x46, 0x3e, 0xc7, 0x52, 0x08, 0x6d, 0x42, 0xce, 0xb7, 0x3d,
+	0xcd, 0x72, 0xf6, 0xe9, 0x6a, 0x86, 0x2b, 0x58, 0x8f, 0x0d, 0x32, 0xd4, 0x24, 0xfd, 0xed, 0x5e,
+	0xcb, 0xd9, 0xa7, 0xb5, 0xc2, 0xf9, 0xd9, 0xfa, 0xbc, 0x6c, 0xe0, 0x79, 0xdf, 0xf6, 0xd8, 0x0f,
+	0xf5, 0xf7, 0x13, 0x50, 0x88, 0xa0, 0xd0, 0x1d, 0x00, 0xdf, 0x1d, 0x7b, 0xbe, 0xe6, 0x52, 0xea,
+	0x73, 0x67, 0x15, 0x71, 0x9e, 0x53, 0x30, 0xa5, 0x3e, 0xaa, 0xc0, 0x0d, 0x83, 0xb8, 0xbe, 0x66,
+	0x79, 0xde, 0x98, 0xb8, 0x9a, 0x37, 0xde, 0xfb, 0x94, 0x18, 0x3e, 0x77, 0x5c, 0x11, 0x2f, 0x33,
+	0x56, 0x8b, 0x73, 0x7a, 0x82, 0x81, 0x9e, 0xc0, 0xcd, 0x28, 0x7e, 0x34, 0xde, 0xb3, 0x2d, 0x43,
+	0x63, 0x93, 0x99, 0xe2, 0x22, 0x37, 0xa6, 0x22, 0x5d, 0xce, 0x7b, 0x46, 0x26, 0xea, 0x8f, 0x13,
+	0xa0, 0x60, 0x7d, 0xdf, 0xdf, 0x21, 0xc3, 0x3d, 0xe2, 0xf6, 0x7c, 0xdd, 0x1f, 0x7b, 0xe8, 0x26,
+	0x64, 0x6d, 0xa2, 0x9b, 0xc4, 0xe5, 0x46, 0xe5, 0xb0, 0x6c, 0xa1, 0x5d, 0xb6, 0x83, 0x75, 0xe3,
+	0x40, 0xdf, 0xb3, 0x6c, 0xcb, 0x9f, 0x70, 0x53, 0x16, 0xe3, 0x97, 0xf0, 0xac, 0xce, 0x0a, 0x8e,
+	0x08, 0xe2, 0x0b, 0x6a, 0xd0, 0x2a, 0xcc, 0x0f, 0x89, 0xe7, 0xe9, 0x03, 0xc2, 0x2d, 0xcd, 0xe3,
+	0xa0, 0xa9, 0x7e, 0x04, 0xc5, 0xa8, 0x1c, 0x2a, 0xc0, 0xfc, 0x6e, 0xfb, 0x59, 0xbb, 0xf3, 0xa2,
+	0xad, 0xcc, 0xa1, 0x25, 0x28, 0xec, 0xb6, 0x71, 0xb3, 0x5a, 0xdf, 0xaa, 0xd6, 0xb6, 0x9b, 0x4a,
+	0x02, 0x2d, 0x40, 0x7e, 0xda, 0x4c, 0xaa, 0x7f, 0x91, 0x00, 0x60, 0xee, 0x96, 0x83, 0xfa, 0x10,
+	0x32, 0x9e, 0xaf, 0xfb, 0x62, 0x55, 0x2e, 0x3e, 0x7e, 0xf7, 0xb2, 0x39, 0x94, 0xf6, 0xb2, 0x7f,
+	0x04, 0x0b, 0x91, 0xa8, 0x85, 0xc9, 0x0b, 0x16, 0xb2, 0x00, 0xa1, 0x9b, 0xa6, 0x2b, 0x0d, 0xe7,
+	0xbf, 0xd5, 0x8f, 0x20, 0xc3, 0xa5, 0x2f, 0x9a, 0x9b, 0x83, 0x74, 0x83, 0xfd, 0x4a, 0xa0, 0x3c,
+	0x64, 0x70, 0xb3, 0xda, 0xf8, 0x9e, 0x92, 0x44, 0x0a, 0x14, 0x1b, 0xad, 0x5e, 0xbd, 0xd3, 0x6e,
+	0x37, 0xeb, 0xfd, 0x66, 0x43, 0x49, 0xa9, 0x77, 0x21, 0xd3, 0x1a, 0x32, 0xcd, 0xb7, 0xd9, 0x92,
+	0xdf, 0x27, 0x2e, 0x71, 0x8c, 0x60, 0x27, 0x4d, 0x09, 0xea, 0x4f, 0x0b, 0x90, 0xd9, 0xa1, 0x63,
+	0xc7, 0x47, 0x8f, 0x23, 0x61, 0x6b, 0x31, 0x3e, 0x43, 0xe0, 0xc0, 0x4a, 0x7f, 0x32, 0x22, 0x32,
+	0xac, 0xdd, 0x84, 0xac, 0xd8, 0x1c, 0x72, 0x38, 0xb2, 0xc5, 0xe8, 0xbe, 0xee, 0x0e, 0x88, 0x2f,
+	0xc7, 0x23, 0x5b, 0xe8, 0x7d, 0x76, 0x62, 0xe9, 0x26, 0x75, 0xec, 0x09, 0xdf, 0x43, 0x39, 0x71,
+	0x2c, 0x61, 0xa2, 0x9b, 0x1d, 0xc7, 0x9e, 0xe0, 0x90, 0x8b, 0xb6, 0xa0, 0xb8, 0x67, 0x39, 0xa6,
+	0x46, 0x47, 0x22, 0xc8, 0x67, 0x2e, 0xdf, 0x71, 0xc2, 0xaa, 0x9a, 0xe5, 0x98, 0x1d, 0x01, 0xc6,
+	0x85, 0xbd, 0x69, 0x03, 0xb5, 0x61, 0xf1, 0x88, 0xda, 0xe3, 0x21, 0x09, 0x75, 0x65, 0xb9, 0xae,
+	0xf7, 0x2e, 0xd7, 0xf5, 0x9c, 0xe3, 0x03, 0x6d, 0x0b, 0x47, 0xd1, 0x26, 0x7a, 0x06, 0x0b, 0xfe,
+	0x70, 0xb4, 0xef, 0x85, 0xea, 0xe6, 0xb9, 0xba, 0xaf, 0x5c, 0xe1, 0x30, 0x06, 0x0f, 0xb4, 0x15,
+	0xfd, 0x48, 0x0b, 0x6d, 0x42, 0xc1, 0xa0, 0x8e, 0x67, 0x79, 0x3e, 0x71, 0x8c, 0xc9, 0x6a, 0x8e,
+	0xfb, 0xfe, 0x8a, 0x51, 0xd6, 0xa7, 0x60, 0x1c, 0x95, 0x2c, 0xfd, 0x56, 0x0a, 0x0a, 0x11, 0x17,
+	0xa0, 0x1e, 0x14, 0x46, 0x2e, 0x1d, 0xe9, 0x03, 0x7e, 0xe2, 0xc9, 0x49, 0x7d, 0xf4, 0x46, 0xee,
+	0xab, 0x74, 0xa7, 0x82, 0x38, 0xaa, 0x45, 0x3d, 0x4d, 0x42, 0x21, 0xc2, 0x44, 0xf7, 0x20, 0x87,
+	0xbb, 0xb8, 0xf5, 0xbc, 0xda, 0x6f, 0x2a, 0x73, 0xa5, 0xdb, 0x27, 0xa7, 0xe5, 0x55, 0xae, 0x2d,
+	0xaa, 0xa0, 0xeb, 0x5a, 0x47, 0x6c, 0x0d, 0xbf, 0x0f, 0xf3, 0x01, 0x34, 0x51, 0xfa, 0xf2, 0xc9,
+	0x69, 0xf9, 0xad, 0x59, 0x68, 0x04, 0x89, 0x7b, 0x5b, 0x55, 0xdc, 0x6c, 0x28, 0xc9, 0x78, 0x24,
+	0xee, 0x1d, 0xe8, 0x2e, 0x31, 0xd1, 0x57, 0x20, 0x2b, 0x81, 0xa9, 0x52, 0xe9, 0xe4, 0xb4, 0x7c,
+	0x73, 0x16, 0x38, 0xc5, 0xe1, 0xde, 0x76, 0xf5, 0x79, 0x53, 0x49, 0xc7, 0xe3, 0x70, 0xcf, 0xd6,
+	0x8f, 0x08, 0x7a, 0x17, 0x32, 0x02, 0x96, 0x29, 0xdd, 0x3a, 0x39, 0x2d, 0x7f, 0xe9, 0x35, 0x75,
+	0x0c, 0x55, 0x5a, 0xfd, 0xdd, 0x3f, 0x5e, 0x9b, 0xfb, 0x9b, 0x3f, 0x59, 0x53, 0x66, 0xd9, 0xa5,
+	0xff, 0x49, 0xc0, 0xc2, 0x85, 0xb5, 0x83, 0x54, 0xc8, 0x3a, 0xd4, 0xa0, 0x23, 0x71, 0x10, 0xe6,
+	0x6a, 0x70, 0x7e, 0xb6, 0x9e, 0x6d, 0xd3, 0x3a, 0x1d, 0x4d, 0xb0, 0xe4, 0xa0, 0x67, 0x33, 0x47,
+	0xf9, 0x93, 0x37, 0x5c, 0x98, 0xb1, 0x87, 0xf9, 0xc7, 0xb0, 0x60, 0xba, 0xd6, 0x11, 0x71, 0x35,
+	0x83, 0x3a, 0xfb, 0xd6, 0x40, 0x1e, 0x72, 0xa5, 0xd8, 0x7c, 0x93, 0x03, 0x71, 0x51, 0x08, 0xd4,
+	0x39, 0xfe, 0x0b, 0x1c, 0xe3, 0xa5, 0xe7, 0x50, 0x8c, 0x2e, 0x75, 0x76, 0x2e, 0x79, 0xd6, 0xaf,
+	0x11, 0x99, 0x58, 0xf2, 0x34, 0x14, 0xe7, 0x19, 0x45, 0xa4, 0x95, 0xef, 0x41, 0x7a, 0x48, 0x4d,
+	0xa1, 0x67, 0xa1, 0x76, 0x83, 0x65, 0x13, 0xff, 0x72, 0xb6, 0x5e, 0xa0, 0x5e, 0x65, 0xc3, 0xb2,
+	0xc9, 0x0e, 0x35, 0x09, 0xe6, 0x00, 0xf5, 0x08, 0xd2, 0x2c, 0xe6, 0xa0, 0x2f, 0x43, 0xba, 0xd6,
+	0x6a, 0x37, 0x94, 0xb9, 0xd2, 0xf2, 0xc9, 0x69, 0x79, 0x81, 0xbb, 0x84, 0x31, 0xd8, 0xda, 0x45,
+	0xeb, 0x90, 0x7d, 0xde, 0xd9, 0xde, 0xdd, 0x61, 0xcb, 0xeb, 0xc6, 0xc9, 0x69, 0x79, 0x29, 0x64,
+	0x0b, 0xa7, 0xa1, 0x3b, 0x90, 0xe9, 0xef, 0x74, 0x37, 0x7a, 0x4a, 0xb2, 0x84, 0x4e, 0x4e, 0xcb,
+	0x8b, 0x21, 0x9f, 0xdb, 0x5c, 0x5a, 0x96, 0xb3, 0x9a, 0x0f, 0xe9, 0xea, 0x8f, 0x12, 0x50, 0x88,
+	0x6c, 0x38, 0xb6, 0x30, 0x1b, 0xcd, 0x8d, 0xea, 0xee, 0x76, 0x5f, 0x99, 0x8b, 0x2c, 0xcc, 0x08,
+	0xa4, 0x41, 0xf6, 0xf5, 0xb1, 0xcd, 0xe2, 0x1c, 0xd4, 0x3b, 0xed, 0x5e, 0xab, 0xd7, 0x6f, 0xb6,
+	0xfb, 0x4a, 0xa2, 0xb4, 0x7a, 0x72, 0x5a, 0x5e, 0x99, 0x05, 0x6f, 0x8c, 0x6d, 0x9b, 0x2d, 0xcd,
+	0x7a, 0xb5, 0xbe, 0xc5, 0xd7, 0xfa, 0x74, 0x69, 0x46, 0x50, 0x75, 0xdd, 0x38, 0x20, 0x26, 0xba,
+	0x0f, 0xf9, 0x46, 0x73, 0xbb, 0xb9, 0x59, 0xe5, 0xd1, 0xbd, 0x74, 0xe7, 0xe4, 0xb4, 0x7c, 0xeb,
+	0xf5, 0xde, 0x6d, 0x32, 0xd0, 0x7d, 0x62, 0xce, 0x2c, 0xd1, 0x08, 0x44, 0xfd, 0x59, 0x12, 0x16,
+	0x30, 0x2b, 0x87, 0x5d, 0xbf, 0x4b, 0x6d, 0xcb, 0x98, 0xa0, 0x2e, 0xe4, 0x0d, 0xea, 0x98, 0x56,
+	0x24, 0x4e, 0x3c, 0xbe, 0x24, 0x25, 0x9a, 0x4a, 0x05, 0xad, 0x7a, 0x20, 0x89, 0xa7, 0x4a, 0xd0,
+	0x03, 0xc8, 0x98, 0xc4, 0xd6, 0x27, 0x32, 0x37, 0xbb, 0x55, 0x11, 0x05, 0x77, 0x25, 0x28, 0xb8,
+	0x2b, 0x0d, 0x59, 0x70, 0x63, 0x81, 0xe3, 0x35, 0x88, 0xfe, 0x52, 0xd3, 0x7d, 0x9f, 0x0c, 0x47,
+	0xbe, 0x48, 0xcc, 0xd2, 0xb8, 0x30, 0xd4, 0x5f, 0x56, 0x25, 0x09, 0x3d, 0x82, 0xec, 0xb1, 0xe5,
+	0x98, 0xf4, 0x58, 0xe6, 0x5e, 0x57, 0x28, 0x95, 0x40, 0xf5, 0x84, 0xa5, 0x24, 0x33, 0x66, 0xb2,
+	0x35, 0xd4, 0xee, 0xb4, 0x9b, 0xc1, 0x1a, 0x92, 0xfc, 0x8e, 0xd3, 0xa6, 0x0e, 0xdb, 0xff, 0xd0,
+	0x69, 0x6b, 0x1b, 0xd5, 0xd6, 0xf6, 0x2e, 0x66, 0xeb, 0x68, 0xe5, 0xe4, 0xb4, 0xac, 0x84, 0x90,
+	0x0d, 0xdd, 0xb2, 0x59, 0x31, 0x70, 0x0b, 0x52, 0xd5, 0xf6, 0xf7, 0x94, 0x64, 0x49, 0x39, 0x39,
+	0x2d, 0x17, 0x43, 0x76, 0xd5, 0x99, 0x4c, 0xfd, 0x3e, 0xdb, 0xaf, 0xfa, 0xf7, 0x29, 0x28, 0xee,
+	0x8e, 0x4c, 0xdd, 0x27, 0x62, 0x9f, 0xa1, 0x32, 0x14, 0x46, 0xba, 0xab, 0xdb, 0x36, 0xb1, 0x2d,
+	0x6f, 0x28, 0xaf, 0x12, 0xa2, 0x24, 0xf4, 0xc1, 0x9b, 0xba, 0xb1, 0x96, 0x63, 0x7b, 0xe7, 0x07,
+	0xff, 0xb6, 0x9e, 0x08, 0x1c, 0xba, 0x0b, 0x8b, 0xfb, 0xc2, 0x5a, 0x4d, 0x37, 0xf8, 0xc4, 0xa6,
+	0xf8, 0xc4, 0x56, 0xe2, 0x26, 0x36, 0x6a, 0x56, 0x45, 0x0e, 0xb2, 0xca, 0xa5, 0xf0, 0xc2, 0x7e,
+	0xb4, 0x89, 0x9e, 0xc0, 0xfc, 0x90, 0x3a, 0x96, 0x4f, 0xdd, 0xeb, 0x67, 0x21, 0x40, 0xa2, 0x7b,
+	0xb0, 0xcc, 0x26, 0x37, 0xb0, 0x87, 0xb3, 0xf9, 0x71, 0x9e, 0xc4, 0x4b, 0x43, 0xfd, 0xa5, 0xec,
+	0x10, 0x33, 0x32, 0xaa, 0x41, 0x86, 0xba, 0x2c, 0x5f, 0xcc, 0x72, 0x73, 0xef, 0x5f, 0x6b, 0xae,
+	0x68, 0x74, 0x98, 0x0c, 0x16, 0xa2, 0xea, 0x37, 0x61, 0xe1, 0xc2, 0x20, 0x58, 0x9a, 0xd4, 0xad,
+	0xee, 0xf6, 0x9a, 0xca, 0x1c, 0x2a, 0x42, 0xae, 0xde, 0x69, 0xf7, 0x5b, 0xed, 0x5d, 0x96, 0xe7,
+	0x15, 0x21, 0x87, 0x3b, 0xdb, 0xdb, 0xb5, 0x6a, 0xfd, 0x99, 0x92, 0x54, 0x2b, 0x50, 0x88, 0x68,
+	0x43, 0x8b, 0x00, 0xbd, 0x7e, 0xa7, 0xab, 0x6d, 0xb4, 0x70, 0xaf, 0x2f, 0xb2, 0xc4, 0x5e, 0xbf,
+	0x8a, 0xfb, 0x92, 0x90, 0x50, 0xff, 0x33, 0x19, 0xcc, 0xa8, 0x4c, 0x0c, 0x6b, 0x17, 0x13, 0xc3,
+	0x2b, 0x8c, 0x97, 0xa9, 0xe1, 0xb4, 0x11, 0x26, 0x88, 0x1f, 0x00, 0xf0, 0x85, 0x43, 0x4c, 0x4d,
+	0xf7, 0xe5, 0xc4, 0x97, 0x5e, 0x73, 0x72, 0x3f, 0xb8, 0xd1, 0xc2, 0x79, 0x89, 0xae, 0xfa, 0xe8,
+	0x5b, 0x50, 0x34, 0xe8, 0x70, 0x64, 0x13, 0x29, 0x9c, 0xba, 0x56, 0xb8, 0x10, 0xe2, 0xab, 0x7e,
+	0x34, 0x35, 0x4d, 0x5f, 0x4c, 0x9e, 0x7f, 0x3b, 0x11, 0x78, 0x26, 0x26, 0x1b, 0x2d, 0x42, 0x6e,
+	0xb7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0x4d, 0x25, 0x81, 0x00, 0xb2, 0xdc, 0xd5, 0x0d, 0x25, 0xc9,
+	0xb2, 0xe8, 0x7a, 0x67, 0xa7, 0xbb, 0xdd, 0xe4, 0x11, 0x0b, 0xad, 0x80, 0x12, 0x38, 0x5b, 0xe3,
+	0x8e, 0x6c, 0x36, 0x94, 0x34, 0xba, 0x01, 0x4b, 0x21, 0x55, 0x4a, 0x66, 0xd0, 0x4d, 0x40, 0x21,
+	0x71, 0xaa, 0x22, 0xab, 0xfe, 0x06, 0x2c, 0xd5, 0xa9, 0xe3, 0xeb, 0x96, 0x13, 0x56, 0x18, 0x8f,
+	0xd9, 0xa0, 0x25, 0x49, 0xb3, 0xe4, 0x4d, 0x50, 0x6d, 0xe9, 0xfc, 0x6c, 0xbd, 0x10, 0x42, 0x5b,
+	0x0d, 0x9e, 0x2a, 0xc9, 0x86, 0xc9, 0xf6, 0xef, 0xc8, 0x32, 0xb9, 0x73, 0x33, 0xb5, 0xf9, 0xf3,
+	0xb3, 0xf5, 0x54, 0xb7, 0xd5, 0xc0, 0x8c, 0x86, 0xbe, 0x0c, 0x79, 0xf2, 0xd2, 0xf2, 0x35, 0x83,
+	0x9d, 0x4b, 0xcc, 0x81, 0x19, 0x9c, 0x63, 0x84, 0x3a, 0x3b, 0x86, 0x6a, 0x00, 0x5d, 0xea, 0xfa,
+	0xb2, 0xe7, 0xaf, 0x43, 0x66, 0x44, 0x5d, 0x7e, 0x77, 0x71, 0xe9, 0x8d, 0x1a, 0x83, 0x8b, 0x85,
+	0x8a, 0x05, 0x58, 0xfd, 0x83, 0x14, 0x40, 0x5f, 0xf7, 0x0e, 0xa5, 0x92, 0xa7, 0x90, 0x0f, 0x6f,
+	0x27, 0xe5, 0x25, 0xc8, 0x95, 0xb3, 0x1d, 0x82, 0xd1, 0x93, 0x60, 0xb1, 0x89, 0xda, 0x29, 0xb6,
+	0x88, 0x0d, 0x3a, 0x8a, 0x2b, 0x3f, 0x2e, 0x16, 0x48, 0xec, 0x98, 0x27, 0xae, 0x2b, 0x67, 0x9e,
+	0xfd, 0x44, 0x75, 0x7e, 0x2c, 0x08, 0xa7, 0xc9, 0xec, 0x3b, 0xf6, 0xda, 0x67, 0x66, 0x46, 0xb6,
+	0xe6, 0xf0, 0x54, 0x0e, 0x7d, 0x0c, 0x05, 0x36, 0x6e, 0xcd, 0xe3, 0x3c, 0x99, 0x78, 0x5f, 0xea,
+	0x2a, 0xa1, 0x01, 0xc3, 0x68, 0xea, 0xe5, 0x3b, 0x00, 0xfa, 0x68, 0x64, 0x5b, 0xc4, 0xd4, 0xf6,
+	0x26, 0x3c, 0xd3, 0xce, 0xe3, 0xbc, 0xa4, 0xd4, 0x26, 0x6c, 0xbb, 0x04, 0x6c, 0xdd, 0xe7, 0xd9,
+	0xf3, 0x35, 0x0e, 0x94, 0xe8, 0xaa, 0x5f, 0x53, 0x60, 0xd1, 0x1d, 0x3b, 0xcc, 0xa1, 0xd2, 0x3a,
+	0xf5, 0xcf, 0x93, 0xf0, 0x56, 0x9b, 0xf8, 0xc7, 0xd4, 0x3d, 0xac, 0xfa, 0xbe, 0x6e, 0x1c, 0x0c,
+	0x89, 0x23, 0xa7, 0x2f, 0x52, 0xd0, 0x24, 0x2e, 0x14, 0x34, 0xab, 0x30, 0xaf, 0xdb, 0x96, 0xee,
+	0x11, 0x91, 0xbc, 0xe5, 0x71, 0xd0, 0x64, 0x65, 0x17, 0x2b, 0xe2, 0x88, 0xe7, 0x11, 0x71, 0xaf,
+	0xc2, 0x0c, 0x0f, 0x08, 0xe8, 0xfb, 0x70, 0x53, 0xa6, 0x69, 0x7a, 0xd8, 0x15, 0x2b, 0x28, 0x82,
+	0x0b, 0xda, 0x66, 0x6c, 0x55, 0x19, 0x6f, 0x9c, 0xcc, 0xe3, 0xa6, 0xe4, 0xce, 0xc8, 0x97, 0x59,
+	0xe1, 0x8a, 0x19, 0xc3, 0x2a, 0x6d, 0xc2, 0xad, 0x4b, 0x45, 0x3e, 0xd7, 0xbd, 0xcd, 0x3f, 0x25,
+	0x01, 0x5a, 0xdd, 0xea, 0x8e, 0x74, 0x52, 0x03, 0xb2, 0xfb, 0xfa, 0xd0, 0xb2, 0x27, 0x57, 0x45,
+	0xc0, 0x29, 0xbe, 0x52, 0x15, 0xee, 0xd8, 0xe0, 0x32, 0x58, 0xca, 0xf2, 0x9a, 0x72, 0xbc, 0xe7,
+	0x10, 0x3f, 0xac, 0x29, 0x79, 0x8b, 0x99, 0xe1, 0xea, 0x4e, 0xb8, 0x74, 0x45, 0x83, 0x4d, 0x00,
+	0x4b, 0x79, 0x8e, 0xf5, 0x49, 0x10, 0xb6, 0x64, 0x13, 0x6d, 0xf1, 0xdb, 0x51, 0xe2, 0x1e, 0x11,
+	0x73, 0x35, 0xc3, 0x9d, 0x7a, 0x9d, 0x3d, 0x58, 0xc2, 0x85, 0xef, 0x42, 0xe9, 0xd2, 0x47, 0x3c,
+	0x65, 0x9a, 0xb2, 0x3e, 0x97, 0x8f, 0x1e, 0xc2, 0xc2, 0x85, 0x71, 0xbe, 0x56, 0xcc, 0xb7, 0xba,
+	0xcf, 0xbf, 0xae, 0xa4, 0xe5, 0xaf, 0x6f, 0x2a, 0x59, 0xf5, 0x4f, 0x53, 0x22, 0xd0, 0x48, 0xaf,
+	0xc6, 0xbf, 0x0a, 0xe4, 0xf8, 0xea, 0x36, 0xa8, 0x2d, 0x03, 0xc0, 0x7b, 0x57, 0xc7, 0x1f, 0x56,
+	0xd3, 0x71, 0x38, 0x0e, 0x05, 0xd1, 0x3a, 0x14, 0xc4, 0x2a, 0xd6, 0xd8, 0x86, 0xe3, 0x6e, 0x5d,
+	0xc0, 0x20, 0x48, 0x4c, 0x12, 0xdd, 0x85, 0x45, 0x7e, 0xf9, 0xe3, 0x1d, 0x10, 0x53, 0x60, 0xd2,
+	0x1c, 0xb3, 0x10, 0x52, 0x39, 0x6c, 0x07, 0x8a, 0x92, 0xa0, 0xf1, 0x7c, 0x3e, 0xc3, 0x0d, 0xba,
+	0x77, 0x9d, 0x41, 0x42, 0x84, 0xa7, 0xf9, 0x85, 0xd1, 0xb4, 0xa1, 0x36, 0x20, 0x17, 0x18, 0x8b,
+	0x56, 0x21, 0xd5, 0xaf, 0x77, 0x95, 0xb9, 0xd2, 0xd2, 0xc9, 0x69, 0xb9, 0x10, 0x90, 0xfb, 0xf5,
+	0x2e, 0xe3, 0xec, 0x36, 0xba, 0x4a, 0xe2, 0x22, 0x67, 0xb7, 0xd1, 0x2d, 0xa5, 0x59, 0x0e, 0xa6,
+	0xee, 0x43, 0x21, 0xd2, 0x03, 0x7a, 0x07, 0xe6, 0x5b, 0xed, 0x4d, 0xdc, 0xec, 0xf5, 0x94, 0xb9,
+	0xd2, 0xcd, 0x93, 0xd3, 0x32, 0x8a, 0x70, 0x5b, 0xce, 0x80, 0xcd, 0x0f, 0xba, 0x03, 0xe9, 0xad,
+	0x0e, 0x3b, 0xdb, 0x45, 0x01, 0x11, 0x41, 0x6c, 0x51, 0xcf, 0x2f, 0xdd, 0x90, 0xc9, 0x5d, 0x54,
+	0xb1, 0xfa, 0x87, 0x09, 0xc8, 0x8a, 0xcd, 0x14, 0x3b, 0x51, 0x55, 0x98, 0x0f, 0xae, 0x09, 0x44,
+	0x71, 0xf7, 0xde, 0xe5, 0x85, 0x58, 0x45, 0xd6, 0x4d, 0x62, 0xf9, 0x05, 0x72, 0xa5, 0x0f, 0xa1,
+	0x18, 0x65, 0x7c, 0xae, 0xc5, 0xf7, 0x7d, 0x28, 0xb0, 0xf5, 0x1d, 0x14, 0x64, 0x8f, 0x21, 0x2b,
+	0x02, 0x42, 0x78, 0xd6, 0x5c, 0x5e, 0x15, 0x4a, 0x24, 0x7a, 0x0a, 0xf3, 0xa2, 0x92, 0x0c, 0x6e,
+	0x87, 0xd7, 0xae, 0xde, 0x45, 0x38, 0x80, 0xab, 0x1f, 0x43, 0xba, 0x4b, 0x88, 0xcb, 0x7c, 0xef,
+	0x50, 0x93, 0x4c, 0x8f, 0x67, 0x59, 0x04, 0x9b, 0xa4, 0xd5, 0x60, 0x45, 0xb0, 0x49, 0x5a, 0x66,
+	0x78, 0xff, 0x95, 0x8c, 0xdc, 0x7f, 0xf5, 0xa1, 0xf8, 0x82, 0x58, 0x83, 0x03, 0x9f, 0x98, 0x5c,
+	0xd1, 0x7d, 0x48, 0x8f, 0x48, 0x68, 0xfc, 0x6a, 0xec, 0x02, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, 0xe2,
+	0xc8, 0x31, 0x97, 0x96, 0x4f, 0x1a, 0xb2, 0xa5, 0xfe, 0x63, 0x12, 0x16, 0x5b, 0x9e, 0x37, 0xd6,
+	0x1d, 0x23, 0xc8, 0xdc, 0xbe, 0x7d, 0x31, 0x73, 0x8b, 0x7d, 0xfb, 0xb9, 0x28, 0x72, 0xf1, 0x5a,
+	0x4f, 0x9e, 0x9e, 0xc9, 0xf0, 0xf4, 0x54, 0x7f, 0x9a, 0x08, 0xee, 0xee, 0xee, 0x46, 0xb6, 0xbb,
+	0xa8, 0x03, 0xa3, 0x9a, 0xc8, 0xae, 0x73, 0xe8, 0xd0, 0x63, 0x07, 0xbd, 0x0d, 0x19, 0xdc, 0x6c,
+	0x37, 0x5f, 0x28, 0x09, 0xb1, 0x3c, 0x2f, 0x80, 0x30, 0x71, 0xc8, 0x31, 0xd3, 0xd4, 0x6d, 0xb6,
+	0x1b, 0x2c, 0xd3, 0x4a, 0xc6, 0x68, 0xea, 0x12, 0xc7, 0xb4, 0x9c, 0x01, 0x7a, 0x07, 0xb2, 0xad,
+	0x5e, 0x6f, 0x97, 0x97, 0x89, 0x6f, 0x9d, 0x9c, 0x96, 0x6f, 0x5c, 0x40, 0xf1, 0x7b, 0x5b, 0x93,
+	0x81, 0x58, 0x99, 0xc3, 0x72, 0xb0, 0x18, 0x10, 0xcb, 0x9f, 0x05, 0x08, 0x77, 0xfa, 0xd5, 0x7e,
+	0x53, 0xc9, 0xc4, 0x80, 0x30, 0x65, 0x7f, 0xe5, 0x76, 0xfb, 0xd7, 0x24, 0x28, 0x55, 0xc3, 0x20,
+	0x23, 0x9f, 0xf1, 0x65, 0x65, 0xd9, 0x87, 0xdc, 0x88, 0xfd, 0xb2, 0x48, 0x90, 0x25, 0x3d, 0x8d,
+	0x7d, 0xbd, 0x9c, 0x91, 0xab, 0x60, 0x6a, 0x93, 0xaa, 0x39, 0xb4, 0x3c, 0xcf, 0xa2, 0x8e, 0xa0,
+	0xe1, 0x50, 0x53, 0xe9, 0xbf, 0x12, 0x70, 0x23, 0x06, 0x81, 0x1e, 0x42, 0xda, 0xa5, 0x76, 0x30,
+	0x87, 0xb7, 0x2f, 0xbb, 0x96, 0x65, 0xa2, 0x98, 0x23, 0xd1, 0x1a, 0x80, 0x3e, 0xf6, 0xa9, 0xce,
+	0xfb, 0xe7, 0xb3, 0x97, 0xc3, 0x11, 0x0a, 0x7a, 0x01, 0x59, 0x8f, 0x18, 0x2e, 0x09, 0x72, 0xe9,
+	0x8f, 0xff, 0xbf, 0xd6, 0x57, 0x7a, 0x5c, 0x0d, 0x96, 0xea, 0x4a, 0x15, 0xc8, 0x0a, 0x0a, 0x5b,
+	0xf6, 0xa6, 0xee, 0xeb, 0xf2, 0xd2, 0x9e, 0xff, 0x66, 0xab, 0x49, 0xb7, 0x07, 0xc1, 0x6a, 0xd2,
+	0xed, 0x81, 0xfa, 0x77, 0x49, 0x80, 0xe6, 0x4b, 0x9f, 0xb8, 0x8e, 0x6e, 0xd7, 0xab, 0xa8, 0x19,
+	0x89, 0xfe, 0x62, 0xb4, 0x5f, 0x8d, 0x7d, 0x89, 0x08, 0x25, 0x2a, 0xf5, 0x6a, 0x4c, 0xfc, 0xbf,
+	0x05, 0xa9, 0xb1, 0x2b, 0x1f, 0xa4, 0x45, 0x1e, 0xbc, 0x8b, 0xb7, 0x31, 0xa3, 0xa1, 0xe6, 0x34,
+	0x6c, 0xa5, 0x2e, 0x7f, 0x76, 0x8e, 0x74, 0x10, 0x1b, 0xba, 0xd8, 0xce, 0x37, 0x74, 0xcd, 0x20,
+	0xf2, 0xe4, 0x28, 0x8a, 0x9d, 0x5f, 0xaf, 0xd6, 0x89, 0xeb, 0xe3, 0xac, 0xa1, 0xb3, 0xff, 0x5f,
+	0x28, 0xbe, 0xdd, 0x07, 0x98, 0x0e, 0x0d, 0xad, 0x41, 0xa6, 0xbe, 0xd1, 0xeb, 0x6d, 0x2b, 0x73,
+	0x22, 0x80, 0x4f, 0x59, 0x9c, 0xac, 0xfe, 0x75, 0x12, 0x72, 0xf5, 0xaa, 0x3c, 0x56, 0xeb, 0xa0,
+	0xf0, 0xa8, 0xc4, 0x9f, 0x3a, 0xc8, 0xcb, 0x91, 0xe5, 0x4e, 0x64, 0x60, 0xb9, 0xa2, 0xa8, 0x5d,
+	0x64, 0x22, 0xcc, 0xea, 0x26, 0x17, 0x40, 0x18, 0x8a, 0x44, 0x3a, 0x41, 0x33, 0xf4, 0x20, 0xc6,
+	0xaf, 0x5d, 0xed, 0x2c, 0x51, 0x9e, 0x4c, 0xdb, 0x1e, 0x2e, 0x04, 0x4a, 0xea, 0xba, 0x87, 0x3e,
+	0x80, 0x25, 0xcf, 0x1a, 0x38, 0x96, 0x33, 0xd0, 0x02, 0xe7, 0xf1, 0x77, 0x97, 0xda, 0xf2, 0xf9,
+	0xd9, 0xfa, 0x42, 0x4f, 0xb0, 0xa4, 0x0f, 0x17, 0x24, 0xb2, 0xce, 0x5d, 0x89, 0xbe, 0x09, 0x8b,
+	0x11, 0x51, 0xe6, 0x45, 0xe1, 0x76, 0xe5, 0xfc, 0x6c, 0xbd, 0x18, 0x4a, 0x3e, 0x23, 0x13, 0x5c,
+	0x0c, 0x05, 0x9f, 0x11, 0x7e, 0xff, 0xb2, 0x4f, 0x5d, 0x83, 0x68, 0x2e, 0xdf, 0xd3, 0xfc, 0x04,
+	0x4f, 0xe3, 0x02, 0xa7, 0x89, 0x6d, 0xae, 0x3e, 0x87, 0x1b, 0x1d, 0xd7, 0x38, 0x20, 0x9e, 0x2f,
+	0x5c, 0x21, 0xbd, 0xf8, 0x31, 0xdc, 0xf6, 0x75, 0xef, 0x50, 0x3b, 0xb0, 0x3c, 0x9f, 0xba, 0x13,
+	0xcd, 0x25, 0x3e, 0x71, 0x18, 0x5f, 0xe3, 0x8f, 0xb5, 0xf2, 0xd2, 0xef, 0x16, 0xc3, 0x6c, 0x09,
+	0x08, 0x0e, 0x10, 0xdb, 0x0c, 0xa0, 0xb6, 0xa0, 0xc8, 0xca, 0x14, 0x79, 0x71, 0xc6, 0x46, 0x0f,
+	0x36, 0x1d, 0x68, 0x6f, 0x7c, 0x4c, 0xe5, 0x6d, 0x3a, 0x10, 0x3f, 0xd5, 0xef, 0x82, 0xd2, 0xb0,
+	0xbc, 0x91, 0xee, 0x1b, 0x07, 0xc1, 0x6d, 0x26, 0x6a, 0x80, 0x72, 0x40, 0x74, 0xd7, 0xdf, 0x23,
+	0xba, 0xaf, 0x8d, 0x88, 0x6b, 0x51, 0xf3, 0xfa, 0x59, 0x5e, 0x0a, 0x45, 0xba, 0x5c, 0x42, 0xfd,
+	0xef, 0x04, 0x00, 0xd6, 0xf7, 0x83, 0x8c, 0xec, 0x6b, 0xb0, 0xec, 0x39, 0xfa, 0xc8, 0x3b, 0xa0,
+	0xbe, 0x66, 0x39, 0x3e, 0x71, 0x8f, 0x74, 0x5b, 0x5e, 0xe0, 0x28, 0x01, 0xa3, 0x25, 0xe9, 0xe8,
+	0x3e, 0xa0, 0x43, 0x42, 0x46, 0x1a, 0xb5, 0x4d, 0x2d, 0x60, 0x8a, 0xa7, 0xe4, 0x34, 0x56, 0x18,
+	0xa7, 0x63, 0x9b, 0xbd, 0x80, 0x8e, 0x6a, 0xb0, 0xc6, 0x86, 0x4f, 0x1c, 0xdf, 0xb5, 0x88, 0xa7,
+	0xed, 0x53, 0x57, 0xf3, 0x6c, 0x7a, 0xac, 0xed, 0x53, 0xdb, 0xa6, 0xc7, 0xc4, 0x0d, 0xee, 0xc6,
+	0x4a, 0x36, 0x1d, 0x34, 0x05, 0x68, 0x83, 0xba, 0x3d, 0x9b, 0x1e, 0x6f, 0x04, 0x08, 0x96, 0xb6,
+	0x4d, 0xc7, 0xec, 0x5b, 0xc6, 0x61, 0x90, 0xb6, 0x85, 0xd4, 0xbe, 0x65, 0x1c, 0xa2, 0x77, 0x60,
+	0x81, 0xd8, 0x84, 0x5f, 0x91, 0x08, 0x54, 0x86, 0xa3, 0x8a, 0x01, 0x91, 0x81, 0xd4, 0x4f, 0x40,
+	0x69, 0x3a, 0x86, 0x3b, 0x19, 0x45, 0xe6, 0xfc, 0x3e, 0x20, 0x16, 0x24, 0x35, 0x9b, 0x1a, 0x87,
+	0xda, 0x50, 0x77, 0xf4, 0x01, 0xb3, 0x4b, 0xbc, 0xf0, 0x29, 0x8c, 0xb3, 0x4d, 0x8d, 0xc3, 0x1d,
+	0x49, 0x57, 0x3f, 0x00, 0xe8, 0x8d, 0x5c, 0xa2, 0x9b, 0x1d, 0x96, 0x4d, 0x30, 0xd7, 0xf1, 0x96,
+	0x66, 0xca, 0x17, 0x52, 0xea, 0xca, 0xad, 0xae, 0x08, 0x46, 0x23, 0xa4, 0xab, 0xbf, 0x0c, 0x37,
+	0xba, 0xb6, 0x6e, 0xf0, 0xaf, 0x05, 0xba, 0xe1, 0x93, 0x15, 0x7a, 0x0a, 0x59, 0x01, 0x95, 0x33,
+	0x19, 0xbb, 0xdd, 0xa6, 0x7d, 0x6e, 0xcd, 0x61, 0x89, 0xaf, 0x15, 0x01, 0xa6, 0x7a, 0xd4, 0xbf,
+	0x4c, 0x40, 0x3e, 0xd4, 0x8f, 0xca, 0xe2, 0x25, 0xc6, 0x77, 0x75, 0xcb, 0x91, 0x55, 0x7d, 0x1e,
+	0x47, 0x49, 0xa8, 0x05, 0x85, 0x51, 0x28, 0x7d, 0x65, 0x3e, 0x17, 0x63, 0x35, 0x8e, 0xca, 0xa2,
+	0x0f, 0x21, 0x1f, 0x3c, 0x49, 0x07, 0x11, 0xf6, 0xea, 0x17, 0xec, 0x29, 0x5c, 0xfd, 0x36, 0xc0,
+	0x77, 0xa8, 0xe5, 0xf4, 0xe9, 0x21, 0x71, 0xf8, 0x13, 0x2b, 0xab, 0x09, 0x49, 0xe0, 0x45, 0xd9,
+	0xe2, 0xa5, 0xbe, 0x98, 0x82, 0xf0, 0xa5, 0x51, 0x34, 0xd5, 0xbf, 0x4d, 0x42, 0x16, 0x53, 0xea,
+	0xd7, 0xab, 0xa8, 0x0c, 0x59, 0x19, 0x27, 0xf8, 0xf9, 0x53, 0xcb, 0x9f, 0x9f, 0xad, 0x67, 0x44,
+	0x80, 0xc8, 0x18, 0x3c, 0x32, 0x44, 0x22, 0x78, 0xf2, 0xb2, 0x08, 0x8e, 0x1e, 0x42, 0x51, 0x82,
+	0xb4, 0x03, 0xdd, 0x3b, 0x10, 0x05, 0x5a, 0x6d, 0xf1, 0xfc, 0x6c, 0x1d, 0x04, 0x72, 0x4b, 0xf7,
+	0x0e, 0x30, 0x08, 0x34, 0xfb, 0x8d, 0x9a, 0x50, 0xf8, 0x94, 0x5a, 0x8e, 0xe6, 0xf3, 0x41, 0xc8,
+	0xcb, 0xc4, 0xd8, 0x79, 0x9c, 0x0e, 0x55, 0x7e, 0x6f, 0x00, 0x9f, 0x4e, 0x07, 0xdf, 0x84, 0x05,
+	0x97, 0x52, 0x5f, 0x84, 0x2d, 0x8b, 0x3a, 0xf2, 0x9e, 0xa2, 0x1c, 0x7b, 0x7d, 0x4d, 0xa9, 0x8f,
+	0x25, 0x0e, 0x17, 0xdd, 0x48, 0x0b, 0x3d, 0x84, 0x15, 0x5b, 0xf7, 0x7c, 0x8d, 0xc7, 0x3b, 0x73,
+	0xaa, 0x2d, 0xcb, 0xb7, 0x1a, 0x62, 0xbc, 0x0d, 0xce, 0x0a, 0x24, 0xd4, 0x7f, 0x4e, 0x40, 0x81,
+	0x0d, 0xc6, 0xda, 0xb7, 0x0c, 0x96, 0xe4, 0x7d, 0xfe, 0xdc, 0xe3, 0x16, 0xa4, 0x0c, 0xcf, 0x95,
+	0x4e, 0xe5, 0x87, 0x6f, 0xbd, 0x87, 0x31, 0xa3, 0xa1, 0x4f, 0x20, 0x2b, 0xef, 0x4b, 0x44, 0xda,
+	0xa1, 0x5e, 0x9f, 0x8e, 0x4a, 0xdf, 0x48, 0x39, 0xbe, 0x96, 0xa7, 0xd6, 0x89, 0x43, 0x00, 0x47,
+	0x49, 0xe8, 0x26, 0x24, 0x0d, 0xe1, 0x2e, 0xf9, 0x41, 0x4b, 0xbd, 0x8d, 0x93, 0x86, 0xa3, 0xfe,
+	0x28, 0x01, 0x0b, 0xd3, 0x0d, 0xcf, 0x56, 0xc0, 0x6d, 0xc8, 0x7b, 0xe3, 0x3d, 0x6f, 0xe2, 0xf9,
+	0x64, 0x18, 0x3c, 0x1f, 0x87, 0x04, 0xd4, 0x82, 0xbc, 0x6e, 0x0f, 0xa8, 0x6b, 0xf9, 0x07, 0x43,
+	0x59, 0x89, 0xc6, 0xa7, 0x0a, 0x51, 0x9d, 0x95, 0x6a, 0x20, 0x82, 0xa7, 0xd2, 0xc1, 0xb9, 0x2f,
+	0xbe, 0x31, 0xe0, 0xe7, 0xfe, 0xdb, 0x50, 0xb4, 0xf5, 0x21, 0xbf, 0x40, 0xf2, 0xad, 0xa1, 0x18,
+	0x47, 0x1a, 0x17, 0x24, 0xad, 0x6f, 0x0d, 0x89, 0xaa, 0x42, 0x3e, 0x54, 0x86, 0x96, 0xa0, 0x50,
+	0x6d, 0xf6, 0xb4, 0x47, 0x8f, 0x9f, 0x6a, 0x9b, 0xf5, 0x1d, 0x65, 0x4e, 0xe6, 0xa6, 0x7f, 0x95,
+	0x80, 0x05, 0x19, 0x8e, 0x64, 0xbe, 0xff, 0x0e, 0xcc, 0xbb, 0xfa, 0xbe, 0x1f, 0x54, 0x24, 0x69,
+	0xb1, 0xaa, 0x59, 0x84, 0x67, 0x15, 0x09, 0x63, 0xc5, 0x57, 0x24, 0x91, 0x0f, 0x1a, 0x52, 0x57,
+	0x7e, 0xd0, 0x90, 0xfe, 0xb9, 0x7c, 0xd0, 0xa0, 0xfe, 0x26, 0xc0, 0x86, 0x65, 0x93, 0xbe, 0xb8,
+	0x6b, 0x8a, 0xab, 0x2f, 0x59, 0x0e, 0x27, 0xef, 0x32, 0x83, 0x1c, 0xae, 0xd5, 0xc0, 0x8c, 0xc6,
+	0x58, 0x03, 0xcb, 0x94, 0x9b, 0x91, 0xb3, 0x36, 0x19, 0x6b, 0x60, 0x99, 0xe1, 0xcb, 0x5b, 0xfa,
+	0xba, 0x97, 0xb7, 0xd3, 0x04, 0x2c, 0xc9, 0xdc, 0x35, 0x0c, 0xbf, 0x5f, 0x85, 0xbc, 0x48, 0x63,
+	0xa7, 0x05, 0x1d, 0x7f, 0xc4, 0x17, 0xb8, 0x56, 0x03, 0xe7, 0x04, 0xbb, 0x65, 0xa2, 0x75, 0x28,
+	0x48, 0x68, 0xe4, 0xe3, 0x27, 0x10, 0xa4, 0x36, 0x33, 0xff, 0xeb, 0x90, 0xde, 0xb7, 0x6c, 0x22,
+	0x17, 0x7a, 0x6c, 0x00, 0x98, 0x3a, 0x60, 0x6b, 0x0e, 0x73, 0x74, 0x2d, 0x17, 0x5c, 0xc6, 0x71,
+	0xfb, 0x64, 0xd9, 0x19, 0xb5, 0x4f, 0x54, 0xa0, 0x33, 0xf6, 0x09, 0x1c, 0xb3, 0x4f, 0xb0, 0x85,
+	0x7d, 0x12, 0x1a, 0xb5, 0x4f, 0x90, 0x7e, 0x2e, 0xf6, 0x6d, 0xc3, 0xcd, 0x9a, 0xad, 0x1b, 0x87,
+	0xb6, 0xe5, 0xf9, 0xc4, 0x8c, 0x46, 0x8c, 0xc7, 0x90, 0xbd, 0x90, 0x74, 0x5e, 0x75, 0x6b, 0x29,
+	0x91, 0xea, 0x7f, 0x24, 0xa0, 0xb8, 0x45, 0x74, 0xdb, 0x3f, 0x98, 0x5e, 0x0d, 0xf9, 0xc4, 0xf3,
+	0xe5, 0x61, 0xc5, 0x7f, 0xa3, 0x6f, 0x40, 0x2e, 0xcc, 0x49, 0xae, 0x7d, 0x7f, 0x0b, 0xa1, 0xe8,
+	0x09, 0xcc, 0xb3, 0x3d, 0x46, 0xc7, 0x41, 0xb1, 0x73, 0xd5, 0xd3, 0x8e, 0x44, 0xb2, 0x43, 0xc6,
+	0x25, 0x3c, 0x09, 0xe1, 0x4b, 0x29, 0x83, 0x83, 0x26, 0xfa, 0x45, 0x28, 0xf2, 0x97, 0x89, 0x20,
+	0xe7, 0xca, 0x5c, 0xa7, 0xb3, 0x20, 0x1e, 0x17, 0x45, 0xbe, 0xf5, 0xbf, 0x09, 0x58, 0xd9, 0xd1,
+	0x27, 0x7b, 0x44, 0x86, 0x0d, 0x62, 0x62, 0x62, 0x50, 0xd7, 0x44, 0xdd, 0x68, 0xb8, 0xb9, 0xe2,
+	0xad, 0x32, 0x4e, 0x38, 0x3e, 0xea, 0x04, 0x05, 0x58, 0x32, 0x52, 0x80, 0xad, 0x40, 0xc6, 0xa1,
+	0x8e, 0x41, 0x64, 0x2c, 0x12, 0x0d, 0xd5, 0x8a, 0x86, 0x9a, 0x52, 0xf8, 0x8c, 0xc8, 0x1f, 0x01,
+	0xdb, 0xd4, 0x0f, 0x7b, 0x43, 0x9f, 0x40, 0xa9, 0xd7, 0xac, 0xe3, 0x66, 0xbf, 0xd6, 0xf9, 0xae,
+	0xd6, 0xab, 0x6e, 0xf7, 0xaa, 0x8f, 0x1f, 0x6a, 0xdd, 0xce, 0xf6, 0xf7, 0x1e, 0x3d, 0x79, 0xf8,
+	0x0d, 0x25, 0x51, 0x2a, 0x9f, 0x9c, 0x96, 0x6f, 0xb7, 0xab, 0xf5, 0x6d, 0xb1, 0x63, 0xf6, 0xe8,
+	0xcb, 0x9e, 0x6e, 0x7b, 0xfa, 0xe3, 0x87, 0x5d, 0x6a, 0x4f, 0x18, 0x86, 0x2d, 0xeb, 0x62, 0xf4,
+	0xbc, 0x8a, 0x1e, 0xc3, 0x89, 0x4b, 0x8f, 0xe1, 0xe9, 0x69, 0x9e, 0xbc, 0xe4, 0x34, 0xdf, 0x80,
+	0x15, 0xc3, 0xa5, 0x9e, 0xa7, 0xb1, 0xec, 0x9f, 0x98, 0x33, 0xf5, 0xc5, 0x97, 0xce, 0xcf, 0xd6,
+	0x97, 0xeb, 0x8c, 0xdf, 0xe3, 0x6c, 0xa9, 0x7e, 0xd9, 0x88, 0x90, 0x78, 0x4f, 0xea, 0x1f, 0xa5,
+	0x58, 0x22, 0x65, 0x1d, 0x59, 0x36, 0x19, 0x10, 0x0f, 0x3d, 0x87, 0x25, 0xc3, 0x25, 0x26, 0x4b,
+	0xeb, 0x75, 0x3b, 0xfa, 0x11, 0xed, 0x2f, 0xc4, 0xe6, 0x34, 0xa1, 0x60, 0xa5, 0x1e, 0x4a, 0xf5,
+	0x46, 0xc4, 0xc0, 0x8b, 0xc6, 0x85, 0x36, 0xfa, 0x14, 0x96, 0x3c, 0x62, 0x5b, 0xce, 0xf8, 0xa5,
+	0x66, 0x50, 0xc7, 0x27, 0x2f, 0x83, 0x17, 0xb1, 0xeb, 0xf4, 0xf6, 0x9a, 0xdb, 0x4c, 0xaa, 0x2e,
+	0x84, 0x6a, 0xe8, 0xfc, 0x6c, 0x7d, 0xf1, 0x22, 0x0d, 0x2f, 0x4a, 0xcd, 0xb2, 0x5d, 0x6a, 0xc3,
+	0xe2, 0x45, 0x6b, 0xd0, 0x8a, 0xdc, 0xfb, 0x3c, 0x84, 0x04, 0x7b, 0x1b, 0xdd, 0x86, 0x9c, 0x4b,
+	0x06, 0x96, 0xe7, 0xbb, 0xc2, 0xcd, 0x8c, 0x13, 0x52, 0xd8, 0xce, 0x17, 0x5f, 0x40, 0x95, 0x7e,
+	0x1d, 0x66, 0x7a, 0x64, 0x9b, 0xc5, 0xb4, 0x3c, 0x7d, 0x4f, 0xaa, 0xcc, 0xe1, 0xa0, 0xc9, 0xd6,
+	0xe0, 0xd8, 0x0b, 0x13, 0x35, 0xfe, 0x9b, 0xd1, 0x78, 0x46, 0x21, 0xbf, 0x07, 0xe3, 0x39, 0x43,
+	0xf0, 0x61, 0x69, 0x3a, 0xf2, 0x61, 0xe9, 0x0a, 0x64, 0x6c, 0x72, 0x44, 0x6c, 0x71, 0x96, 0x63,
+	0xd1, 0xb8, 0xf7, 0x10, 0x8a, 0xc1, 0x17, 0x8c, 0xfc, 0xcb, 0x89, 0x1c, 0xa4, 0xfb, 0xd5, 0xde,
+	0x33, 0x65, 0x0e, 0x01, 0x64, 0xc5, 0xe2, 0x14, 0xaf, 0x75, 0xf5, 0x4e, 0x7b, 0xa3, 0xb5, 0xa9,
+	0x24, 0xef, 0xfd, 0x2c, 0x05, 0xf9, 0xf0, 0xbd, 0x88, 0x9d, 0x1d, 0xed, 0xe6, 0x8b, 0x60, 0x75,
+	0x87, 0xf4, 0x36, 0x39, 0x46, 0x6f, 0x4f, 0x6f, 0xa1, 0x3e, 0x11, 0x0f, 0xe4, 0x21, 0x3b, 0xb8,
+	0x81, 0x7a, 0x17, 0x72, 0xd5, 0x5e, 0xaf, 0xb5, 0xd9, 0x6e, 0x36, 0x94, 0xcf, 0x12, 0xa5, 0x2f,
+	0x9d, 0x9c, 0x96, 0x97, 0x43, 0x50, 0xd5, 0x13, 0x8b, 0x8f, 0xa3, 0xea, 0xf5, 0x66, 0xb7, 0xdf,
+	0x6c, 0x28, 0xaf, 0x92, 0xb3, 0x28, 0x7e, 0xab, 0xc2, 0x3f, 0xdd, 0xc9, 0x77, 0x71, 0xb3, 0x5b,
+	0xc5, 0xac, 0xc3, 0xcf, 0x92, 0xe2, 0x72, 0x6c, 0xda, 0xa3, 0x4b, 0x46, 0xba, 0xcb, 0xfa, 0x5c,
+	0x0b, 0xbe, 0x85, 0x7b, 0x95, 0x12, 0x9f, 0x77, 0x4c, 0x1f, 0xbf, 0x88, 0x6e, 0x4e, 0x58, 0x6f,
+	0xfc, 0xd5, 0x91, 0xab, 0x49, 0xcd, 0xf4, 0xd6, 0x63, 0xb1, 0x87, 0x69, 0x51, 0x61, 0x1e, 0xef,
+	0xb6, 0xdb, 0x0c, 0xf4, 0x2a, 0x3d, 0x33, 0x3a, 0x3c, 0x76, 0x58, 0xc5, 0x8c, 0xee, 0x42, 0x2e,
+	0x78, 0x94, 0x54, 0x3e, 0x4b, 0xcf, 0x18, 0x54, 0x0f, 0x5e, 0x54, 0x79, 0x87, 0x5b, 0xbb, 0x7d,
+	0xfe, 0xa9, 0xde, 0xab, 0xcc, 0x6c, 0x87, 0x07, 0x63, 0xdf, 0xa4, 0xc7, 0x0e, 0xdb, 0xb3, 0xf2,
+	0x1e, 0xee, 0xb3, 0x8c, 0xb8, 0xb4, 0x08, 0x31, 0xf2, 0x12, 0xee, 0x5d, 0xc8, 0xe1, 0xe6, 0x77,
+	0xc4, 0x57, 0x7d, 0xaf, 0xb2, 0x33, 0x7a, 0x30, 0xf9, 0x94, 0x18, 0xb2, 0xb7, 0x0e, 0xee, 0x6e,
+	0x55, 0xb9, 0xcb, 0x67, 0x51, 0x1d, 0x77, 0x74, 0xa0, 0x3b, 0xc4, 0x9c, 0x7e, 0xe3, 0x12, 0xb2,
+	0xee, 0xfd, 0x0a, 0xe4, 0x82, 0xcc, 0x14, 0xad, 0x41, 0xf6, 0x45, 0x07, 0x3f, 0x6b, 0x62, 0x65,
+	0x4e, 0xf8, 0x30, 0xe0, 0xbc, 0x10, 0x35, 0x45, 0x19, 0xe6, 0x77, 0xaa, 0xed, 0xea, 0x66, 0x13,
+	0x07, 0x57, 0xe4, 0x01, 0x40, 0xa6, 0x57, 0x25, 0x45, 0x76, 0x10, 0xea, 0xac, 0xad, 0xfe, 0xf0,
+	0x27, 0x6b, 0x73, 0x3f, 0xfe, 0xc9, 0xda, 0xdc, 0xab, 0xf3, 0xb5, 0xc4, 0x0f, 0xcf, 0xd7, 0x12,
+	0xff, 0x70, 0xbe, 0x96, 0xf8, 0xf7, 0xf3, 0xb5, 0xc4, 0x5e, 0x96, 0x1f, 0x02, 0x4f, 0xfe, 0x2f,
+	0x00, 0x00, 0xff, 0xff, 0x4b, 0xdb, 0xdc, 0xec, 0xf0, 0x31, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/types.proto b/vendor/github.com/docker/swarmkit/api/types.proto
index a9fb07a..890b3cf 100644
--- a/vendor/github.com/docker/swarmkit/api/types.proto
+++ b/vendor/github.com/docker/swarmkit/api/types.proto
@@ -57,6 +57,12 @@
 	}
 }
 
+enum ResourceType {
+	TASK = 0;
+	SECRET = 1;
+	CONFIG = 2;
+}
+
 message Resources {
 	// Amount of CPUs (e.g. 2000000000 = 2 CPU cores)
 	int64 nano_cpus = 1 [(gogoproto.customname) = "NanoCPUs"];
@@ -208,6 +214,18 @@
 	// ReadOnly should be set to true if the mount should not be writable.
 	bool readonly = 4 [(gogoproto.customname) = "ReadOnly"];
 
+	// Consistency indicates the tolerable level of file system consistency
+	enum Consistency {
+		option (gogoproto.goproto_enum_prefix) = false;
+		option (gogoproto.enum_customname) = "MountConsistency";
+
+		DEFAULT = 0 [(gogoproto.enumvalue_customname) = "MountConsistencyDefault"];
+		CONSISTENT = 1 [(gogoproto.enumvalue_customname) = "MountConsistencyFull"];
+		CACHED = 2 [(gogoproto.enumvalue_customname) = "MountConsistencyCached"];
+		DELEGATED = 3 [(gogoproto.enumvalue_customname) = "MountConsistencyDelegated"];
+	}
+	Consistency consistency = 8;
+
 	// BindOptions specifies options that are specific to a bind mount.
 	message BindOptions {
 		enum Propagation {
@@ -508,6 +526,15 @@
 	// HostPorts provides a list of ports allocated at the host
 	// level.
 	PortStatus port_status = 6;
+
+	// AppliedBy gives the node ID of the manager that applied this task
+	// status update to the Task object.
+	string applied_by = 7;
+
+	// AppliedAt gives a timestamp of when this status update was applied to
+	// the Task object.
+	// Note: can't use stdtime because this field is nullable.
+	google.protobuf.Timestamp applied_at = 8;
 }
 
 // NetworkAttachmentConfig specifies how a service should be attached to a particular network.
diff --git a/vendor/github.com/docker/swarmkit/api/watch.pb.go b/vendor/github.com/docker/swarmkit/api/watch.pb.go
index db7e80f..58fa891 100644
--- a/vendor/github.com/docker/swarmkit/api/watch.pb.go
+++ b/vendor/github.com/docker/swarmkit/api/watch.pb.go
@@ -1,5 +1,5 @@
 // Code generated by protoc-gen-gogo.
-// source: watch.proto
+// source: github.com/docker/swarmkit/api/watch.proto
 // DO NOT EDIT!
 
 package api
@@ -1442,7 +1442,7 @@
 			ServerStreams: true,
 		},
 	},
-	Metadata: "watch.proto",
+	Metadata: "github.com/docker/swarmkit/api/watch.proto",
 }
 
 func (m *Object) Marshal() (dAtA []byte, err error) {
@@ -4519,81 +4519,83 @@
 	ErrIntOverflowWatch   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("watch.proto", fileDescriptorWatch) }
+func init() { proto.RegisterFile("github.com/docker/swarmkit/api/watch.proto", fileDescriptorWatch) }
 
 var fileDescriptorWatch = []byte{
-	// 1155 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x96, 0xbb, 0x73, 0x1b, 0xd5,
-	0x17, 0xc7, 0xb5, 0x8a, 0xbc, 0x92, 0x8e, 0xac, 0xc4, 0x73, 0xed, 0x24, 0xfb, 0xd3, 0x2f, 0x48,
-	0x42, 0x0c, 0xe0, 0x21, 0x41, 0x01, 0x13, 0xc2, 0x00, 0x81, 0x19, 0x4b, 0x16, 0x23, 0x91, 0xb1,
-	0xec, 0xb9, 0xb6, 0xe3, 0x52, 0xb3, 0xde, 0x3d, 0x56, 0x16, 0xed, 0x43, 0xdc, 0x5d, 0xc9, 0x71,
-	0x47, 0x41, 0xc1, 0xa4, 0x67, 0x86, 0x26, 0x15, 0xd4, 0x34, 0x74, 0xf0, 0x0f, 0x64, 0xa8, 0x28,
-	0xa1, 0xd1, 0x10, 0x95, 0x14, 0xfc, 0x05, 0x14, 0xcc, 0x7d, 0xac, 0x1f, 0xca, 0xca, 0x21, 0x95,
-	0xee, 0xbd, 0xfb, 0xf9, 0x9e, 0x7b, 0xf6, 0xbc, 0x56, 0x50, 0x38, 0x32, 0x23, 0xeb, 0x61, 0x7d,
-	0xc8, 0x82, 0x28, 0x20, 0xc4, 0x0e, 0xac, 0x01, 0xb2, 0x7a, 0x78, 0x64, 0x32, 0x6f, 0xe0, 0x44,
-	0xf5, 0xf1, 0xbb, 0xa5, 0x42, 0x38, 0x44, 0x2b, 0x94, 0x40, 0xa9, 0x18, 0x1c, 0x7c, 0x81, 0x56,
-	0x14, 0x6f, 0x0b, 0xd1, 0xf1, 0x10, 0xe3, 0xcd, 0x4a, 0x3f, 0xe8, 0x07, 0x62, 0x79, 0x9b, 0xaf,
-	0xd4, 0xe9, 0xf2, 0xd0, 0x1d, 0xf5, 0x1d, 0xff, 0xb6, 0xfc, 0x91, 0x87, 0xb5, 0xaf, 0x33, 0xa0,
-	0x6f, 0x09, 0x4b, 0xa4, 0x0e, 0x19, 0x3f, 0xb0, 0xd1, 0xd0, 0xaa, 0xda, 0x6a, 0x61, 0xcd, 0xa8,
-	0x3f, 0xef, 0x41, 0xbd, 0x1b, 0xd8, 0xd8, 0x4e, 0x51, 0xc1, 0x91, 0x0f, 0x20, 0x1b, 0x22, 0x1b,
-	0x3b, 0x16, 0x1a, 0x69, 0x21, 0xf9, 0x7f, 0x92, 0x64, 0x47, 0x22, 0xed, 0x14, 0x8d, 0x69, 0x2e,
-	0xf4, 0x31, 0x3a, 0x0a, 0xd8, 0xc0, 0xb8, 0x34, 0x5f, 0xd8, 0x95, 0x08, 0x17, 0x2a, 0x9a, 0x7b,
-	0x18, 0x99, 0xe1, 0xc0, 0xc8, 0xcc, 0xf7, 0x70, 0xd7, 0x0c, 0xb9, 0x44, 0x70, 0xfc, 0x22, 0xcb,
-	0x1d, 0x85, 0x11, 0x32, 0x63, 0x61, 0xfe, 0x45, 0x4d, 0x89, 0xf0, 0x8b, 0x14, 0x4d, 0xee, 0x80,
-	0x1e, 0xa2, 0xc5, 0x30, 0x32, 0x74, 0xa1, 0x2b, 0x25, 0xbf, 0x19, 0x27, 0xda, 0x29, 0xaa, 0x58,
-	0xf2, 0x11, 0xe4, 0x18, 0x86, 0xc1, 0x88, 0x59, 0x68, 0x64, 0x85, 0xee, 0x46, 0x92, 0x8e, 0x2a,
-	0xa6, 0x9d, 0xa2, 0x27, 0x3c, 0xf9, 0x04, 0xf2, 0xf8, 0x28, 0x42, 0x3f, 0x74, 0x02, 0xdf, 0xc8,
-	0x09, 0xf1, 0x2b, 0x49, 0xe2, 0x56, 0x0c, 0xb5, 0x53, 0xf4, 0x54, 0xc1, 0x1d, 0xb6, 0x02, 0xff,
-	0xd0, 0xe9, 0x1b, 0xf9, 0xf9, 0x0e, 0x37, 0x05, 0xc1, 0x1d, 0x96, 0x6c, 0x23, 0x17, 0xe7, 0xbe,
-	0xb6, 0x0d, 0x8b, 0x3b, 0xe8, 0xa2, 0x15, 0x35, 0x8e, 0x77, 0xdc, 0x20, 0x22, 0xb7, 0x00, 0x54,
-	0xb6, 0x7a, 0x8e, 0x2d, 0x2a, 0x22, 0xdf, 0x28, 0x4e, 0x27, 0x95, 0xbc, 0x4a, 0x67, 0x67, 0x83,
-	0xe6, 0x15, 0xd0, 0xb1, 0x09, 0x81, 0x4c, 0xe8, 0x06, 0x91, 0x28, 0x83, 0x0c, 0x15, 0xeb, 0xda,
-	0x36, 0x5c, 0x8e, 0x2d, 0x36, 0x47, 0x61, 0x14, 0x78, 0x9c, 0x1a, 0x38, 0xbe, 0xb2, 0x46, 0xc5,
-	0x9a, 0xac, 0xc0, 0x82, 0xe3, 0xdb, 0xf8, 0x48, 0x48, 0xf3, 0x54, 0x6e, 0xf8, 0xe9, 0xd8, 0x74,
-	0x47, 0x28, 0xca, 0x23, 0x4f, 0xe5, 0xa6, 0xf6, 0x97, 0x0e, 0xb9, 0xd8, 0x24, 0x31, 0x20, 0x7d,
-	0xe2, 0x98, 0x3e, 0x9d, 0x54, 0xd2, 0x9d, 0x8d, 0x76, 0x8a, 0xa6, 0x1d, 0x9b, 0xdc, 0x84, 0xbc,
-	0x63, 0xf7, 0x86, 0x0c, 0x0f, 0x1d, 0x65, 0xb6, 0xb1, 0x38, 0x9d, 0x54, 0x72, 0x9d, 0x8d, 0x6d,
-	0x71, 0xc6, 0xc3, 0xee, 0xd8, 0x72, 0x4d, 0x56, 0x20, 0xe3, 0x9b, 0x9e, 0xba, 0x48, 0x54, 0xb6,
-	0xe9, 0x21, 0x79, 0x15, 0x0a, 0xfc, 0x37, 0x36, 0x92, 0x51, 0x0f, 0x81, 0x1f, 0x2a, 0xe1, 0x3d,
-	0xd0, 0x2d, 0xf1, 0x5a, 0xaa, 0xb2, 0x6a, 0xc9, 0x15, 0x72, 0x36, 0x00, 0x22, 0xf0, 0x32, 0x14,
-	0x1d, 0x28, 0xca, 0x55, 0x7c, 0x85, 0xfe, 0x12, 0x46, 0x16, 0xa5, 0x54, 0x39, 0x52, 0x3f, 0x97,
-	0xa9, 0x6c, 0x42, 0xa6, 0x78, 0xa5, 0x9c, 0xe6, 0xea, 0x75, 0xc8, 0xf2, 0xee, 0xe5, 0x70, 0x4e,
-	0xc0, 0x30, 0x9d, 0x54, 0x74, 0xde, 0xd8, 0x82, 0xd4, 0xf9, 0xc3, 0x8e, 0x4d, 0xee, 0xaa, 0x94,
-	0xca, 0x72, 0xaa, 0x5e, 0xe4, 0x18, 0x2f, 0x18, 0x1e, 0x3a, 0xce, 0x93, 0x0d, 0x28, 0xda, 0x18,
-	0x3a, 0x0c, 0xed, 0x5e, 0x18, 0x99, 0x11, 0x1a, 0x50, 0xd5, 0x56, 0x2f, 0x27, 0xd7, 0x32, 0xef,
-	0xd5, 0x1d, 0x0e, 0xf1, 0x97, 0x52, 0x2a, 0xb1, 0x27, 0x6b, 0x90, 0x61, 0x81, 0x8b, 0x46, 0x41,
-	0x88, 0x6f, 0xcc, 0x1b, 0x45, 0x34, 0x70, 0xc5, 0x38, 0xe2, 0x2c, 0xe9, 0x00, 0x78, 0xe8, 0x1d,
-	0x20, 0x0b, 0x1f, 0x3a, 0x43, 0x63, 0x51, 0x28, 0xdf, 0x9c, 0xa7, 0xdc, 0x19, 0xa2, 0x55, 0xdf,
-	0x3c, 0xc1, 0x79, 0x72, 0x4f, 0xc5, 0x64, 0x13, 0xae, 0x32, 0x3c, 0x44, 0x86, 0xbe, 0x85, 0x76,
-	0x4f, 0x4d, 0x1f, 0x1e, 0xb1, 0xa2, 0x88, 0xd8, 0xf5, 0xe9, 0xa4, 0xb2, 0x4c, 0x4f, 0x00, 0x35,
-	0xa8, 0x44, 0xf8, 0x96, 0xd9, 0x73, 0xc7, 0x36, 0xf9, 0x1c, 0x56, 0xce, 0x98, 0x93, 0xc3, 0x82,
-	0x5b, 0xbb, 0x2c, 0xac, 0x5d, 0x9b, 0x4e, 0x2a, 0xe4, 0xd4, 0x9a, 0x9c, 0x2a, 0xc2, 0x18, 0x61,
-	0xb3, 0xa7, 0xbc, 0x61, 0x64, 0x13, 0x5d, 0x89, 0x0b, 0x56, 0xb4, 0xd1, 0xf9, 0x1b, 0x64, 0x77,
-	0xf3, 0x1b, 0x96, 0x92, 0x6e, 0x90, 0x63, 0x60, 0xf6, 0x06, 0x75, 0x6a, 0x37, 0x32, 0x90, 0x6e,
-	0x1c, 0xd7, 0xfe, 0x48, 0xc3, 0xe2, 0x3e, 0xff, 0x1e, 0x51, 0xfc, 0x72, 0x84, 0x61, 0x44, 0x5a,
-	0x90, 0x45, 0x3f, 0x62, 0x0e, 0x86, 0x86, 0x56, 0xbd, 0xb4, 0x5a, 0x58, 0xbb, 0x99, 0x14, 0xdb,
-	0xb3, 0x12, 0xb9, 0x69, 0xf9, 0x11, 0x3b, 0xa6, 0xb1, 0x96, 0xdc, 0x83, 0x02, 0xc3, 0x70, 0xe4,
-	0x61, 0xef, 0x90, 0x05, 0xde, 0x45, 0x1f, 0x8e, 0x07, 0xc8, 0xf8, 0x68, 0xa3, 0x20, 0xf9, 0xcf,
-	0x58, 0xe0, 0x91, 0x5b, 0x40, 0x1c, 0xdf, 0x72, 0x47, 0x36, 0xf6, 0x02, 0xd7, 0xee, 0xc9, 0x4f,
-	0xa0, 0x68, 0xde, 0x1c, 0x5d, 0x52, 0x4f, 0xb6, 0x5c, 0x5b, 0x0e, 0xb5, 0xd2, 0xb7, 0x1a, 0xc0,
-	0xa9, 0x0f, 0x89, 0xf3, 0xe7, 0x63, 0xd0, 0x4d, 0x2b, 0xe2, 0x33, 0x37, 0x2d, 0x0a, 0xe6, 0xb5,
-	0xb9, 0x2f, 0xb5, 0x2e, 0xb0, 0xfb, 0x8e, 0x6f, 0x53, 0x25, 0x21, 0x77, 0x21, 0x7b, 0xe8, 0xb8,
-	0x11, 0xb2, 0xd0, 0xb8, 0x24, 0x42, 0x72, 0xe3, 0xa2, 0x36, 0xa1, 0x31, 0x5c, 0xfb, 0x25, 0x8e,
-	0xed, 0x26, 0x86, 0xa1, 0xd9, 0x47, 0xf2, 0x29, 0xe8, 0x38, 0x46, 0x3f, 0x8a, 0x43, 0xfb, 0xc6,
-	0x5c, 0x2f, 0x94, 0xa2, 0xde, 0xe2, 0x38, 0x55, 0x2a, 0xf2, 0x3e, 0x64, 0xc7, 0x32, 0x5a, 0xff,
-	0x25, 0xa0, 0x31, 0x5b, 0xfa, 0x49, 0x83, 0x05, 0x61, 0xe8, 0x4c, 0x18, 0xb4, 0x97, 0x0f, 0xc3,
-	0x1a, 0xe8, 0x2a, 0x11, 0xe9, 0xf9, 0xdf, 0x1e, 0x99, 0x12, 0xaa, 0x48, 0xf2, 0x21, 0xc0, 0x4c,
-	0x02, 0x2f, 0xd6, 0xe5, 0x83, 0x38, 0xab, 0x6f, 0xfd, 0xa3, 0xc1, 0x95, 0x19, 0x57, 0xc8, 0x1d,
-	0x58, 0xd9, 0x5f, 0xdf, 0x6d, 0xb6, 0x7b, 0xeb, 0xcd, 0xdd, 0xce, 0x56, 0xb7, 0xb7, 0xd7, 0xbd,
-	0xdf, 0xdd, 0xda, 0xef, 0x2e, 0xa5, 0x4a, 0xa5, 0xc7, 0x4f, 0xaa, 0xd7, 0x66, 0xf0, 0x3d, 0x7f,
-	0xe0, 0x07, 0x47, 0xdc, 0xf1, 0xe5, 0x73, 0xaa, 0x26, 0x6d, 0xad, 0xef, 0xb6, 0x96, 0xb4, 0xd2,
-	0xff, 0x1e, 0x3f, 0xa9, 0x5e, 0x9d, 0x11, 0x35, 0x19, 0xca, 0xc9, 0x74, 0x5e, 0xb3, 0xb7, 0xbd,
-	0xc1, 0x35, 0xe9, 0x44, 0xcd, 0xde, 0xd0, 0x4e, 0xd2, 0xd0, 0xd6, 0xe6, 0xd6, 0x83, 0xd6, 0x52,
-	0x26, 0x51, 0x43, 0xd1, 0x0b, 0xc6, 0x58, 0xba, 0xfe, 0xcd, 0xf7, 0xe5, 0xd4, 0xcf, 0x3f, 0x94,
-	0x67, 0x5f, 0x75, 0xcd, 0x83, 0x05, 0x71, 0x44, 0xec, 0x78, 0x51, 0x7d, 0x51, 0x23, 0x96, 0xaa,
-	0x2f, 0xaa, 0xa7, 0xda, 0xd5, 0x5f, 0x7f, 0xfc, 0xfb, 0xbb, 0xf4, 0x15, 0x28, 0x0a, 0xe2, 0x6d,
-	0xcf, 0xf4, 0xcd, 0x3e, 0xb2, 0x77, 0xb4, 0x86, 0xf1, 0xf4, 0x59, 0x39, 0xf5, 0xfb, 0xb3, 0x72,
-	0xea, 0xab, 0x69, 0x59, 0x7b, 0x3a, 0x2d, 0x6b, 0xbf, 0x4d, 0xcb, 0xda, 0x9f, 0xd3, 0xb2, 0x76,
-	0xa0, 0x8b, 0x3f, 0x90, 0xef, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x53, 0xd9, 0x73, 0xb7,
-	0x0a, 0x00, 0x00,
+	// 1186 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x96, 0xbd, 0x73, 0x1b, 0xc5,
+	0x1b, 0xc7, 0x75, 0x8a, 0x7c, 0x92, 0x1e, 0xdb, 0x89, 0x67, 0xe3, 0x24, 0xf7, 0xd3, 0x2f, 0xc8,
+	0x42, 0x0c, 0x90, 0x49, 0x82, 0x0c, 0x26, 0x24, 0x03, 0x04, 0x66, 0x2c, 0x59, 0x8c, 0x44, 0xc6,
+	0x2f, 0xb3, 0xb6, 0x93, 0x52, 0x73, 0xbe, 0x7b, 0xac, 0x1c, 0xba, 0xbb, 0x15, 0x7b, 0x27, 0x39,
+	0xee, 0x28, 0x28, 0x98, 0xf4, 0xcc, 0xd0, 0xa4, 0x82, 0x9a, 0x86, 0x0e, 0xfe, 0x81, 0x0c, 0x15,
+	0x25, 0x34, 0x1a, 0xa2, 0x92, 0x82, 0xbf, 0x80, 0x82, 0xd9, 0x97, 0xf3, 0x8b, 0x72, 0xb2, 0x49,
+	0xa5, 0xbd, 0xbd, 0xcf, 0xf7, 0xd9, 0x67, 0x9f, 0xb7, 0x13, 0xdc, 0xec, 0x7a, 0xf1, 0xe3, 0xc1,
+	0x5e, 0xcd, 0x61, 0xc1, 0xb2, 0xcb, 0x9c, 0x1e, 0xf2, 0xe5, 0xe8, 0xc0, 0xe6, 0x41, 0xcf, 0x8b,
+	0x97, 0xed, 0xbe, 0xb7, 0x7c, 0x60, 0xc7, 0xce, 0xe3, 0x5a, 0x9f, 0xb3, 0x98, 0x11, 0xa2, 0x80,
+	0x5a, 0x02, 0xd4, 0x86, 0xef, 0x95, 0xce, 0xd3, 0x47, 0x7d, 0x74, 0x22, 0xa5, 0x2f, 0xdd, 0x3e,
+	0x87, 0x65, 0x7b, 0x5f, 0xa0, 0x13, 0x27, 0xf4, 0x79, 0x96, 0xe3, 0xc3, 0x3e, 0x26, 0xec, 0x62,
+	0x97, 0x75, 0x99, 0x5c, 0x2e, 0x8b, 0x95, 0xde, 0xbd, 0x77, 0x86, 0x05, 0x49, 0xec, 0x0d, 0xf6,
+	0x97, 0xfb, 0xfe, 0xa0, 0xeb, 0x85, 0xfa, 0x47, 0x09, 0xab, 0x5f, 0xe7, 0xc0, 0xdc, 0x94, 0xce,
+	0x90, 0x1a, 0xe4, 0x42, 0xe6, 0xa2, 0x65, 0x54, 0x8c, 0x1b, 0xb3, 0x2b, 0x56, 0xed, 0xe5, 0x10,
+	0xd4, 0x36, 0x98, 0x8b, 0xad, 0x0c, 0x95, 0x1c, 0xb9, 0x07, 0xf9, 0x08, 0xf9, 0xd0, 0x73, 0xd0,
+	0xca, 0x4a, 0xc9, 0xff, 0xd3, 0x24, 0xdb, 0x0a, 0x69, 0x65, 0x68, 0x42, 0x0b, 0x61, 0x88, 0xf1,
+	0x01, 0xe3, 0x3d, 0xeb, 0xc2, 0x74, 0xe1, 0x86, 0x42, 0x84, 0x50, 0xd3, 0xc2, 0xc3, 0xd8, 0x8e,
+	0x7a, 0x56, 0x6e, 0xba, 0x87, 0x3b, 0x76, 0x24, 0x24, 0x92, 0x13, 0x07, 0x39, 0xfe, 0x20, 0x8a,
+	0x91, 0x5b, 0x33, 0xd3, 0x0f, 0x6a, 0x28, 0x44, 0x1c, 0xa4, 0x69, 0x72, 0x07, 0xcc, 0x08, 0x1d,
+	0x8e, 0xb1, 0x65, 0x4a, 0x5d, 0x29, 0xfd, 0x66, 0x82, 0x68, 0x65, 0xa8, 0x66, 0xc9, 0x47, 0x50,
+	0xe0, 0x18, 0xb1, 0x01, 0x77, 0xd0, 0xca, 0x4b, 0xdd, 0xf5, 0x34, 0x1d, 0xd5, 0x4c, 0x2b, 0x43,
+	0x8f, 0x78, 0xf2, 0x09, 0x14, 0xf1, 0x49, 0x8c, 0x61, 0xe4, 0xb1, 0xd0, 0x2a, 0x48, 0xf1, 0x6b,
+	0x69, 0xe2, 0x66, 0x02, 0xb5, 0x32, 0xf4, 0x58, 0x21, 0x1c, 0x76, 0x58, 0xb8, 0xef, 0x75, 0xad,
+	0xe2, 0x74, 0x87, 0x1b, 0x92, 0x10, 0x0e, 0x2b, 0xb6, 0x5e, 0x48, 0x72, 0x5f, 0xdd, 0x82, 0xb9,
+	0x6d, 0xf4, 0xd1, 0x89, 0xeb, 0x87, 0xdb, 0x3e, 0x8b, 0xc9, 0x6d, 0x00, 0x9d, 0xad, 0x8e, 0xe7,
+	0xca, 0x8a, 0x28, 0xd6, 0xe7, 0xc7, 0xa3, 0xa5, 0xa2, 0x4e, 0x67, 0x7b, 0x8d, 0x16, 0x35, 0xd0,
+	0x76, 0x09, 0x81, 0x5c, 0xe4, 0xb3, 0x58, 0x96, 0x41, 0x8e, 0xca, 0x75, 0x75, 0x0b, 0x2e, 0x26,
+	0x16, 0x1b, 0x83, 0x28, 0x66, 0x81, 0xa0, 0x7a, 0x5e, 0xa8, 0xad, 0x51, 0xb9, 0x26, 0x8b, 0x30,
+	0xe3, 0x85, 0x2e, 0x3e, 0x91, 0xd2, 0x22, 0x55, 0x0f, 0x62, 0x77, 0x68, 0xfb, 0x03, 0x94, 0xe5,
+	0x51, 0xa4, 0xea, 0xa1, 0xfa, 0x97, 0x09, 0x85, 0xc4, 0x24, 0xb1, 0x20, 0x7b, 0xe4, 0x98, 0x39,
+	0x1e, 0x2d, 0x65, 0xdb, 0x6b, 0xad, 0x0c, 0xcd, 0x7a, 0x2e, 0xb9, 0x05, 0x45, 0xcf, 0xed, 0xf4,
+	0x39, 0xee, 0x7b, 0xda, 0x6c, 0x7d, 0x6e, 0x3c, 0x5a, 0x2a, 0xb4, 0xd7, 0xb6, 0xe4, 0x9e, 0x08,
+	0xbb, 0xe7, 0xaa, 0x35, 0x59, 0x84, 0x5c, 0x68, 0x07, 0xfa, 0x20, 0x59, 0xd9, 0x76, 0x80, 0xe4,
+	0x75, 0x98, 0x15, 0xbf, 0x89, 0x91, 0x9c, 0x7e, 0x09, 0x62, 0x53, 0x0b, 0xef, 0x83, 0xe9, 0xc8,
+	0x6b, 0xe9, 0xca, 0xaa, 0xa6, 0x57, 0xc8, 0xc9, 0x00, 0xc8, 0xc0, 0xab, 0x50, 0xb4, 0x61, 0x5e,
+	0xad, 0x92, 0x23, 0xcc, 0x57, 0x30, 0x32, 0xa7, 0xa4, 0xda, 0x91, 0xda, 0xa9, 0x4c, 0xe5, 0x53,
+	0x32, 0x25, 0x2a, 0xe5, 0x38, 0x57, 0x6f, 0x42, 0x5e, 0x74, 0xaf, 0x80, 0x0b, 0x12, 0x86, 0xf1,
+	0x68, 0xc9, 0x14, 0x8d, 0x2d, 0x49, 0x53, 0xbc, 0x6c, 0xbb, 0xe4, 0xae, 0x4e, 0xa9, 0x2a, 0xa7,
+	0xca, 0x59, 0x8e, 0x89, 0x82, 0x11, 0xa1, 0x13, 0x3c, 0x59, 0x83, 0x79, 0x17, 0x23, 0x8f, 0xa3,
+	0xdb, 0x89, 0x62, 0x3b, 0x46, 0x0b, 0x2a, 0xc6, 0x8d, 0x8b, 0xe9, 0xb5, 0x2c, 0x7a, 0x75, 0x5b,
+	0x40, 0xe2, 0x52, 0x5a, 0x25, 0x9f, 0xc9, 0x0a, 0xe4, 0x38, 0xf3, 0xd1, 0x9a, 0x95, 0xe2, 0xeb,
+	0xd3, 0x46, 0x11, 0x65, 0xbe, 0x1c, 0x47, 0x82, 0x25, 0x6d, 0x80, 0x00, 0x83, 0x3d, 0xe4, 0xd1,
+	0x63, 0xaf, 0x6f, 0xcd, 0x49, 0xe5, 0xdb, 0xd3, 0x94, 0xdb, 0x7d, 0x74, 0x6a, 0xeb, 0x47, 0xb8,
+	0x48, 0xee, 0xb1, 0x98, 0xac, 0xc3, 0x15, 0x8e, 0xfb, 0xc8, 0x31, 0x74, 0xd0, 0xed, 0xe8, 0xe9,
+	0x23, 0x22, 0x36, 0x2f, 0x23, 0x76, 0x6d, 0x3c, 0x5a, 0xba, 0x4c, 0x8f, 0x00, 0x3d, 0xa8, 0x64,
+	0xf8, 0x2e, 0xf3, 0x97, 0xb6, 0x5d, 0xf2, 0x39, 0x2c, 0x9e, 0x30, 0xa7, 0x86, 0x85, 0xb0, 0x76,
+	0x51, 0x5a, 0xbb, 0x3a, 0x1e, 0x2d, 0x91, 0x63, 0x6b, 0x6a, 0xaa, 0x48, 0x63, 0x84, 0x4f, 0xee,
+	0x8a, 0x86, 0x51, 0x4d, 0x74, 0x29, 0x29, 0x58, 0xd9, 0x46, 0xa7, 0x4f, 0x50, 0xdd, 0x2d, 0x4e,
+	0x58, 0x48, 0x3b, 0x41, 0x8d, 0x81, 0xc9, 0x13, 0xf4, 0xae, 0x5b, 0xcf, 0x41, 0xb6, 0x7e, 0x58,
+	0xfd, 0x23, 0x0b, 0x73, 0x8f, 0xc4, 0x07, 0x91, 0xe2, 0x97, 0x03, 0x8c, 0x62, 0xd2, 0x84, 0x3c,
+	0x86, 0x31, 0xf7, 0x30, 0xb2, 0x8c, 0xca, 0x85, 0x1b, 0xb3, 0x2b, 0xb7, 0xd2, 0x62, 0x7b, 0x52,
+	0xa2, 0x1e, 0x9a, 0x61, 0xcc, 0x0f, 0x69, 0xa2, 0x25, 0xf7, 0x61, 0x96, 0x63, 0x34, 0x08, 0xb0,
+	0xb3, 0xcf, 0x59, 0x70, 0xd6, 0x87, 0xe3, 0x21, 0x72, 0x31, 0xda, 0x28, 0x28, 0xfe, 0x33, 0xce,
+	0x02, 0x72, 0x1b, 0x88, 0x17, 0x3a, 0xfe, 0xc0, 0xc5, 0x0e, 0xf3, 0xdd, 0x8e, 0xfa, 0x8a, 0xca,
+	0xe6, 0x2d, 0xd0, 0x05, 0xfd, 0x66, 0xd3, 0x77, 0xd5, 0x50, 0x2b, 0x7d, 0x6b, 0x00, 0x1c, 0xfb,
+	0x90, 0x3a, 0x7f, 0x3e, 0x06, 0xd3, 0x76, 0x62, 0x31, 0x73, 0xb3, 0xb2, 0x60, 0xde, 0x98, 0x7a,
+	0xa9, 0x55, 0x89, 0x3d, 0xf0, 0x42, 0x97, 0x6a, 0x09, 0xb9, 0x0b, 0xf9, 0x7d, 0xcf, 0x8f, 0x91,
+	0x47, 0xd6, 0x05, 0x19, 0x92, 0xeb, 0x67, 0xb5, 0x09, 0x4d, 0xe0, 0xea, 0x2f, 0x49, 0x6c, 0xd7,
+	0x31, 0x8a, 0xec, 0x2e, 0x92, 0x4f, 0xc1, 0xc4, 0x21, 0x86, 0x71, 0x12, 0xda, 0xb7, 0xa6, 0x7a,
+	0xa1, 0x15, 0xb5, 0xa6, 0xc0, 0xa9, 0x56, 0x91, 0x0f, 0x20, 0x3f, 0x54, 0xd1, 0xfa, 0x2f, 0x01,
+	0x4d, 0xd8, 0xd2, 0x4f, 0x06, 0xcc, 0x48, 0x43, 0x27, 0xc2, 0x60, 0xbc, 0x7a, 0x18, 0x56, 0xc0,
+	0xd4, 0x89, 0xc8, 0x4e, 0xff, 0xf6, 0xa8, 0x94, 0x50, 0x4d, 0x92, 0x0f, 0x01, 0x26, 0x12, 0x78,
+	0xb6, 0xae, 0xc8, 0x92, 0xac, 0xde, 0xfc, 0xc7, 0x80, 0x4b, 0x13, 0xae, 0x90, 0x3b, 0xb0, 0xf8,
+	0x68, 0x75, 0xa7, 0xd1, 0xea, 0xac, 0x36, 0x76, 0xda, 0x9b, 0x1b, 0x9d, 0xdd, 0x8d, 0x07, 0x1b,
+	0x9b, 0x8f, 0x36, 0x16, 0x32, 0xa5, 0xd2, 0xd3, 0x67, 0x95, 0xab, 0x13, 0xf8, 0x6e, 0xd8, 0x0b,
+	0xd9, 0x81, 0x70, 0xfc, 0xf2, 0x29, 0x55, 0x83, 0x36, 0x57, 0x77, 0x9a, 0x0b, 0x46, 0xe9, 0x7f,
+	0x4f, 0x9f, 0x55, 0xae, 0x4c, 0x88, 0x1a, 0x1c, 0xd5, 0x64, 0x3a, 0xad, 0xd9, 0xdd, 0x5a, 0x13,
+	0x9a, 0x6c, 0xaa, 0x66, 0xb7, 0xef, 0xa6, 0x69, 0x68, 0x73, 0x7d, 0xf3, 0x61, 0x73, 0x21, 0x97,
+	0xaa, 0xa1, 0x18, 0xb0, 0x21, 0x96, 0xae, 0x7d, 0xf3, 0x7d, 0x39, 0xf3, 0xf3, 0x0f, 0xe5, 0xc9,
+	0xab, 0xae, 0x04, 0x30, 0x23, 0xb7, 0x88, 0x9b, 0x2c, 0x2a, 0xe7, 0x35, 0x62, 0xa9, 0x72, 0x5e,
+	0x3d, 0x55, 0xaf, 0xfc, 0xfa, 0xe3, 0xdf, 0xdf, 0x65, 0x2f, 0xc1, 0xbc, 0x24, 0xde, 0x09, 0xec,
+	0xd0, 0xee, 0x22, 0x7f, 0xd7, 0xa8, 0x5b, 0xcf, 0x5f, 0x94, 0x33, 0xbf, 0xbf, 0x28, 0x67, 0xbe,
+	0x1a, 0x97, 0x8d, 0xe7, 0xe3, 0xb2, 0xf1, 0xdb, 0xb8, 0x6c, 0xfc, 0x39, 0x2e, 0x1b, 0x7b, 0xa6,
+	0xfc, 0x03, 0xf9, 0xfe, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x76, 0x89, 0xef, 0x57, 0x0b,
+	0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/api/watch.proto b/vendor/github.com/docker/swarmkit/api/watch.proto
index f84fd9e..d017730 100644
--- a/vendor/github.com/docker/swarmkit/api/watch.proto
+++ b/vendor/github.com/docker/swarmkit/api/watch.proto
@@ -2,11 +2,11 @@
 
 package docker.swarmkit.v1;
 
-import "specs.proto";
-import "objects.proto";
-import "types.proto";
+import "github.com/docker/swarmkit/api/specs.proto";
+import "github.com/docker/swarmkit/api/objects.proto";
+import "github.com/docker/swarmkit/api/types.proto";
 import "gogoproto/gogo.proto";
-import "plugin/plugin.proto";
+import "github.com/docker/swarmkit/protobuf/plugin/plugin.proto";
 
 message Object {
 	oneof Object {
diff --git a/vendor/github.com/docker/swarmkit/ca/auth.go b/vendor/github.com/docker/swarmkit/ca/auth.go
index 10cb2c7..488d34d 100644
--- a/vendor/github.com/docker/swarmkit/ca/auth.go
+++ b/vendor/github.com/docker/swarmkit/ca/auth.go
@@ -5,7 +5,7 @@
 	"crypto/x509/pkix"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/log"
diff --git a/vendor/github.com/docker/swarmkit/ca/config.go b/vendor/github.com/docker/swarmkit/ca/config.go
index cfaccd0..0fd4ebe 100644
--- a/vendor/github.com/docker/swarmkit/ca/config.go
+++ b/vendor/github.com/docker/swarmkit/ca/config.go
@@ -12,7 +12,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	cfconfig "github.com/cloudflare/cfssl/config"
 	events "github.com/docker/go-events"
 	"github.com/docker/swarmkit/api"
@@ -22,6 +21,7 @@
 	"github.com/docker/swarmkit/watch"
 	"github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"google.golang.org/grpc/credentials"
 
 	"golang.org/x/net/context"
@@ -68,14 +68,11 @@
 	renewalMu sync.Mutex
 
 	rootCA        *RootCA
-	externalCA    *ExternalCA
 	keyReadWriter *KeyReadWriter
 
 	certificate *tls.Certificate
 	issuerInfo  *IssuerInfo
 
-	externalCAClientRootPool *x509.CertPool
-
 	ServerTLSCreds *MutableTLSCreds
 	ClientTLSCreds *MutableTLSCreds
 
@@ -90,7 +87,7 @@
 	Err  error
 }
 
-func validateRootCAAndTLSCert(rootCA *RootCA, externalCARootPool *x509.CertPool, tlsKeyPair *tls.Certificate) error {
+func validateRootCAAndTLSCert(rootCA *RootCA, tlsKeyPair *tls.Certificate) error {
 	var (
 		leafCert         *x509.Certificate
 		intermediatePool *x509.CertPool
@@ -116,10 +113,6 @@
 	if _, err := leafCert.Verify(opts); err != nil {
 		return errors.Wrap(err, "new root CA does not match existing TLS credentials")
 	}
-	opts.Roots = externalCARootPool
-	if _, err := leafCert.Verify(opts); err != nil {
-		return errors.Wrap(err, "new external root pool does not match existing TLS credentials")
-	}
 	return nil
 }
 
@@ -139,16 +132,7 @@
 		return nil, nil, err
 	}
 
-	// Make a new TLS config for the external CA client without a
-	// ServerName value set.
-	externalCATLSConfig := &tls.Config{
-		Certificates: []tls.Certificate{*tlsKeyPair},
-		RootCAs:      rootCA.Pool,
-		MinVersion:   tls.VersionTLS12,
-	}
-
 	q := watch.NewQueue()
-
 	return &SecurityConfig{
 		rootCA:        rootCA,
 		keyReadWriter: krw,
@@ -157,10 +141,8 @@
 		issuerInfo:  issuerInfo,
 		queue:       q,
 
-		externalCA:               NewExternalCA(rootCA, externalCATLSConfig),
-		ClientTLSCreds:           clientTLSCreds,
-		ServerTLSCreds:           serverTLSCreds,
-		externalCAClientRootPool: rootCA.Pool,
+		ClientTLSCreds: clientTLSCreds,
+		ServerTLSCreds: serverTLSCreds,
 	}, q.Close, nil
 }
 
@@ -172,11 +154,6 @@
 	return s.rootCA
 }
 
-// ExternalCA returns the external CA.
-func (s *SecurityConfig) ExternalCA() *ExternalCA {
-	return s.externalCA
-}
-
 // KeyWriter returns the object that can write keys to disk
 func (s *SecurityConfig) KeyWriter() KeyWriter {
 	return s.keyReadWriter
@@ -188,19 +165,16 @@
 }
 
 // UpdateRootCA replaces the root CA with a new root CA
-func (s *SecurityConfig) UpdateRootCA(rootCA *RootCA, externalCARootPool *x509.CertPool) error {
+func (s *SecurityConfig) UpdateRootCA(rootCA *RootCA) error {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
 	// refuse to update the root CA if the current TLS credentials do not validate against it
-	if err := validateRootCAAndTLSCert(rootCA, externalCARootPool, s.certificate); err != nil {
+	if err := validateRootCAAndTLSCert(rootCA, s.certificate); err != nil {
 		return err
 	}
 
 	s.rootCA = rootCA
-	s.externalCAClientRootPool = externalCARootPool
-	s.externalCA.UpdateRootCA(rootCA)
-
 	return s.updateTLSCredentials(s.certificate, s.issuerInfo)
 }
 
@@ -233,14 +207,6 @@
 		return errors.Wrap(err, "failed to update the client credentials")
 	}
 
-	// Update the external CA to use the new client TLS
-	// config using a copy without a serverName specified.
-	s.externalCA.UpdateTLSConfig(&tls.Config{
-		Certificates: certs,
-		RootCAs:      s.externalCAClientRootPool,
-		MinVersion:   tls.VersionTLS12,
-	})
-
 	if err := s.ServerTLSCreds.loadNewTLSConfig(serverConfig); err != nil {
 		return errors.Wrap(err, "failed to update the server TLS credentials")
 	}
@@ -507,7 +473,7 @@
 		return nil, nil, err
 	}
 	// validate against the existing security config creds
-	if err := s.UpdateRootCA(&rootCA, rootCA.Pool); err != nil {
+	if err := s.UpdateRootCA(&rootCA); err != nil {
 		return nil, nil, err
 	}
 	if err := SaveRootCA(rootCA, rootPaths); err != nil {
diff --git a/vendor/github.com/docker/swarmkit/ca/external.go b/vendor/github.com/docker/swarmkit/ca/external.go
index ef76e2f..789361e 100644
--- a/vendor/github.com/docker/swarmkit/ca/external.go
+++ b/vendor/github.com/docker/swarmkit/ca/external.go
@@ -14,13 +14,13 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/cloudflare/cfssl/api"
 	"github.com/cloudflare/cfssl/config"
 	"github.com/cloudflare/cfssl/csr"
 	"github.com/cloudflare/cfssl/signer"
 	"github.com/docker/swarmkit/log"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/net/context/ctxhttp"
 )
@@ -47,18 +47,28 @@
 type ExternalCA struct {
 	ExternalRequestTimeout time.Duration
 
-	mu     sync.Mutex
-	rootCA *RootCA
-	urls   []string
-	client *http.Client
+	mu            sync.Mutex
+	intermediates []byte
+	urls          []string
+	client        *http.Client
+}
+
+// NewExternalCATLSConfig takes a TLS certificate and root pool and returns a TLS config that can be updated
+// without killing existing connections
+func NewExternalCATLSConfig(certs []tls.Certificate, rootPool *x509.CertPool) *tls.Config {
+	return &tls.Config{
+		Certificates: certs,
+		RootCAs:      rootPool,
+		MinVersion:   tls.VersionTLS12,
+	}
 }
 
 // NewExternalCA creates a new ExternalCA which uses the given tlsConfig to
 // authenticate to any of the given URLS of CFSSL API endpoints.
-func NewExternalCA(rootCA *RootCA, tlsConfig *tls.Config, urls ...string) *ExternalCA {
+func NewExternalCA(intermediates []byte, tlsConfig *tls.Config, urls ...string) *ExternalCA {
 	return &ExternalCA{
 		ExternalRequestTimeout: 5 * time.Second,
-		rootCA:                 rootCA,
+		intermediates:          intermediates,
 		urls:                   urls,
 		client: &http.Client{
 			Transport: &http.Transport{
@@ -68,19 +78,6 @@
 	}
 }
 
-// Copy returns a copy of the external CA that can be updated independently
-func (eca *ExternalCA) Copy() *ExternalCA {
-	eca.mu.Lock()
-	defer eca.mu.Unlock()
-
-	return &ExternalCA{
-		ExternalRequestTimeout: eca.ExternalRequestTimeout,
-		rootCA:                 eca.rootCA,
-		urls:                   eca.urls,
-		client:                 eca.client,
-	}
-}
-
 // UpdateTLSConfig updates the HTTP Client for this ExternalCA by creating
 // a new client which uses the given tlsConfig.
 func (eca *ExternalCA) UpdateTLSConfig(tlsConfig *tls.Config) {
@@ -102,13 +99,6 @@
 	eca.urls = urls
 }
 
-// UpdateRootCA changes the root CA used to append intermediates
-func (eca *ExternalCA) UpdateRootCA(rca *RootCA) {
-	eca.mu.Lock()
-	eca.rootCA = rca
-	eca.mu.Unlock()
-}
-
 // Sign signs a new certificate by proxying the given certificate signing
 // request to an external CFSSL API server.
 func (eca *ExternalCA) Sign(ctx context.Context, req signer.SignRequest) (cert []byte, err error) {
@@ -117,7 +107,7 @@
 	eca.mu.Lock()
 	urls := eca.urls
 	client := eca.client
-	intermediates := eca.rootCA.Intermediates
+	intermediates := eca.intermediates
 	eca.mu.Unlock()
 
 	if len(urls) == 0 {
diff --git a/vendor/github.com/docker/swarmkit/ca/keyreadwriter.go b/vendor/github.com/docker/swarmkit/ca/keyreadwriter.go
index 964cb3e..4a7c0a0 100644
--- a/vendor/github.com/docker/swarmkit/ca/keyreadwriter.go
+++ b/vendor/github.com/docker/swarmkit/ca/keyreadwriter.go
@@ -187,10 +187,7 @@
 		return err
 	}
 
-	if err := k.writeKey(keyBlock, updatedKEK, updatedHeaderObj); err != nil {
-		return err
-	}
-	return nil
+	return k.writeKey(keyBlock, updatedKEK, updatedHeaderObj)
 }
 
 // ViewAndUpdateHeaders updates the header manager, and updates any headers on the existing key
diff --git a/vendor/github.com/docker/swarmkit/ca/renewer.go b/vendor/github.com/docker/swarmkit/ca/renewer.go
index 6d0229b..2a2fae7 100644
--- a/vendor/github.com/docker/swarmkit/ca/renewer.go
+++ b/vendor/github.com/docker/swarmkit/ca/renewer.go
@@ -4,11 +4,11 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/go-events"
 	"github.com/docker/swarmkit/connectionbroker"
 	"github.com/docker/swarmkit/log"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/vendor/github.com/docker/swarmkit/ca/server.go b/vendor/github.com/docker/swarmkit/ca/server.go
index cb3b6ac..16dbedc 100644
--- a/vendor/github.com/docker/swarmkit/ca/server.go
+++ b/vendor/github.com/docker/swarmkit/ca/server.go
@@ -7,7 +7,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/equality"
 	"github.com/docker/swarmkit/identity"
@@ -15,6 +14,7 @@
 	"github.com/docker/swarmkit/manager/state/store"
 	gogotypes "github.com/gogo/protobuf/types"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -25,13 +25,6 @@
 	defaultRootReconciliationInterval  = 3 * time.Second
 )
 
-// APISecurityConfigUpdater knows how to update a SecurityConfig from an api.Cluster object
-type APISecurityConfigUpdater interface {
-	UpdateRootCA(ctx context.Context, cluster *api.Cluster) error
-}
-
-var _ APISecurityConfigUpdater = &Server{}
-
 // Server is the CA and NodeCA API gRPC server.
 // TODO(aaronl): At some point we may want to have separate implementations of
 // CA, NodeCA, and other hypothetical future CA services. At the moment,
@@ -43,6 +36,10 @@
 	cancel                      func()
 	store                       *store.MemoryStore
 	securityConfig              *SecurityConfig
+	clusterID                   string
+	localRootCA                 *RootCA
+	externalCA                  *ExternalCA
+	externalCAPool              *x509.CertPool
 	joinTokens                  *api.JoinTokens
 	reconciliationRetryInterval time.Duration
 
@@ -60,10 +57,12 @@
 	// the security config as a result
 	lastSeenClusterRootCA *api.RootCA
 	lastSeenExternalCAs   []*api.ExternalCA
-	secConfigMu           sync.Mutex
 
-	// before we update the security config with the new root CA, we need to be able to save the root certs
-	rootPaths CertPaths
+	// This mutex protects the components of the CA server used to issue new certificates
+	// (and any attributes used to update those components): `lastSeenClusterRootCA` and
+	// `lastSeenExternalCA`, which are used to update `externalCA` and the `rootCA` object
+	// of the SecurityConfig
+	signingMu sync.Mutex
 
 	// lets us monitor and finish root rotations
 	rootReconciler                  *rootRotationReconciler
@@ -78,18 +77,36 @@
 }
 
 // NewServer creates a CA API server.
-func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig, rootCAPaths CertPaths) *Server {
+func NewServer(store *store.MemoryStore, securityConfig *SecurityConfig) *Server {
 	return &Server{
 		store:                           store,
 		securityConfig:                  securityConfig,
+		localRootCA:                     securityConfig.RootCA(),
+		externalCA:                      NewExternalCA(nil, nil),
 		pending:                         make(map[string]*api.Node),
 		started:                         make(chan struct{}),
 		reconciliationRetryInterval:     defaultReconciliationRetryInterval,
 		rootReconciliationRetryInterval: defaultRootReconciliationInterval,
-		rootPaths:                       rootCAPaths,
+		clusterID:                       securityConfig.ClientTLSCreds.Organization(),
 	}
 }
 
+// ExternalCA returns the current external CA - this is exposed to support unit testing only, and the external CA
+// should really be a private field
+func (s *Server) ExternalCA() *ExternalCA {
+	s.signingMu.Lock()
+	defer s.signingMu.Unlock()
+	return s.externalCA
+}
+
+// RootCA returns the current local root CA - this is exposed to support unit testing only, and the root CA
+// should really be a private field
+func (s *Server) RootCA() *RootCA {
+	s.signingMu.Lock()
+	defer s.signingMu.Unlock()
+	return s.localRootCA
+}
+
 // SetReconciliationRetryInterval changes the time interval between
 // reconciliation attempts. This function must be called before Run.
 func (s *Server) SetReconciliationRetryInterval(reconciliationRetryInterval time.Duration) {
@@ -114,7 +131,7 @@
 	// a cached value.
 	resp := api.GetUnlockKeyResponse{}
 	s.store.View(func(tx store.ReadTx) {
-		cluster := store.GetCluster(tx, s.securityConfig.ClientTLSCreds.Organization())
+		cluster := store.GetCluster(tx, s.clusterID)
 		resp.Version = cluster.Meta.Version
 		if cluster.Spec.EncryptionConfig.AutoLockManagers {
 			for _, encryptionKey := range cluster.UnlockKeys {
@@ -222,7 +239,7 @@
 		return nil, grpc.Errorf(codes.InvalidArgument, codes.InvalidArgument.String())
 	}
 
-	if _, err := s.isRunningLocked(); err != nil {
+	if err := s.isReadyLocked(); err != nil {
 		return nil, err
 	}
 
@@ -233,8 +250,7 @@
 	)
 
 	s.store.View(func(readTx store.ReadTx) {
-		clusters, err = store.FindClusters(readTx, store.ByName("default"))
-
+		clusters, err = store.FindClusters(readTx, store.ByName(store.DefaultClusterName))
 	})
 
 	// Not having a cluster object yet means we can't check
@@ -254,14 +270,14 @@
 
 	// If the remote node is a worker (either forwarded by a manager, or calling directly),
 	// issue a renew worker certificate entry with the correct ID
-	nodeID, err := AuthorizeForwardedRoleAndOrg(ctx, []string{WorkerRole}, []string{ManagerRole}, s.securityConfig.ClientTLSCreds.Organization(), blacklistedCerts)
+	nodeID, err := AuthorizeForwardedRoleAndOrg(ctx, []string{WorkerRole}, []string{ManagerRole}, s.clusterID, blacklistedCerts)
 	if err == nil {
 		return s.issueRenewCertificate(ctx, nodeID, request.CSR)
 	}
 
 	// If the remote node is a manager (either forwarded by another manager, or calling directly),
 	// issue a renew certificate entry with the correct ID
-	nodeID, err = AuthorizeForwardedRoleAndOrg(ctx, []string{ManagerRole}, []string{ManagerRole}, s.securityConfig.ClientTLSCreds.Organization(), blacklistedCerts)
+	nodeID, err = AuthorizeForwardedRoleAndOrg(ctx, []string{ManagerRole}, []string{ManagerRole}, s.clusterID, blacklistedCerts)
 	if err == nil {
 		return s.issueRenewCertificate(ctx, nodeID, request.CSR)
 	}
@@ -393,8 +409,11 @@
 		"method": "GetRootCACertificate",
 	})
 
+	s.signingMu.Lock()
+	defer s.signingMu.Unlock()
+
 	return &api.GetRootCACertificateResponse{
-		Certificate: s.securityConfig.RootCA().Certs,
+		Certificate: s.localRootCA.Certs,
 	}, nil
 }
 
@@ -409,47 +428,51 @@
 	s.wg.Add(1)
 	s.ctx, s.cancel = context.WithCancel(log.WithModule(ctx, "ca"))
 	ctx = s.ctx
-	// we need to set it on the server, because `Server.UpdateRootCA` can be called from outside the Run function
-	s.rootReconciler = &rootRotationReconciler{
-		ctx:                 log.WithField(ctx, "method", "(*Server).rootRotationReconciler"),
-		clusterID:           s.securityConfig.ClientTLSCreds.Organization(),
-		store:               s.store,
-		batchUpdateInterval: s.rootReconciliationRetryInterval,
-	}
-	rootReconciler := s.rootReconciler
 	s.mu.Unlock()
 	defer s.wg.Done()
 	defer func() {
 		s.mu.Lock()
-		s.rootReconciler = nil
 		s.mu.Unlock()
 	}()
 
 	// Retrieve the channels to keep track of changes in the cluster
 	// Retrieve all the currently registered nodes
-	var nodes []*api.Node
-
+	var (
+		nodes   []*api.Node
+		cluster *api.Cluster
+		err     error
+	)
 	updates, cancel, err := store.ViewAndWatch(
 		s.store,
 		func(readTx store.ReadTx) error {
-			clusters, err := store.FindClusters(readTx, store.ByName(store.DefaultClusterName))
-			if err != nil {
-				return err
-			}
-			if len(clusters) != 1 {
+			cluster = store.GetCluster(readTx, s.clusterID)
+			if cluster == nil {
 				return errors.New("could not find cluster object")
 			}
-			s.UpdateRootCA(ctx, clusters[0]) // call once to ensure that the join tokens are always set
 			nodes, err = store.FindNodes(readTx, store.All)
 			return err
 		},
 		api.EventCreateNode{},
 		api.EventUpdateNode{},
 		api.EventDeleteNode{},
+		api.EventUpdateCluster{
+			Cluster: &api.Cluster{ID: s.clusterID},
+			Checks:  []api.ClusterCheckFunc{api.ClusterCheckID},
+		},
 	)
 
-	// Do this after updateCluster has been called, so isRunning never
-	// returns true without joinTokens being set correctly.
+	// call once to ensure that the join tokens and local/external CA signer are always set
+	rootReconciler := &rootRotationReconciler{
+		ctx:                 log.WithField(ctx, "method", "(*Server).rootRotationReconciler"),
+		clusterID:           s.clusterID,
+		store:               s.store,
+		batchUpdateInterval: s.rootReconciliationRetryInterval,
+	}
+
+	s.UpdateRootCA(ctx, cluster, rootReconciler)
+
+	// Do this after updateCluster has been called, so Ready() and isRunning never returns true without
+	// the join tokens and external CA/security config's root CA being set correctly
 	s.mu.Lock()
 	close(s.started)
 	s.mu.Unlock()
@@ -475,6 +498,9 @@
 	ticker := time.NewTicker(s.reconciliationRetryInterval)
 	defer ticker.Stop()
 
+	externalTLSCredsChange, externalTLSWatchCancel := s.securityConfig.Watch()
+	defer externalTLSWatchCancel()
+
 	// Watch for new nodes being created, new nodes being updated, and changes
 	// to the cluster
 	for {
@@ -499,8 +525,29 @@
 				rootReconciler.UpdateNode(v.Node)
 			case api.EventDeleteNode:
 				rootReconciler.DeleteNode(v.Node)
+			case api.EventUpdateCluster:
+				if v.Cluster.ID == s.clusterID {
+					s.UpdateRootCA(ctx, v.Cluster, rootReconciler)
+				}
 			}
+		case <-externalTLSCredsChange:
+			// The TLS certificates can rotate independently of the root CA (and hence which roots the
+			// external CA trusts) and external CA URLs.  It's possible that the root CA update is received
+			// before the external TLS cred change notification.  During that period, it is possible that
+			// the TLS creds will expire or otherwise fail to authorize against external CAs.  However, in
+			// that case signing will just fail with a recoverable connectivity error - the state of the
+			// certificate issuance is left as pending, and on the next tick, the server will try to sign
+			// all nodes with pending certs again (by which time the TLS cred change will have been
+			// received).
 
+			// Note that if the external CA changes, the new external CA *MUST* trust the current server's
+			// certificate issuer, and this server's certificates should not be extremely close to expiry,
+			// otherwise this server would not be able to get new TLS certificates and will no longer be
+			// able to function.
+			s.signingMu.Lock()
+			s.externalCA.UpdateTLSConfig(NewExternalCATLSConfig(
+				s.securityConfig.ClientTLSCreds.Config().Certificates, s.externalCAPool))
+			s.signingMu.Unlock()
 		case <-ticker.C:
 			for _, node := range s.pending {
 				if err := s.evaluateAndSignNodeCert(ctx, node); err != nil {
@@ -527,6 +574,7 @@
 	}
 	s.cancel()
 	s.started = make(chan struct{})
+	s.joinTokens = nil
 	s.mu.Unlock()
 
 	// Wait for Run to complete
@@ -553,6 +601,18 @@
 	return ctx, nil
 }
 
+func (s *Server) isReadyLocked() error {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if !s.isRunning() {
+		return grpc.Errorf(codes.Aborted, "CA signer is stopped")
+	}
+	if s.joinTokens == nil {
+		return grpc.Errorf(codes.Aborted, "CA signer is still starting")
+	}
+	return nil
+}
+
 func (s *Server) isRunning() bool {
 	if s.ctx == nil {
 		return false
@@ -565,33 +625,59 @@
 	return true
 }
 
+// filterExternalCAURLS returns a list of external CA urls filtered by the desired cert.
+func filterExternalCAURLS(ctx context.Context, desiredCert, defaultCert []byte, apiExternalCAs []*api.ExternalCA) (urls []string) {
+	desiredCert = NormalizePEMs(desiredCert)
+
+	// TODO(aaronl): In the future, this will be abstracted with an ExternalCA interface that has different
+	// implementations for different CA types. At the moment, only CFSSL is supported.
+	for i, extCA := range apiExternalCAs {
+		// We want to support old external CA specifications which did not have a CA cert.  If there is no cert specified,
+		// we assume it's the old cert
+		certForExtCA := extCA.CACert
+		if len(certForExtCA) == 0 {
+			certForExtCA = defaultCert
+		}
+		certForExtCA = NormalizePEMs(certForExtCA)
+		if extCA.Protocol != api.ExternalCA_CAProtocolCFSSL {
+			log.G(ctx).Debugf("skipping external CA %d (url: %s) due to unknown protocol type", i, extCA.URL)
+			continue
+		}
+		if !bytes.Equal(certForExtCA, desiredCert) {
+			log.G(ctx).Debugf("skipping external CA %d (url: %s) because it has the wrong CA cert", i, extCA.URL)
+			continue
+		}
+		urls = append(urls, extCA.URL)
+	}
+	return
+}
+
 // UpdateRootCA is called when there are cluster changes, and it ensures that the local RootCA is
 // always aware of changes in clusterExpiry and the Root CA key material - this can be called by
 // anything to update the root CA material
-func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster) error {
+func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster, reconciler *rootRotationReconciler) error {
 	s.mu.Lock()
 	s.joinTokens = cluster.RootCA.JoinTokens.Copy()
-	reconciler := s.rootReconciler
 	s.mu.Unlock()
 	rCA := cluster.RootCA.Copy()
 	if reconciler != nil {
 		reconciler.UpdateRootCA(rCA)
 	}
 
-	s.secConfigMu.Lock()
-	defer s.secConfigMu.Unlock()
+	s.signingMu.Lock()
+	defer s.signingMu.Unlock()
 	firstSeenCluster := s.lastSeenClusterRootCA == nil && s.lastSeenExternalCAs == nil
 	rootCAChanged := len(rCA.CACert) != 0 && !equality.RootCAEqualStable(s.lastSeenClusterRootCA, rCA)
 	externalCAChanged := !equality.ExternalCAsEqualStable(s.lastSeenExternalCAs, cluster.Spec.CAConfig.ExternalCAs)
-	logger := log.G(ctx).WithFields(logrus.Fields{
+	ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{
 		"cluster.id": cluster.ID,
 		"method":     "(*Server).UpdateRootCA",
-	})
+	}))
 
 	if rootCAChanged {
 		setOrUpdate := "set"
 		if !firstSeenCluster {
-			logger.Debug("Updating security config due to change in cluster Root CA")
+			log.G(ctx).Debug("Updating signing root CA and external CA due to change in cluster Root CA")
 			setOrUpdate = "updated"
 		}
 		expiry := DefaultNodeCertExpiration
@@ -599,91 +685,55 @@
 			// NodeCertExpiry exists, let's try to parse the duration out of it
 			clusterExpiry, err := gogotypes.DurationFromProto(cluster.Spec.CAConfig.NodeCertExpiry)
 			if err != nil {
-				logger.WithError(err).Warn("failed to parse certificate expiration, using default")
+				log.G(ctx).WithError(err).Warn("failed to parse certificate expiration, using default")
 			} else {
 				// We were able to successfully parse the expiration out of the cluster.
 				expiry = clusterExpiry
 			}
 		} else {
 			// NodeCertExpiry seems to be nil
-			logger.Warn("no certificate expiration specified, using default")
+			log.G(ctx).Warn("no certificate expiration specified, using default")
 		}
 		// Attempt to update our local RootCA with the new parameters
-		var intermediates []byte
-		signingCert := rCA.CACert
-		signingKey := rCA.CAKey
-		if rCA.RootRotation != nil {
-			signingCert = rCA.RootRotation.CrossSignedCACert
-			signingKey = rCA.RootRotation.CAKey
-			intermediates = rCA.RootRotation.CrossSignedCACert
-		}
-		if signingKey == nil {
-			signingCert = nil
-		}
-		updatedRootCA, err := NewRootCA(rCA.CACert, signingCert, signingKey, expiry, intermediates)
+		updatedRootCA, err := RootCAFromAPI(ctx, rCA, expiry)
 		if err != nil {
 			return errors.Wrap(err, "invalid Root CA object in cluster")
 		}
-		externalCARootPool := updatedRootCA.Pool
+
+		s.localRootCA = &updatedRootCA
+		s.externalCAPool = updatedRootCA.Pool
+		externalCACert := rCA.CACert
 		if rCA.RootRotation != nil {
+			externalCACert = rCA.RootRotation.CACert
 			// the external CA has to trust the new CA cert
-			externalCARootPool = x509.NewCertPool()
-			externalCARootPool.AppendCertsFromPEM(rCA.CACert)
-			externalCARootPool.AppendCertsFromPEM(rCA.RootRotation.CACert)
+			s.externalCAPool = x509.NewCertPool()
+			s.externalCAPool.AppendCertsFromPEM(rCA.CACert)
+			s.externalCAPool.AppendCertsFromPEM(rCA.RootRotation.CACert)
 		}
+		s.lastSeenExternalCAs = cluster.Spec.CAConfig.Copy().ExternalCAs
+		urls := filterExternalCAURLS(ctx, externalCACert, rCA.CACert, s.lastSeenExternalCAs)
+		// Replace the external CA with the relevant intermediates, URLS, and TLS config
+		s.externalCA = NewExternalCA(updatedRootCA.Intermediates,
+			NewExternalCATLSConfig(s.securityConfig.ClientTLSCreds.Config().Certificates, s.externalCAPool), urls...)
 
-		// Attempt to update our local RootCA with the new parameters
-		if err := s.securityConfig.UpdateRootCA(&updatedRootCA, externalCARootPool); err != nil {
-			return errors.Wrap(err, "updating Root CA failed")
-		}
-		if err := SaveRootCA(updatedRootCA, s.rootPaths); err != nil {
-			return errors.Wrap(err, "unable to save new root CA certificates")
-		}
 		// only update the server cache if we've successfully updated the root CA
-		logger.Debugf("Root CA %s successfully", setOrUpdate)
+		log.G(ctx).Debugf("Root CA %s successfully", setOrUpdate)
 		s.lastSeenClusterRootCA = rCA
-	}
-
-	// we want to update if the external CA changed, or if the root CA changed because the root CA could affect what
-	// certificate for external CAs we want to filter by
-	if rootCAChanged || externalCAChanged {
+	} else if externalCAChanged {
+		// we want to update only if the external CA URLS have changed, since if the root CA has changed we already
+		// run similar logic
 		if !firstSeenCluster {
-			logger.Debug("Updating security config external CA URLs due to change in cluster Root CA or cluster spec")
+			log.G(ctx).Debug("Updating security config external CA URLs due to change in cluster spec's list of external CAs")
 		}
 		wantedExternalCACert := rCA.CACert // we want to only add external CA URLs that use this cert
 		if rCA.RootRotation != nil {
 			// we're rotating to a new root, so we only want external CAs with the new root cert
 			wantedExternalCACert = rCA.RootRotation.CACert
 		}
-		wantedExternalCACert = NormalizePEMs(wantedExternalCACert)
-		// Update our security config with the list of External CA URLs
-		// from the new cluster state.
-
-		// TODO(aaronl): In the future, this will be abstracted with an
-		// ExternalCA interface that has different implementations for
-		// different CA types. At the moment, only CFSSL is supported.
-		var cfsslURLs []string
-		for i, extCA := range cluster.Spec.CAConfig.ExternalCAs {
-			// We want to support old external CA specifications which did not have a CA cert.  If there is no cert specified,
-			// we assume it's the old cert
-			certForExtCA := extCA.CACert
-			if len(certForExtCA) == 0 {
-				certForExtCA = rCA.CACert
-			}
-			certForExtCA = NormalizePEMs(certForExtCA)
-			if extCA.Protocol != api.ExternalCA_CAProtocolCFSSL {
-				logger.Debugf("skipping external CA %d (url: %s) due to unknown protocol type", i, extCA.URL)
-				continue
-			}
-			if !bytes.Equal(certForExtCA, wantedExternalCACert) {
-				logger.Debugf("skipping external CA %d (url: %s) because it has the wrong CA cert", i, extCA.URL)
-				continue
-			}
-			cfsslURLs = append(cfsslURLs, extCA.URL)
-		}
-
-		s.securityConfig.externalCA.UpdateURLs(cfsslURLs...)
+		// Update our external CA with the list of External CA URLs from the new cluster state
 		s.lastSeenExternalCAs = cluster.Spec.CAConfig.Copy().ExternalCAs
+		urls := filterExternalCAURLS(ctx, wantedExternalCACert, rCA.CACert, s.lastSeenExternalCAs)
+		s.externalCA.UpdateURLs(urls...)
 	}
 	return nil
 }
@@ -714,8 +764,10 @@
 
 // signNodeCert does the bulk of the work for signing a certificate
 func (s *Server) signNodeCert(ctx context.Context, node *api.Node) error {
-	rootCA := s.securityConfig.RootCA()
-	externalCA := s.securityConfig.externalCA
+	s.signingMu.Lock()
+	rootCA := s.localRootCA
+	externalCA := s.externalCA
+	s.signingMu.Unlock()
 
 	node = node.Copy()
 	nodeID := node.ID
@@ -736,7 +788,7 @@
 		rawCSR = node.Certificate.CSR
 		cn     = node.Certificate.CN
 		ou     = role
-		org    = s.securityConfig.ClientTLSCreds.Organization()
+		org    = s.clusterID
 	)
 
 	// Try using the external CA first.
@@ -847,3 +899,19 @@
 
 	return false
 }
+
+// RootCAFromAPI creates a RootCA object from an api.RootCA object
+func RootCAFromAPI(ctx context.Context, apiRootCA *api.RootCA, expiry time.Duration) (RootCA, error) {
+	var intermediates []byte
+	signingCert := apiRootCA.CACert
+	signingKey := apiRootCA.CAKey
+	if apiRootCA.RootRotation != nil {
+		signingCert = apiRootCA.RootRotation.CrossSignedCACert
+		signingKey = apiRootCA.RootRotation.CAKey
+		intermediates = apiRootCA.RootRotation.CrossSignedCACert
+	}
+	if signingKey == nil {
+		signingCert = nil
+	}
+	return NewRootCA(apiRootCA.CACert, signingCert, signingKey, expiry, intermediates)
+}
diff --git a/vendor/github.com/docker/swarmkit/log/context.go b/vendor/github.com/docker/swarmkit/log/context.go
index ce7da93..ac4f848 100644
--- a/vendor/github.com/docker/swarmkit/log/context.go
+++ b/vendor/github.com/docker/swarmkit/log/context.go
@@ -3,7 +3,7 @@
 import (
 	"path"
 
-	"github.com/Sirupsen/logrus"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go b/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go
index 2cfc951..ab1b6d6 100644
--- a/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go
+++ b/vendor/github.com/docker/swarmkit/manager/allocator/cnmallocator/networkallocator.go
@@ -48,8 +48,10 @@
 	tasks map[string]struct{}
 
 	// Allocator state to indicate if allocation has been
-	// successfully completed for this node.
-	nodes map[string]struct{}
+	// successfully completed for this node on this network.
+	// outer map key: node id
+	// inner map key: network id
+	nodes map[string]map[string]struct{}
 }
 
 // Local in-memory state related to network that need to be tracked by cnmNetworkAllocator
@@ -89,7 +91,7 @@
 		networks: make(map[string]*network),
 		services: make(map[string]struct{}),
 		tasks:    make(map[string]struct{}),
-		nodes:    make(map[string]struct{}),
+		nodes:    make(map[string]map[string]struct{}),
 	}
 
 	// There are no driver configurations and notification
@@ -430,56 +432,6 @@
 	return true
 }
 
-// IsNodeAllocated returns if the passed node has its network resources allocated or not.
-func (na *cnmNetworkAllocator) IsNodeAllocated(node *api.Node) bool {
-	// If the node is not found in the allocated set, then it is
-	// not allocated.
-	if _, ok := na.nodes[node.ID]; !ok {
-		return false
-	}
-
-	// If no attachment, not allocated.
-	if node.Attachment == nil {
-		return false
-	}
-
-	// If the network is not allocated, the node cannot be allocated.
-	localNet, ok := na.networks[node.Attachment.Network.ID]
-	if !ok {
-		return false
-	}
-
-	// Addresses empty, not allocated.
-	if len(node.Attachment.Addresses) == 0 {
-		return false
-	}
-
-	// The allocated IP address not found in local endpoint state. Not allocated.
-	if _, ok := localNet.endpoints[node.Attachment.Addresses[0]]; !ok {
-		return false
-	}
-
-	return true
-}
-
-// AllocateNode allocates the IP addresses for the network to which
-// the node is attached.
-func (na *cnmNetworkAllocator) AllocateNode(node *api.Node) error {
-	if err := na.allocateNetworkIPs(node.Attachment); err != nil {
-		return err
-	}
-
-	na.nodes[node.ID] = struct{}{}
-	return nil
-}
-
-// DeallocateNode deallocates the IP addresses for the network to
-// which the node is attached.
-func (na *cnmNetworkAllocator) DeallocateNode(node *api.Node) error {
-	delete(na.nodes, node.ID)
-	return na.releaseEndpoints([]*api.NetworkAttachment{node.Attachment})
-}
-
 // AllocateTask allocates all the endpoint resources for all the
 // networks that a task is attached to.
 func (na *cnmNetworkAllocator) AllocateTask(t *api.Task) error {
@@ -489,7 +441,7 @@
 		}
 		if err := na.allocateNetworkIPs(nAttach); err != nil {
 			if err := na.releaseEndpoints(t.Networks[:i]); err != nil {
-				log.G(context.TODO()).WithError(err).Errorf("Failed to release IP addresses while rolling back allocation for task %s network %s", t.ID, nAttach.Network.ID)
+				log.G(context.TODO()).WithError(err).Errorf("failed to release IP addresses while rolling back allocation for task %s network %s", t.ID, nAttach.Network.ID)
 			}
 			return errors.Wrapf(err, "failed to allocate network IP for task %s network %s", t.ID, nAttach.Network.ID)
 		}
@@ -507,6 +459,75 @@
 	return na.releaseEndpoints(t.Networks)
 }
 
+// IsAttachmentAllocated returns if the passed node and network has resources allocated or not.
+func (na *cnmNetworkAllocator) IsAttachmentAllocated(node *api.Node, networkAttachment *api.NetworkAttachment) bool {
+	if node == nil {
+		return false
+	}
+
+	if networkAttachment == nil {
+		return false
+	}
+
+	// If the node is not found in the allocated set, then it is
+	// not allocated.
+	if _, ok := na.nodes[node.ID]; !ok {
+		return false
+	}
+
+	// If the nework is not found in the allocated set, then it is
+	// not allocated.
+	if _, ok := na.nodes[node.ID][networkAttachment.Network.ID]; !ok {
+		return false
+	}
+
+	// If the network is not allocated, the node cannot be allocated.
+	localNet, ok := na.networks[networkAttachment.Network.ID]
+	if !ok {
+		return false
+	}
+
+	// Addresses empty, not allocated.
+	if len(networkAttachment.Addresses) == 0 {
+		return false
+	}
+
+	// The allocated IP address not found in local endpoint state. Not allocated.
+	if _, ok := localNet.endpoints[networkAttachment.Addresses[0]]; !ok {
+		return false
+	}
+
+	return true
+}
+
+// AllocateAttachment allocates the IP addresses for a LB in a network
+// on a given node
+func (na *cnmNetworkAllocator) AllocateAttachment(node *api.Node, networkAttachment *api.NetworkAttachment) error {
+
+	if err := na.allocateNetworkIPs(networkAttachment); err != nil {
+		return err
+	}
+
+	if na.nodes[node.ID] == nil {
+		na.nodes[node.ID] = make(map[string]struct{})
+	}
+	na.nodes[node.ID][networkAttachment.Network.ID] = struct{}{}
+
+	return nil
+}
+
+// DeallocateAttachment deallocates the IP addresses for a LB in a network to
+// which the node is attached.
+func (na *cnmNetworkAllocator) DeallocateAttachment(node *api.Node, networkAttachment *api.NetworkAttachment) error {
+
+	delete(na.nodes[node.ID], networkAttachment.Network.ID)
+	if len(na.nodes[node.ID]) == 0 {
+		delete(na.nodes, node.ID)
+	}
+
+	return na.releaseEndpoints([]*api.NetworkAttachment{networkAttachment})
+}
+
 func (na *cnmNetworkAllocator) releaseEndpoints(networks []*api.NetworkAttachment) error {
 	for _, nAttach := range networks {
 		localNet := na.getNetwork(nAttach.Network.ID)
diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/network.go b/vendor/github.com/docker/swarmkit/manager/allocator/network.go
index c760ad5..c771512 100644
--- a/vendor/github.com/docker/swarmkit/manager/allocator/network.go
+++ b/vendor/github.com/docker/swarmkit/manager/allocator/network.go
@@ -154,11 +154,10 @@
 
 	// First, allocate objects that already have addresses associated with
 	// them, to reserve these IP addresses in internal state.
-	if nc.ingressNetwork != nil {
-		if err := a.allocateNodes(ctx, true); err != nil {
-			return err
-		}
+	if err := a.allocateNodes(ctx, true); err != nil {
+		return err
 	}
+
 	if err := a.allocateServices(ctx, true); err != nil {
 		return err
 	}
@@ -166,20 +165,14 @@
 		return err
 	}
 
-	// Now allocate objects that don't have addresses yet.
-	if nc.ingressNetwork != nil {
-		if err := a.allocateNodes(ctx, false); err != nil {
-			return err
-		}
-	}
-	if err := a.allocateServices(ctx, false); err != nil {
-		return err
-	}
-	if err := a.allocateTasks(ctx, false); err != nil {
+	if err := a.allocateNodes(ctx, false); err != nil {
 		return err
 	}
 
-	return nil
+	if err := a.allocateServices(ctx, false); err != nil {
+		return err
+	}
+	return a.allocateTasks(ctx, false)
 }
 
 func (a *Allocator) doNetworkAlloc(ctx context.Context, ev events.Event) {
@@ -208,22 +201,22 @@
 		}); err != nil {
 			log.G(ctx).WithError(err).Errorf("Failed to commit allocation for network %s", n.ID)
 		}
-
 		if IsIngressNetwork(n) {
 			nc.ingressNetwork = n
-			err := a.allocateNodes(ctx, false)
-			if err != nil {
-				log.G(ctx).WithError(err).Error(err)
-			}
+		}
+		err := a.allocateNodes(ctx, false)
+		if err != nil {
+			log.G(ctx).WithError(err).Error(err)
 		}
 	case api.EventDeleteNetwork:
 		n := v.Network.Copy()
 
 		if IsIngressNetwork(n) && nc.ingressNetwork != nil && nc.ingressNetwork.ID == n.ID {
 			nc.ingressNetwork = nil
-			if err := a.deallocateNodes(ctx); err != nil {
-				log.G(ctx).WithError(err).Error(err)
-			}
+		}
+
+		if err := a.deallocateNodeAttachments(ctx, n.ID); err != nil {
+			log.G(ctx).WithError(err).Error(err)
 		}
 
 		// The assumption here is that all dependent objects
@@ -361,33 +354,67 @@
 	nc := a.netCtx
 
 	if isDelete {
-		if nc.nwkAllocator.IsNodeAllocated(node) {
-			if err := nc.nwkAllocator.DeallocateNode(node); err != nil {
-				log.G(ctx).WithError(err).Errorf("Failed freeing network resources for node %s", node.ID)
-			} else {
-				nc.somethingWasDeallocated = true
+		if err := a.deallocateNode(node); err != nil {
+			log.G(ctx).WithError(err).Errorf("Failed freeing network resources for node %s", node.ID)
+		} else {
+			nc.somethingWasDeallocated = true
+		}
+	} else {
+		allocatedNetworks, err := a.getAllocatedNetworks()
+		if err != nil {
+			log.G(ctx).WithError(err).Errorf("Error listing allocated networks in network %s", node.ID)
+		}
+
+		isAllocated := a.allocateNode(ctx, node, false, allocatedNetworks)
+
+		if isAllocated {
+			if err := a.store.Batch(func(batch *store.Batch) error {
+				return a.commitAllocatedNode(ctx, batch, node)
+			}); err != nil {
+				log.G(ctx).WithError(err).Errorf("Failed to commit allocation of network resources for node %s", node.ID)
 			}
 		}
-		return
+	}
+}
+
+func isOverlayNetwork(n *api.Network) bool {
+	if n.DriverState != nil && n.DriverState.Name == "overlay" {
+		return true
 	}
 
-	if !nc.nwkAllocator.IsNodeAllocated(node) && nc.ingressNetwork != nil {
-		if node.Attachment == nil {
-			node.Attachment = &api.NetworkAttachment{}
-		}
+	if n.Spec.DriverConfig != nil && n.Spec.DriverConfig.Name == "overlay" {
+		return true
+	}
 
-		node.Attachment.Network = nc.ingressNetwork.Copy()
-		if err := a.allocateNode(ctx, node); err != nil {
-			log.G(ctx).WithError(err).Errorf("Failed to allocate network resources for node %s", node.ID)
-			return
-		}
+	return false
+}
 
-		if err := a.store.Batch(func(batch *store.Batch) error {
-			return a.commitAllocatedNode(ctx, batch, node)
-		}); err != nil {
-			log.G(ctx).WithError(err).Errorf("Failed to commit allocation of network resources for node %s", node.ID)
+func (a *Allocator) getAllocatedNetworks() ([]*api.Network, error) {
+	var (
+		err               error
+		nc                = a.netCtx
+		na                = nc.nwkAllocator
+		allocatedNetworks []*api.Network
+	)
+
+	// Find allocated networks
+	var networks []*api.Network
+	a.store.View(func(tx store.ReadTx) {
+		networks, err = store.FindNetworks(tx, store.All)
+	})
+
+	if err != nil {
+		return nil, errors.Wrap(err, "error listing all networks in store while trying to allocate during init")
+	}
+
+	for _, n := range networks {
+
+		if isOverlayNetwork(n) && na.IsAllocated(n) {
+			allocatedNetworks = append(allocatedNetworks, n)
 		}
 	}
+
+	return allocatedNetworks, nil
 }
 
 func (a *Allocator) allocateNodes(ctx context.Context, existingAddressesOnly bool) error {
@@ -396,7 +423,6 @@
 		allocatedNodes []*api.Node
 		nodes          []*api.Node
 		err            error
-		nc             = a.netCtx
 	)
 
 	a.store.View(func(tx store.ReadTx) {
@@ -406,26 +432,16 @@
 		return errors.Wrap(err, "error listing all nodes in store while trying to allocate network resources")
 	}
 
+	allocatedNetworks, err := a.getAllocatedNetworks()
+	if err != nil {
+		return errors.Wrap(err, "error listing all nodes in store while trying to allocate network resources")
+	}
+
 	for _, node := range nodes {
-		if nc.nwkAllocator.IsNodeAllocated(node) {
-			continue
+		isAllocated := a.allocateNode(ctx, node, existingAddressesOnly, allocatedNetworks)
+		if isAllocated {
+			allocatedNodes = append(allocatedNodes, node)
 		}
-
-		if node.Attachment == nil {
-			node.Attachment = &api.NetworkAttachment{}
-		}
-
-		if existingAddressesOnly && len(node.Attachment.Addresses) == 0 {
-			continue
-		}
-
-		node.Attachment.Network = nc.ingressNetwork.Copy()
-		if err := a.allocateNode(ctx, node); err != nil {
-			log.G(ctx).WithError(err).Errorf("Failed to allocate network resources for node %s", node.ID)
-			continue
-		}
-
-		allocatedNodes = append(allocatedNodes, node)
 	}
 
 	if err := a.store.Batch(func(batch *store.Batch) error {
@@ -457,21 +473,90 @@
 	}
 
 	for _, node := range nodes {
-		if nc.nwkAllocator.IsNodeAllocated(node) {
-			if err := nc.nwkAllocator.DeallocateNode(node); err != nil {
-				log.G(ctx).WithError(err).Errorf("Failed freeing network resources for node %s", node.ID)
-			} else {
-				nc.somethingWasDeallocated = true
+		if err := a.deallocateNode(node); err != nil {
+			log.G(ctx).WithError(err).Errorf("Failed freeing network resources for node %s", node.ID)
+		} else {
+			nc.somethingWasDeallocated = true
+		}
+		if err := a.store.Batch(func(batch *store.Batch) error {
+			return a.commitAllocatedNode(ctx, batch, node)
+		}); err != nil {
+			log.G(ctx).WithError(err).Errorf("Failed to commit deallocation of network resources for node %s", node.ID)
+		}
+	}
+
+	return nil
+}
+
+func (a *Allocator) deallocateNodeAttachments(ctx context.Context, nid string) error {
+	var (
+		nodes []*api.Node
+		nc    = a.netCtx
+		err   error
+	)
+
+	a.store.View(func(tx store.ReadTx) {
+		nodes, err = store.FindNodes(tx, store.All)
+	})
+	if err != nil {
+		return fmt.Errorf("error listing all nodes in store while trying to free network resources")
+	}
+
+	for _, node := range nodes {
+
+		var networkAttachment *api.NetworkAttachment
+		var naIndex int
+		for index, na := range node.Attachments {
+			if na.Network.ID == nid {
+				networkAttachment = na
+				naIndex = index
+				break
 			}
-			node.Attachment = nil
-			if err := a.store.Batch(func(batch *store.Batch) error {
-				return a.commitAllocatedNode(ctx, batch, node)
-			}); err != nil {
+		}
+
+		if networkAttachment == nil {
+			log.G(ctx).Errorf("Failed to find network %s on node %s", nid, node.ID)
+			continue
+		}
+
+		if nc.nwkAllocator.IsAttachmentAllocated(node, networkAttachment) {
+			if err := nc.nwkAllocator.DeallocateAttachment(node, networkAttachment); err != nil {
 				log.G(ctx).WithError(err).Errorf("Failed to commit deallocation of network resources for node %s", node.ID)
+			} else {
+
+				// Delete the lbattachment
+				node.Attachments[naIndex] = node.Attachments[len(node.Attachments)-1]
+				node.Attachments[len(node.Attachments)-1] = nil
+				node.Attachments = node.Attachments[:len(node.Attachments)-1]
+
+				if err := a.store.Batch(func(batch *store.Batch) error {
+					return a.commitAllocatedNode(ctx, batch, node)
+				}); err != nil {
+					log.G(ctx).WithError(err).Errorf("Failed to commit deallocation of network resources for node %s", node.ID)
+				}
+
+			}
+		}
+
+	}
+	return nil
+}
+
+func (a *Allocator) deallocateNode(node *api.Node) error {
+	var (
+		nc = a.netCtx
+	)
+
+	for _, na := range node.Attachments {
+		if nc.nwkAllocator.IsAttachmentAllocated(node, na) {
+			if err := nc.nwkAllocator.DeallocateAttachment(node, na); err != nil {
+				return err
 			}
 		}
 	}
 
+	node.Attachments = nil
+
 	return nil
 }
 
@@ -758,8 +843,48 @@
 	nc.pendingTasks[t.ID] = t
 }
 
-func (a *Allocator) allocateNode(ctx context.Context, node *api.Node) error {
-	return a.netCtx.nwkAllocator.AllocateNode(node)
+func (a *Allocator) allocateNode(ctx context.Context, node *api.Node, existingAddressesOnly bool, networks []*api.Network) bool {
+	var allocated bool
+
+	nc := a.netCtx
+
+	for _, network := range networks {
+
+		var lbAttachment *api.NetworkAttachment
+		for _, na := range node.Attachments {
+			if na.Network != nil && na.Network.ID == network.ID {
+				lbAttachment = na
+				break
+			}
+		}
+
+		if lbAttachment != nil {
+			if nc.nwkAllocator.IsAttachmentAllocated(node, lbAttachment) {
+				continue
+			}
+		}
+
+		if lbAttachment == nil {
+			lbAttachment = &api.NetworkAttachment{}
+			node.Attachments = append(node.Attachments, lbAttachment)
+		}
+
+		if existingAddressesOnly && len(lbAttachment.Addresses) == 0 {
+			continue
+		}
+
+		lbAttachment.Network = network.Copy()
+		if err := a.netCtx.nwkAllocator.AllocateAttachment(node, lbAttachment); err != nil {
+			log.G(ctx).WithError(err).Errorf("Failed to allocate network resources for node %s", node.ID)
+			// TODO: Should we add a unallocatedNode and retry allocating resources like we do for network, tasks, services?
+			// right now, we will only retry allocating network resources for the node when the node is updated.
+			continue
+		}
+
+		allocated = true
+	}
+	return allocated
+
 }
 
 func (a *Allocator) commitAllocatedNode(ctx context.Context, batch *store.Batch, node *api.Node) error {
@@ -768,13 +893,13 @@
 
 		if err == store.ErrSequenceConflict {
 			storeNode := store.GetNode(tx, node.ID)
-			storeNode.Attachment = node.Attachment.Copy()
+			storeNode.Attachments = node.Attachments
 			err = store.UpdateNode(tx, storeNode)
 		}
 
 		return errors.Wrapf(err, "failed updating state in store transaction for node %s", node.ID)
 	}); err != nil {
-		if err := a.netCtx.nwkAllocator.DeallocateNode(node); err != nil {
+		if err := a.deallocateNode(node); err != nil {
 			log.G(ctx).WithError(err).Errorf("failed rolling back allocation of node %s", node.ID)
 		}
 
diff --git a/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go b/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go
index 04dd168..f6b69b4 100644
--- a/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go
+++ b/vendor/github.com/docker/swarmkit/manager/allocator/networkallocator/networkallocator.go
@@ -66,22 +66,6 @@
 	HostPublishPortsNeedUpdate(s *api.Service) bool
 
 	//
-	// Node Allocation
-	//
-
-	// IsNodeAllocated returns if the passed node has its network
-	// resources allocated or not.
-	IsNodeAllocated(node *api.Node) bool
-
-	// AllocateNode allocates the IP addresses for the network to which
-	// the node is attached.
-	AllocateNode(node *api.Node) error
-
-	// DeallocateNode deallocates the IP addresses for the network to
-	// which the node is attached.
-	DeallocateNode(node *api.Node) error
-
-	//
 	// Task Allocation
 	//
 
@@ -96,6 +80,15 @@
 	// DeallocateTask releases all the endpoint resources for all the
 	// networks that a task is attached to.
 	DeallocateTask(t *api.Task) error
+
+	// AllocateAttachment Allocates a load balancer endpoint for the node
+	AllocateAttachment(node *api.Node, networkAttachment *api.NetworkAttachment) error
+
+	// DeallocateAttachment Deallocates a load balancer endpoint for the node
+	DeallocateAttachment(node *api.Node, networkAttachment *api.NetworkAttachment) error
+
+	// IsAttachmentAllocated If lb endpoint is allocated on the node
+	IsAttachmentAllocated(node *api.Node, networkAttachment *api.NetworkAttachment) bool
 }
 
 // IsIngressNetwork check if the network is an ingress network
diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/ca_rotation.go b/vendor/github.com/docker/swarmkit/manager/controlapi/ca_rotation.go
index 41e9a4d..5e8fa43 100644
--- a/vendor/github.com/docker/swarmkit/manager/controlapi/ca_rotation.go
+++ b/vendor/github.com/docker/swarmkit/manager/controlapi/ca_rotation.go
@@ -63,7 +63,6 @@
 		return nil, grpc.Errorf(codes.InvalidArgument, "rotating from one external CA to a different external CA is not supported")
 	default:
 		// We need the same credentials but to connect to the original URLs (in case we are in the middle of a root rotation already)
-		externalCA := securityConfig.ExternalCA().Copy()
 		var urls []string
 		for _, c := range extCAs {
 			if c.Protocol == api.ExternalCA_CAProtocolCFSSL {
@@ -74,7 +73,11 @@
 			return nil, grpc.Errorf(codes.InvalidArgument,
 				"must provide an external CA for the current external root CA to generate a cross-signed certificate")
 		}
-		externalCA.UpdateURLs(urls...)
+		rootPool := x509.NewCertPool()
+		rootPool.AppendCertsFromPEM(apiRootCA.CACert)
+
+		externalCAConfig := ca.NewExternalCATLSConfig(securityConfig.ClientTLSCreds.Config().Certificates, rootPool)
+		externalCA := ca.NewExternalCA(nil, externalCAConfig, urls...)
 		crossSignedCert, err = externalCA.CrossSignRootCA(ctx, newCARootCA)
 	}
 
diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go b/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go
index 7e9dea2..329313a 100644
--- a/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go
+++ b/vendor/github.com/docker/swarmkit/manager/controlapi/cluster.go
@@ -104,17 +104,14 @@
 		if cluster == nil {
 			return grpc.Errorf(codes.NotFound, "cluster %s not found", request.ClusterID)
 		}
-		// This ensures that we always have the latest security config, so our ca.SecurityConfig.RootCA and
-		// ca.SecurityConfig.externalCA objects are up-to-date with the current api.Cluster.RootCA and
-		// api.Cluster.Spec.ExternalCA objects, respectively.  Note that if, during this update, the cluster gets
-		// updated again with different CA info and the security config gets changed under us, that's still fine because
-		// this cluster update would fail anyway due to its version being too low on write.
-		if err := s.scu.UpdateRootCA(ctx, cluster); err != nil {
+		// This ensures that we have the current rootCA with which to generate tokens (expiration doesn't matter
+		// for generating the tokens)
+		rootCA, err := ca.RootCAFromAPI(ctx, &cluster.RootCA, ca.DefaultNodeCertExpiration)
+		if err != nil {
 			log.G(ctx).WithField(
-				"method", "(*controlapi.Server).UpdateCluster").WithError(err).Error("could not update security config")
-			return grpc.Errorf(codes.Internal, "could not update security config")
+				"method", "(*controlapi.Server).UpdateCluster").WithError(err).Error("invalid cluster root CA")
+			return grpc.Errorf(codes.Internal, "error loading cluster rootCA for update")
 		}
-		rootCA := s.securityConfig.RootCA()
 
 		cluster.Meta.Version = *request.ClusterVersion
 		cluster.Spec = *request.Spec.Copy()
@@ -122,10 +119,10 @@
 		expireBlacklistedCerts(cluster)
 
 		if request.Rotation.WorkerJoinToken {
-			cluster.RootCA.JoinTokens.Worker = ca.GenerateJoinToken(rootCA)
+			cluster.RootCA.JoinTokens.Worker = ca.GenerateJoinToken(&rootCA)
 		}
 		if request.Rotation.ManagerJoinToken {
-			cluster.RootCA.JoinTokens.Manager = ca.GenerateJoinToken(rootCA)
+			cluster.RootCA.JoinTokens.Manager = ca.GenerateJoinToken(&rootCA)
 		}
 
 		updatedRootCA, err := validateCAConfig(ctx, s.securityConfig, cluster)
diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/config.go b/vendor/github.com/docker/swarmkit/manager/controlapi/config.go
index 3a6f6a1..d0fe8a5 100644
--- a/vendor/github.com/docker/swarmkit/manager/controlapi/config.go
+++ b/vendor/github.com/docker/swarmkit/manager/controlapi/config.go
@@ -4,11 +4,11 @@
 	"bytes"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/identity"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/manager/state/store"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/network.go b/vendor/github.com/docker/swarmkit/manager/controlapi/network.go
index 708f36b..b150de0 100644
--- a/vendor/github.com/docker/swarmkit/manager/controlapi/network.go
+++ b/vendor/github.com/docker/swarmkit/manager/controlapi/network.go
@@ -96,11 +96,7 @@
 		return err
 	}
 
-	if err := validateIPAM(spec.IPAM, pg); err != nil {
-		return err
-	}
-
-	return nil
+	return validateIPAM(spec.IPAM, pg)
 }
 
 // CreateNetwork creates and returns a Network based on the provided NetworkSpec.
diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/secret.go b/vendor/github.com/docker/swarmkit/manager/controlapi/secret.go
index 2370814..bac4c10 100644
--- a/vendor/github.com/docker/swarmkit/manager/controlapi/secret.go
+++ b/vendor/github.com/docker/swarmkit/manager/controlapi/secret.go
@@ -4,12 +4,12 @@
 	"crypto/subtle"
 	"strings"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/validation"
 	"github.com/docker/swarmkit/identity"
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/manager/state/store"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -158,6 +158,12 @@
 		return nil, err
 	}
 
+	if request.Spec.Driver != nil { // Check that the requested driver is valid
+		if _, err := s.dr.NewSecretDriver(request.Spec.Driver); err != nil {
+			return nil, err
+		}
+	}
+
 	secret := secretFromSecretSpec(request.Spec) // the store will handle name conflicts
 	err := s.store.Update(func(tx store.Tx) error {
 		return store.CreateSecret(tx, secret)
diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/server.go b/vendor/github.com/docker/swarmkit/manager/controlapi/server.go
index c2490ba..c16e229 100644
--- a/vendor/github.com/docker/swarmkit/manager/controlapi/server.go
+++ b/vendor/github.com/docker/swarmkit/manager/controlapi/server.go
@@ -5,6 +5,7 @@
 
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/swarmkit/ca"
+	"github.com/docker/swarmkit/manager/drivers"
 	"github.com/docker/swarmkit/manager/state/raft"
 	"github.com/docker/swarmkit/manager/state/store"
 )
@@ -18,18 +19,17 @@
 	store          *store.MemoryStore
 	raft           *raft.Node
 	securityConfig *ca.SecurityConfig
-	scu            ca.APISecurityConfigUpdater
 	pg             plugingetter.PluginGetter
+	dr             *drivers.DriverProvider
 }
 
 // NewServer creates a Cluster API server.
-func NewServer(store *store.MemoryStore, raft *raft.Node, securityConfig *ca.SecurityConfig,
-	scu ca.APISecurityConfigUpdater, pg plugingetter.PluginGetter) *Server {
+func NewServer(store *store.MemoryStore, raft *raft.Node, securityConfig *ca.SecurityConfig, pg plugingetter.PluginGetter, dr *drivers.DriverProvider) *Server {
 	return &Server{
 		store:          store,
+		dr:             dr,
 		raft:           raft,
 		securityConfig: securityConfig,
-		scu:            scu,
 		pg:             pg,
 	}
 }
diff --git a/vendor/github.com/docker/swarmkit/manager/controlapi/service.go b/vendor/github.com/docker/swarmkit/manager/controlapi/service.go
index 0a0a9ff..951c27b 100644
--- a/vendor/github.com/docker/swarmkit/manager/controlapi/service.go
+++ b/vendor/github.com/docker/swarmkit/manager/controlapi/service.go
@@ -56,10 +56,7 @@
 	if err := validateResources(r.Limits); err != nil {
 		return err
 	}
-	if err := validateResources(r.Reservations); err != nil {
-		return err
-	}
-	return nil
+	return validateResources(r.Reservations)
 }
 
 func validateRestartPolicy(rp *api.RestartPolicy) error {
@@ -161,11 +158,7 @@
 		return err
 	}
 
-	if err := validateHealthCheck(container.Healthcheck); err != nil {
-		return err
-	}
-
-	return nil
+	return validateHealthCheck(container.Healthcheck)
 }
 
 // validateImage validates image name in containerSpec
@@ -481,11 +474,7 @@
 	if err := validateEndpointSpec(spec.Endpoint); err != nil {
 		return err
 	}
-	if err := validateMode(spec); err != nil {
-		return err
-	}
-
-	return nil
+	return validateMode(spec)
 }
 
 // checkPortConflicts does a best effort to find if the passed in spec has port
diff --git a/vendor/github.com/docker/swarmkit/manager/dispatcher/assignments.go b/vendor/github.com/docker/swarmkit/manager/dispatcher/assignments.go
index 3f17a6d..5a56348 100644
--- a/vendor/github.com/docker/swarmkit/manager/dispatcher/assignments.go
+++ b/vendor/github.com/docker/swarmkit/manager/dispatcher/assignments.go
@@ -3,28 +3,17 @@
 import (
 	"fmt"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/equality"
 	"github.com/docker/swarmkit/api/validation"
 	"github.com/docker/swarmkit/manager/drivers"
 	"github.com/docker/swarmkit/manager/state/store"
-)
-
-// Used as a key in tasksUsingDependency and changes. Only using the
-// ID could cause (rare) collisions between different types of
-// objects, so we also include the type of object in the key.
-type objectType int
-
-const (
-	typeTask objectType = iota
-	typeSecret
-	typeConfig
+	"github.com/sirupsen/logrus"
 )
 
 type typeAndID struct {
 	id      string
-	objType objectType
+	objType api.ResourceType
 }
 
 type assignmentSet struct {
@@ -45,39 +34,78 @@
 	}
 }
 
+func assignSecret(a *assignmentSet, readTx store.ReadTx, mapKey typeAndID, t *api.Task) {
+	a.tasksUsingDependency[mapKey] = make(map[string]struct{})
+	secret, err := a.secret(readTx, t, mapKey.id)
+	if err != nil {
+		a.log.WithFields(logrus.Fields{
+			"resource.type": "secret",
+			"secret.id":     mapKey.id,
+			"error":         err,
+		}).Debug("failed to fetch secret")
+		return
+	}
+	a.changes[mapKey] = &api.AssignmentChange{
+		Assignment: &api.Assignment{
+			Item: &api.Assignment_Secret{
+				Secret: secret,
+			},
+		},
+		Action: api.AssignmentChange_AssignmentActionUpdate,
+	}
+}
+
+func assignConfig(a *assignmentSet, readTx store.ReadTx, mapKey typeAndID) {
+	a.tasksUsingDependency[mapKey] = make(map[string]struct{})
+	config := store.GetConfig(readTx, mapKey.id)
+	if config == nil {
+		a.log.WithFields(logrus.Fields{
+			"resource.type": "config",
+			"config.id":     mapKey.id,
+		}).Debug("config not found")
+		return
+	}
+	a.changes[mapKey] = &api.AssignmentChange{
+		Assignment: &api.Assignment{
+			Item: &api.Assignment_Config{
+				Config: config,
+			},
+		},
+		Action: api.AssignmentChange_AssignmentActionUpdate,
+	}
+}
+
 func (a *assignmentSet) addTaskDependencies(readTx store.ReadTx, t *api.Task) {
+	for _, resourceRef := range t.Spec.ResourceReferences {
+		mapKey := typeAndID{objType: resourceRef.ResourceType, id: resourceRef.ResourceID}
+		if len(a.tasksUsingDependency[mapKey]) == 0 {
+			switch resourceRef.ResourceType {
+			case api.ResourceType_SECRET:
+				assignSecret(a, readTx, mapKey, t)
+			case api.ResourceType_CONFIG:
+				assignConfig(a, readTx, mapKey)
+			default:
+				a.log.WithField(
+					"resource.type", resourceRef.ResourceType,
+				).Debug("invalid resource type for a task dependency, skipping")
+				continue
+			}
+		}
+		a.tasksUsingDependency[mapKey][t.ID] = struct{}{}
+	}
+
 	var secrets []*api.SecretReference
 	container := t.Spec.GetContainer()
 	if container != nil {
 		secrets = container.Secrets
 	}
+
 	for _, secretRef := range secrets {
 		secretID := secretRef.SecretID
-		mapKey := typeAndID{objType: typeSecret, id: secretID}
+		mapKey := typeAndID{objType: api.ResourceType_SECRET, id: secretID}
 
 		if len(a.tasksUsingDependency[mapKey]) == 0 {
-			a.tasksUsingDependency[mapKey] = make(map[string]struct{})
-
-			secret, err := a.secret(readTx, secretID)
-			if err != nil {
-				a.log.WithFields(logrus.Fields{
-					"secret.id":   secretID,
-					"secret.name": secretRef.SecretName,
-					"error":       err,
-				}).Error("failed to fetch secret")
-				continue
-			}
-
-			// If the secret was found, add this secret to
-			// our set that we send down.
-			a.changes[mapKey] = &api.AssignmentChange{
-				Assignment: &api.Assignment{
-					Item: &api.Assignment_Secret{
-						Secret: secret,
-					},
-				},
-				Action: api.AssignmentChange_AssignmentActionUpdate,
-			}
+			assignSecret(a, readTx, mapKey, t)
 		}
 		a.tasksUsingDependency[mapKey][t.ID] = struct{}{}
 	}
@@ -88,30 +116,10 @@
 	}
 	for _, configRef := range configs {
 		configID := configRef.ConfigID
-		mapKey := typeAndID{objType: typeConfig, id: configID}
+		mapKey := typeAndID{objType: api.ResourceType_CONFIG, id: configID}
 
 		if len(a.tasksUsingDependency[mapKey]) == 0 {
-			a.tasksUsingDependency[mapKey] = make(map[string]struct{})
-
-			config := store.GetConfig(readTx, configID)
-			if config == nil {
-				a.log.WithFields(logrus.Fields{
-					"config.id":   configID,
-					"config.name": configRef.ConfigName,
-				}).Debug("config not found")
-				continue
-			}
-
-			// If the config was found, add this config to
-			// our set that we send down.
-			a.changes[mapKey] = &api.AssignmentChange{
-				Assignment: &api.Assignment{
-					Item: &api.Assignment_Config{
-						Config: config,
-					},
-				},
-				Action: api.AssignmentChange_AssignmentActionUpdate,
-			}
+			assignConfig(a, readTx, mapKey)
 		}
 		a.tasksUsingDependency[mapKey][t.ID] = struct{}{}
 	}
@@ -133,6 +141,35 @@
 
 func (a *assignmentSet) releaseTaskDependencies(t *api.Task) bool {
 	var modified bool
+
+	for _, resourceRef := range t.Spec.ResourceReferences {
+		var assignment *api.Assignment
+		switch resourceRef.ResourceType {
+		case api.ResourceType_SECRET:
+			assignment = &api.Assignment{
+				Item: &api.Assignment_Secret{
+					Secret: &api.Secret{ID: resourceRef.ResourceID},
+				},
+			}
+		case api.ResourceType_CONFIG:
+			assignment = &api.Assignment{
+				Item: &api.Assignment_Config{
+					Config: &api.Config{ID: resourceRef.ResourceID},
+				},
+			}
+		default:
+			a.log.WithField(
+				"resource.type", resourceRef.ResourceType,
+			).Debug("invalid resource type for a task dependency, skipping")
+			continue
+		}
+
+		mapKey := typeAndID{objType: resourceRef.ResourceType, id: resourceRef.ResourceID}
+		if a.releaseDependency(mapKey, assignment, t.ID) {
+			modified = true
+		}
+	}
+
 	container := t.Spec.GetContainer()
 
 	var secrets []*api.SecretReference
@@ -142,7 +179,7 @@
 
 	for _, secretRef := range secrets {
 		secretID := secretRef.SecretID
-		mapKey := typeAndID{objType: typeSecret, id: secretID}
+		mapKey := typeAndID{objType: api.ResourceType_SECRET, id: secretID}
 		assignment := &api.Assignment{
 			Item: &api.Assignment_Secret{
 				Secret: &api.Secret{ID: secretID},
@@ -160,7 +197,7 @@
 
 	for _, configRef := range configs {
 		configID := configRef.ConfigID
-		mapKey := typeAndID{objType: typeConfig, id: configID}
+		mapKey := typeAndID{objType: api.ResourceType_CONFIG, id: configID}
 		assignment := &api.Assignment{
 			Item: &api.Assignment_Config{
 				Config: &api.Config{ID: configID},
@@ -205,7 +242,7 @@
 		a.addTaskDependencies(readTx, t)
 	}
 	a.tasksMap[t.ID] = t
-	a.changes[typeAndID{objType: typeTask, id: t.ID}] = &api.AssignmentChange{
+	a.changes[typeAndID{objType: api.ResourceType_TASK, id: t.ID}] = &api.AssignmentChange{
 		Assignment: &api.Assignment{
 			Item: &api.Assignment_Task{
 				Task: t,
@@ -221,7 +258,7 @@
 		return false
 	}
 
-	a.changes[typeAndID{objType: typeTask, id: t.ID}] = &api.AssignmentChange{
+	a.changes[typeAndID{objType: api.ResourceType_TASK, id: t.ID}] = &api.AssignmentChange{
 		Assignment: &api.Assignment{
 			Item: &api.Assignment_Task{
 				Task: &api.Task{ID: t.ID},
@@ -254,7 +291,7 @@
 
 // secret populates the secret value from raft store. For external secrets, the value is populated
 // from the secret driver.
-func (a *assignmentSet) secret(readTx store.ReadTx, secretID string) (*api.Secret, error) {
+func (a *assignmentSet) secret(readTx store.ReadTx, task *api.Task, secretID string) (*api.Secret, error) {
 	secret := store.GetSecret(readTx, secretID)
 	if secret == nil {
 		return nil, fmt.Errorf("secret not found")
@@ -266,7 +303,7 @@
 	if err != nil {
 		return nil, err
 	}
-	value, err := d.Get(&secret.Spec)
+	value, err := d.Get(&secret.Spec, task)
 	if err != nil {
 		return nil, err
 	}
diff --git a/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go b/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go
index 8ec3ae2..4de6a30 100644
--- a/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go
+++ b/vendor/github.com/docker/swarmkit/manager/dispatcher/dispatcher.go
@@ -11,7 +11,6 @@
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/transport"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/go-events"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/equality"
@@ -19,10 +18,12 @@
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/manager/drivers"
 	"github.com/docker/swarmkit/manager/state/store"
+	"github.com/docker/swarmkit/protobuf/ptypes"
 	"github.com/docker/swarmkit/remotes"
 	"github.com/docker/swarmkit/watch"
 	gogotypes "github.com/gogo/protobuf/types"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -127,6 +128,7 @@
 	cancel               context.CancelFunc
 	clusterUpdateQueue   *watch.Queue
 	dp                   *drivers.DriverProvider
+	securityConfig       *ca.SecurityConfig
 
 	taskUpdates     map[string]*api.TaskStatus // indexed by task ID
 	taskUpdatesLock sync.Mutex
@@ -144,7 +146,7 @@
 }
 
 // New returns Dispatcher with cluster interface(usually raft.Node).
-func New(cluster Cluster, c *Config, dp *drivers.DriverProvider) *Dispatcher {
+func New(cluster Cluster, c *Config, dp *drivers.DriverProvider, securityConfig *ca.SecurityConfig) *Dispatcher {
 	d := &Dispatcher{
 		dp:                    dp,
 		nodes:                 newNodeStore(c.HeartbeatPeriod, c.HeartbeatEpsilon, c.GracePeriodMultiplier, c.RateLimitPeriod),
@@ -153,6 +155,7 @@
 		cluster:               cluster,
 		processUpdatesTrigger: make(chan struct{}, 1),
 		config:                c,
+		securityConfig:        securityConfig,
 	}
 
 	d.processUpdatesCond = sync.NewCond(&d.processUpdatesLock)
@@ -630,6 +633,8 @@
 				}
 
 				task.Status = *status
+				task.Status.AppliedBy = d.securityConfig.ClientTLSCreds.NodeID()
+				task.Status.AppliedAt = ptypes.MustTimestampProto(time.Now())
 				if err := store.UpdateTask(tx, task); err != nil {
 					logger.WithError(err).Error("failed to update task status")
 					return nil
@@ -849,10 +854,7 @@
 		appliesTo = msg.ResultsIn
 		msg.Type = assignmentType
 
-		if err := stream.Send(&msg); err != nil {
-			return err
-		}
-		return nil
+		return stream.Send(&msg)
 	}
 
 	// TODO(aaronl): Also send node secrets that should be exposed to
diff --git a/vendor/github.com/docker/swarmkit/manager/drivers/secrets.go b/vendor/github.com/docker/swarmkit/manager/drivers/secrets.go
index 9c8ccc7..2e7bc39 100644
--- a/vendor/github.com/docker/swarmkit/manager/drivers/secrets.go
+++ b/vendor/github.com/docker/swarmkit/manager/drivers/secrets.go
@@ -26,12 +26,45 @@
 }
 
 // Get gets a secret from the secret provider
-func (d *SecretDriver) Get(spec *api.SecretSpec) ([]byte, error) {
+func (d *SecretDriver) Get(spec *api.SecretSpec, task *api.Task) ([]byte, error) {
 	if spec == nil {
-		return nil, fmt.Errorf("spec is nil")
+		return nil, fmt.Errorf("secret spec is nil")
 	}
+	if task == nil {
+		return nil, fmt.Errorf("task is nil")
+	}
+
 	var secretResp SecretsProviderResponse
-	secretReq := &SecretsProviderRequest{Name: spec.Annotations.Name}
+	secretReq := &SecretsProviderRequest{
+		SecretName:    spec.Annotations.Name,
+		ServiceName:   task.ServiceAnnotations.Name,
+		ServiceLabels: task.ServiceAnnotations.Labels,
+	}
+	container := task.Spec.GetContainer()
+	if container != nil {
+		secretReq.ServiceHostname = container.Hostname
+	}
+
+	if task.Endpoint != nil && task.Endpoint.Spec != nil {
+		secretReq.ServiceEndpointSpec = &EndpointSpec{
+			Mode: int32(task.Endpoint.Spec.Mode),
+		}
+		for _, p := range task.Endpoint.Spec.Ports {
+			if p == nil {
+				continue
+			}
+			secretReq.ServiceEndpointSpec.Ports =
+				append(secretReq.ServiceEndpointSpec.Ports,
+					PortConfig{
+						Name:          p.Name,
+						Protocol:      int32(p.Protocol),
+						PublishedPort: p.PublishedPort,
+						TargetPort:    p.TargetPort,
+						PublishMode:   int32(p.PublishMode),
+					})
+		}
+	}
+
 	err := d.plugin.Client().Call(SecretsProviderAPI, secretReq, &secretResp)
 	if err != nil {
 		return nil, err
@@ -40,16 +73,38 @@
 		return nil, fmt.Errorf(secretResp.Err)
 	}
 	// Assign the secret value
-	return []byte(secretResp.Value), nil
+	return secretResp.Value, nil
 }
 
 // SecretsProviderRequest is the secrets provider request.
 type SecretsProviderRequest struct {
-	Name string `json:"name"` // Name is the name of the secret plugin
+	SecretName          string            `json:",omitempty"` // SecretName is the name of the secret to request from the plugin
+	ServiceHostname     string            `json:",omitempty"` // ServiceHostname is the hostname of the service, can be used for x509 certificate
+	ServiceName         string            `json:",omitempty"` // ServiceName is the name of the service that requested the secret
+	ServiceLabels       map[string]string `json:",omitempty"` // ServiceLabels capture environment names and other metadata
+	ServiceEndpointSpec *EndpointSpec     `json:",omitempty"` // ServiceEndpointSpec holds the specification for endpoints
 }
 
 // SecretsProviderResponse is the secrets provider response.
 type SecretsProviderResponse struct {
-	Value string `json:"value"` // Value is the value of the secret
-	Err   string `json:"err"`   // Err is the error response of the plugin
+	Value []byte `json:",omitempty"` // Value is the value of the secret
+	Err   string `json:",omitempty"` // Err is the error response of the plugin
+}
+
+// EndpointSpec represents the spec of an endpoint.
+type EndpointSpec struct {
+	Mode  int32        `json:",omitempty"`
+	Ports []PortConfig `json:",omitempty"`
+}
+
+// PortConfig represents the config of a port.
+type PortConfig struct {
+	Name     string `json:",omitempty"`
+	Protocol int32  `json:",omitempty"`
+	// TargetPort is the port inside the container
+	TargetPort uint32 `json:",omitempty"`
+	// PublishedPort is the port on the swarm hosts
+	PublishedPort uint32 `json:",omitempty"`
+	// PublishMode is the mode in which port is published
+	PublishMode int32 `json:",omitempty"`
 }
diff --git a/vendor/github.com/docker/swarmkit/manager/logbroker/broker.go b/vendor/github.com/docker/swarmkit/manager/logbroker/broker.go
index f5ec2b3..860b55c 100644
--- a/vendor/github.com/docker/swarmkit/manager/logbroker/broker.go
+++ b/vendor/github.com/docker/swarmkit/manager/logbroker/broker.go
@@ -9,7 +9,6 @@
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/go-events"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/ca"
@@ -17,6 +16,7 @@
 	"github.com/docker/swarmkit/log"
 	"github.com/docker/swarmkit/manager/state/store"
 	"github.com/docker/swarmkit/watch"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 )
 
@@ -57,12 +57,12 @@
 	}
 }
 
-// Run the log broker
-func (lb *LogBroker) Run(ctx context.Context) error {
+// Start starts the log broker
+func (lb *LogBroker) Start(ctx context.Context) error {
 	lb.mu.Lock()
+	defer lb.mu.Unlock()
 
 	if lb.cancelAll != nil {
-		lb.mu.Unlock()
 		return errAlreadyRunning
 	}
 
@@ -71,12 +71,7 @@
 	lb.subscriptionQueue = watch.NewQueue()
 	lb.registeredSubscriptions = make(map[string]*subscription)
 	lb.subscriptionsByNode = make(map[string]map[*subscription]struct{})
-	lb.mu.Unlock()
-
-	select {
-	case <-lb.pctx.Done():
-		return lb.pctx.Err()
-	}
+	return nil
 }
 
 // Stop stops the log broker
@@ -234,8 +229,15 @@
 		return err
 	}
 
+	lb.mu.Lock()
+	pctx := lb.pctx
+	lb.mu.Unlock()
+	if pctx == nil {
+		return errNotRunning
+	}
+
 	subscription := lb.newSubscription(request.Selector, request.Options)
-	subscription.Run(lb.pctx)
+	subscription.Run(pctx)
 	defer subscription.Stop()
 
 	log := log.G(ctx).WithFields(
@@ -257,8 +259,8 @@
 		select {
 		case <-ctx.Done():
 			return ctx.Err()
-		case <-lb.pctx.Done():
-			return lb.pctx.Err()
+		case <-pctx.Done():
+			return pctx.Err()
 		case event := <-publishCh:
 			publish := event.(*logMessage)
 			if publish.completed {
@@ -308,6 +310,13 @@
 		return err
 	}
 
+	lb.mu.Lock()
+	pctx := lb.pctx
+	lb.mu.Unlock()
+	if pctx == nil {
+		return errNotRunning
+	}
+
 	lb.nodeConnected(remote.NodeID)
 	defer lb.nodeDisconnected(remote.NodeID)
 
@@ -329,7 +338,7 @@
 		select {
 		case <-stream.Context().Done():
 			return stream.Context().Err()
-		case <-lb.pctx.Done():
+		case <-pctx.Done():
 			return nil
 		default:
 		}
@@ -362,7 +371,7 @@
 			}
 		case <-stream.Context().Done():
 			return stream.Context().Err()
-		case <-lb.pctx.Done():
+		case <-pctx.Done():
 			return nil
 		}
 	}
diff --git a/vendor/github.com/docker/swarmkit/manager/manager.go b/vendor/github.com/docker/swarmkit/manager/manager.go
index 4771c9d..39db22b 100644
--- a/vendor/github.com/docker/swarmkit/manager/manager.go
+++ b/vendor/github.com/docker/swarmkit/manager/manager.go
@@ -13,10 +13,10 @@
 	"syscall"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/cloudflare/cfssl/helpers"
 	"github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/go-events"
+	gmetrics "github.com/docker/go-metrics"
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/ca"
 	"github.com/docker/swarmkit/connectionbroker"
@@ -45,6 +45,7 @@
 	gogotypes "github.com/gogo/protobuf/types"
 	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
@@ -53,6 +54,9 @@
 const (
 	// defaultTaskHistoryRetentionLimit is the number of tasks to keep.
 	defaultTaskHistoryRetentionLimit = 5
+
+	// Default value for grpc max message size.
+	grpcMaxMessageSize = 128 << 20
 )
 
 // RemoteAddrs provides a listening address and an optional advertise address
@@ -87,7 +91,11 @@
 	// cluster to join.
 	JoinRaft string
 
-	// Top-level state directory
+	// ForceJoin causes us to invoke raft's Join RPC even if already part
+	// of a cluster.
+	ForceJoin bool
+
+	// StateDir is the top-level state directory
 	StateDir string
 
 	// ForceNewCluster defines if we have to force a new cluster
@@ -130,6 +138,7 @@
 	caserver               *ca.Server
 	dispatcher             *dispatcher.Dispatcher
 	logbroker              *logbroker.LogBroker
+	watchServer            *watchapi.Server
 	replicatedOrchestrator *replicated.Orchestrator
 	globalOrchestrator     *global.Orchestrator
 	taskReaper             *taskreaper.TaskReaper
@@ -159,6 +168,16 @@
 	errServe        chan error
 }
 
+var (
+	leaderMetric gmetrics.Gauge
+)
+
+func init() {
+	ns := gmetrics.NewNamespace("swarm", "manager", nil)
+	leaderMetric = ns.NewGauge("leader", "Indicates if this manager node is a leader", "")
+	gmetrics.Register(ns)
+}
+
 type closeOnceListener struct {
 	once sync.Once
 	net.Listener
@@ -202,6 +221,7 @@
 	newNodeOpts := raft.NodeOptions{
 		ID:              config.SecurityConfig.ClientTLSCreds.NodeID(),
 		JoinAddr:        config.JoinRaft,
+		ForceJoin:       config.ForceJoin,
 		Config:          raftCfg,
 		StateDir:        raftStateDir,
 		ForceNewCluster: config.ForceNewCluster,
@@ -214,13 +234,15 @@
 		grpc.Creds(config.SecurityConfig.ServerTLSCreds),
 		grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
 		grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
+		grpc.MaxMsgSize(grpcMaxMessageSize),
 	}
 
 	m := &Manager{
 		config:          *config,
-		caserver:        ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig, config.RootCAPaths),
-		dispatcher:      dispatcher.New(raftNode, dispatcher.DefaultConfig(), drivers.New(config.PluginGetter)),
+		caserver:        ca.NewServer(raftNode.MemoryStore(), config.SecurityConfig),
+		dispatcher:      dispatcher.New(raftNode, dispatcher.DefaultConfig(), drivers.New(config.PluginGetter), config.SecurityConfig),
 		logbroker:       logbroker.New(raftNode.MemoryStore()),
+		watchServer:     watchapi.NewServer(raftNode.MemoryStore()),
 		server:          grpc.NewServer(opts...),
 		localserver:     grpc.NewServer(opts...),
 		raftNode:        raftNode,
@@ -397,14 +419,13 @@
 		return err
 	}
 
-	baseControlAPI := controlapi.NewServer(m.raftNode.MemoryStore(), m.raftNode, m.config.SecurityConfig, m.caserver, m.config.PluginGetter)
-	baseWatchAPI := watchapi.NewServer(m.raftNode.MemoryStore())
+	baseControlAPI := controlapi.NewServer(m.raftNode.MemoryStore(), m.raftNode, m.config.SecurityConfig, m.config.PluginGetter, drivers.New(m.config.PluginGetter))
 	baseResourceAPI := resourceapi.New(m.raftNode.MemoryStore())
 	healthServer := health.NewHealthServer()
 	localHealthServer := health.NewHealthServer()
 
 	authenticatedControlAPI := api.NewAuthenticatedWrapperControlServer(baseControlAPI, authorize)
-	authenticatedWatchAPI := api.NewAuthenticatedWrapperWatchServer(baseWatchAPI, authorize)
+	authenticatedWatchAPI := api.NewAuthenticatedWrapperWatchServer(m.watchServer, authorize)
 	authenticatedResourceAPI := api.NewAuthenticatedWrapperResourceAllocatorServer(baseResourceAPI, authorize)
 	authenticatedLogsServerAPI := api.NewAuthenticatedWrapperLogsServer(m.logbroker, authorize)
 	authenticatedLogBrokerAPI := api.NewAuthenticatedWrapperLogBrokerServer(m.logbroker, authorize)
@@ -477,7 +498,7 @@
 	grpc_prometheus.Register(m.server)
 
 	api.RegisterControlServer(m.localserver, localProxyControlAPI)
-	api.RegisterWatchServer(m.localserver, baseWatchAPI)
+	api.RegisterWatchServer(m.localserver, m.watchServer)
 	api.RegisterLogsServer(m.localserver, localProxyLogsAPI)
 	api.RegisterHealthServer(m.localserver, localHealthServer)
 	api.RegisterDispatcherServer(m.localserver, localProxyDispatcherAPI)
@@ -490,6 +511,10 @@
 	healthServer.SetServingStatus("Raft", api.HealthCheckResponse_NOT_SERVING)
 	localHealthServer.SetServingStatus("ControlAPI", api.HealthCheckResponse_NOT_SERVING)
 
+	if err := m.watchServer.Start(ctx); err != nil {
+		log.G(ctx).WithError(err).Error("watch server failed to start")
+	}
+
 	go m.serveListener(ctx, m.remoteListener)
 	go m.serveListener(ctx, m.controlListener)
 
@@ -565,8 +590,8 @@
 const stopTimeout = 8 * time.Second
 
 // Stop stops the manager. It immediately closes all open connections and
-// active RPCs as well as stopping the scheduler. If clearData is set, the
-// raft logs, snapshots, and keys will be erased.
+// active RPCs as well as stopping the manager's subsystems. If clearData is
+// set, the raft logs, snapshots, and keys will be erased.
 func (m *Manager) Stop(ctx context.Context, clearData bool) {
 	log.G(ctx).Info("Stopping manager")
 	// It's not safe to start shutting down while the manager is still
@@ -600,6 +625,7 @@
 
 	m.dispatcher.Stop()
 	m.logbroker.Stop()
+	m.watchServer.Stop()
 	m.caserver.Stop()
 
 	if m.allocator != nil {
@@ -709,16 +735,14 @@
 
 func (m *Manager) watchForClusterChanges(ctx context.Context) error {
 	clusterID := m.config.SecurityConfig.ClientTLSCreds.Organization()
+	var cluster *api.Cluster
 	clusterWatch, clusterWatchCancel, err := store.ViewAndWatch(m.raftNode.MemoryStore(),
 		func(tx store.ReadTx) error {
-			cluster := store.GetCluster(tx, clusterID)
+			cluster = store.GetCluster(tx, clusterID)
 			if cluster == nil {
 				return fmt.Errorf("unable to get current cluster")
 			}
-			if err := m.caserver.UpdateRootCA(ctx, cluster); err != nil {
-				log.G(ctx).WithError(err).Error("could not update security config")
-			}
-			return m.updateKEK(ctx, cluster)
+			return nil
 		},
 		api.EventUpdateCluster{
 			Cluster: &api.Cluster{ID: clusterID},
@@ -728,14 +752,15 @@
 	if err != nil {
 		return err
 	}
+	if err := m.updateKEK(ctx, cluster); err != nil {
+		return err
+	}
+
 	go func() {
 		for {
 			select {
 			case event := <-clusterWatch:
 				clusterEvent := event.(api.EventUpdateCluster)
-				if err := m.caserver.UpdateRootCA(ctx, clusterEvent.Cluster); err != nil {
-					log.G(ctx).WithError(err).Error("could not update security config")
-				}
 				m.updateKEK(ctx, clusterEvent.Cluster)
 			case <-ctx.Done():
 				clusterWatchCancel()
@@ -863,8 +888,10 @@
 
 			if newState == raft.IsLeader {
 				m.becomeLeader(ctx)
+				leaderMetric.Set(1)
 			} else if newState == raft.IsFollower {
 				m.becomeFollower()
+				leaderMetric.Set(0)
 			}
 			m.mu.Unlock()
 		case <-ctx.Done():
@@ -1001,11 +1028,9 @@
 		}
 	}(m.dispatcher)
 
-	go func(lb *logbroker.LogBroker) {
-		if err := lb.Run(ctx); err != nil {
-			log.G(ctx).WithError(err).Error("LogBroker exited with an error")
-		}
-	}(m.logbroker)
+	if err := m.logbroker.Start(ctx); err != nil {
+		log.G(ctx).WithError(err).Error("LogBroker failed to start")
+	}
 
 	go func(server *ca.Server) {
 		if err := server.Run(ctx); err != nil {
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/global/global.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/global/global.go
index b89a105..a1d2873 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/global/global.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/global/global.go
@@ -156,25 +156,12 @@
 				g.reconcileOneNode(ctx, v.Node)
 			case api.EventUpdateNode:
 				g.updateNode(v.Node)
-				switch v.Node.Status.State {
-				// NodeStatus_DISCONNECTED is a transient state, no need to make any change
-				case api.NodeStatus_DOWN:
-					g.foreachTaskFromNode(ctx, v.Node, g.shutdownTask)
-				case api.NodeStatus_READY:
-					// node could come back to READY from DOWN or DISCONNECT
-					g.reconcileOneNode(ctx, v.Node)
-				}
+				g.reconcileOneNode(ctx, v.Node)
 			case api.EventDeleteNode:
 				g.foreachTaskFromNode(ctx, v.Node, g.deleteTask)
 				delete(g.nodes, v.Node.ID)
 			case api.EventUpdateTask:
 				g.handleTaskChange(ctx, v.Task)
-			case api.EventDeleteTask:
-				// CLI allows deleting task
-				if _, exists := g.globalServices[v.Task.ServiceID]; !exists {
-					continue
-				}
-				g.reconcileServicesOneNode(ctx, []string{v.Task.ServiceID}, v.Task.NodeID)
 			}
 		case <-g.stopChan:
 			return nil
@@ -216,7 +203,7 @@
 	if _, exists := g.globalServices[t.ServiceID]; !exists {
 		return
 	}
-	// if a task's DesiredState has past running, which
+	// if a task's DesiredState has passed running, it
 	// means the task has been processed
 	if t.DesiredState > api.TaskStateRunning {
 		return
@@ -264,33 +251,41 @@
 }
 
 func (g *Orchestrator) reconcileServices(ctx context.Context, serviceIDs []string) {
-	nodeCompleted := make(map[string]map[string]struct{})
 	nodeTasks := make(map[string]map[string][]*api.Task)
 
 	g.store.View(func(tx store.ReadTx) {
 		for _, serviceID := range serviceIDs {
+			service := g.globalServices[serviceID].Service
+			if service == nil {
+				continue
+			}
+
 			tasks, err := store.FindTasks(tx, store.ByServiceID(serviceID))
 			if err != nil {
 				log.G(ctx).WithError(err).Errorf("global orchestrator: reconcileServices failed finding tasks for service %s", serviceID)
 				continue
 			}
 
-			// a node may have completed this service
-			nodeCompleted[serviceID] = make(map[string]struct{})
 			// nodeID -> task list
 			nodeTasks[serviceID] = make(map[string][]*api.Task)
 
 			for _, t := range tasks {
-				if t.DesiredState <= api.TaskStateRunning {
-					// Collect all running instances of this service
-					nodeTasks[serviceID][t.NodeID] = append(nodeTasks[serviceID][t.NodeID], t)
+				nodeTasks[serviceID][t.NodeID] = append(nodeTasks[serviceID][t.NodeID], t)
+			}
+
+			// Keep all runnable instances of this service,
+			// and instances that were not be restarted due
+			// to restart policy but may be updated if the
+			// service spec changed.
+			for nodeID, slot := range nodeTasks[serviceID] {
+				updatable := g.restarts.UpdatableTasksInSlot(ctx, slot, g.globalServices[serviceID].Service)
+				if len(updatable) != 0 {
+					nodeTasks[serviceID][nodeID] = updatable
 				} else {
-					// for finished tasks, check restartPolicy
-					if isTaskCompleted(t, orchestrator.RestartCondition(t)) {
-						nodeCompleted[serviceID][t.NodeID] = struct{}{}
-					}
+					delete(nodeTasks[serviceID], nodeID)
 				}
 			}
+
 		}
 	})
 
@@ -311,9 +306,7 @@
 				ntasks := nodeTasks[serviceID][nodeID]
 				delete(nodeTasks[serviceID], nodeID)
 
-				// if restart policy considers this node has finished its task
-				// it should remove all running tasks
-				if _, exists := nodeCompleted[serviceID][nodeID]; exists || !meetsConstraints {
+				if !meetsConstraints {
 					g.shutdownTasks(ctx, batch, ntasks)
 					continue
 				}
@@ -357,7 +350,7 @@
 
 // updateNode updates g.nodes based on the current node value
 func (g *Orchestrator) updateNode(node *api.Node) {
-	if node.Spec.Availability == api.NodeAvailabilityDrain {
+	if node.Spec.Availability == api.NodeAvailabilityDrain || node.Status.State == api.NodeStatus_DOWN {
 		delete(g.nodes, node.ID)
 	} else {
 		g.nodes[node.ID] = node
@@ -381,27 +374,27 @@
 // reconcileOneNode checks all global services on one node
 func (g *Orchestrator) reconcileOneNode(ctx context.Context, node *api.Node) {
 	if node.Spec.Availability == api.NodeAvailabilityDrain {
-		log.G(ctx).Debugf("global orchestrator: node %s in drain state, removing tasks from it", node.ID)
+		log.G(ctx).Debugf("global orchestrator: node %s in drain state, shutting down its tasks", node.ID)
 		g.foreachTaskFromNode(ctx, node, g.shutdownTask)
 		return
 	}
 
-	var serviceIDs []string
-	for id := range g.globalServices {
-		serviceIDs = append(serviceIDs, id)
+	if node.Status.State == api.NodeStatus_DOWN {
+		log.G(ctx).Debugf("global orchestrator: node %s is down, shutting down its tasks", node.ID)
+		g.foreachTaskFromNode(ctx, node, g.shutdownTask)
+		return
 	}
-	g.reconcileServicesOneNode(ctx, serviceIDs, node.ID)
-}
 
-// reconcileServicesOneNode checks the specified services on one node
-func (g *Orchestrator) reconcileServicesOneNode(ctx context.Context, serviceIDs []string, nodeID string) {
-	node, exists := g.nodes[nodeID]
+	if node.Spec.Availability == api.NodeAvailabilityPause {
+		// the node is paused, so we won't add or update tasks
+		return
+	}
+
+	node, exists := g.nodes[node.ID]
 	if !exists {
 		return
 	}
 
-	// whether each service has completed on the node
-	completed := make(map[string]bool)
 	// tasks by service
 	tasks := make(map[string][]*api.Task)
 
@@ -411,53 +404,44 @@
 	)
 
 	g.store.View(func(tx store.ReadTx) {
-		tasksOnNode, err = store.FindTasks(tx, store.ByNodeID(nodeID))
+		tasksOnNode, err = store.FindTasks(tx, store.ByNodeID(node.ID))
 	})
 	if err != nil {
-		log.G(ctx).WithError(err).Errorf("global orchestrator: reconcile failed finding tasks on node %s", nodeID)
+		log.G(ctx).WithError(err).Errorf("global orchestrator: reconcile failed finding tasks on node %s", node.ID)
 		return
 	}
 
-	for _, serviceID := range serviceIDs {
+	for serviceID, service := range g.globalServices {
 		for _, t := range tasksOnNode {
 			if t.ServiceID != serviceID {
 				continue
 			}
-			if t.DesiredState <= api.TaskStateRunning {
-				tasks[serviceID] = append(tasks[serviceID], t)
+			tasks[serviceID] = append(tasks[serviceID], t)
+		}
+
+		// Keep all runnable instances of this service,
+		// and instances that were not be restarted due
+		// to restart policy but may be updated if the
+		// service spec changed.
+		for serviceID, slot := range tasks {
+			updatable := g.restarts.UpdatableTasksInSlot(ctx, slot, service.Service)
+
+			if len(updatable) != 0 {
+				tasks[serviceID] = updatable
 			} else {
-				if isTaskCompleted(t, orchestrator.RestartCondition(t)) {
-					completed[serviceID] = true
-				}
+				delete(tasks, serviceID)
 			}
 		}
 	}
 
 	err = g.store.Batch(func(batch *store.Batch) error {
-		for _, serviceID := range serviceIDs {
-			service, exists := g.globalServices[serviceID]
-			if !exists {
-				continue
-			}
-
+		for serviceID, service := range g.globalServices {
 			if !constraint.NodeMatches(service.constraints, node) {
 				continue
 			}
 
-			// if restart policy considers this node has finished its task
-			// it should remove all running tasks
-			if completed[serviceID] {
-				g.shutdownTasks(ctx, batch, tasks[serviceID])
-				continue
-			}
-
-			if node.Spec.Availability == api.NodeAvailabilityPause {
-				// the node is paused, so we won't add or update tasks
-				continue
-			}
-
 			if len(tasks) == 0 {
-				g.addTask(ctx, batch, service.Service, nodeID)
+				g.addTask(ctx, batch, service.Service, node.ID)
 			} else {
 				// If task is out of date, update it. This can happen
 				// on node reconciliation if, for example, we pause a
@@ -487,7 +471,7 @@
 				}
 
 				if len(cleanTasks) == 0 {
-					g.addTask(ctx, batch, service.Service, nodeID)
+					g.addTask(ctx, batch, service.Service, node.ID)
 				} else {
 					dirtyTasks = append(dirtyTasks, cleanTasks[1:]...)
 				}
@@ -523,7 +507,9 @@
 				if !nodeExists || !serviceExists {
 					return nil
 				}
-				if !constraint.NodeMatches(serviceEntry.constraints, node) {
+
+				if node.Spec.Availability == api.NodeAvailabilityPause ||
+					!constraint.NodeMatches(serviceEntry.constraints, node) {
 					t.DesiredState = api.TaskStateShutdown
 					return store.UpdateTask(tx, t)
 				}
@@ -592,6 +578,14 @@
 	return orchestrator.IsGlobalService(service)
 }
 
+// SlotTuple returns a slot tuple for the global service task.
+func (g *Orchestrator) SlotTuple(t *api.Task) orchestrator.SlotTuple {
+	return orchestrator.SlotTuple{
+		ServiceID: t.ServiceID,
+		NodeID:    t.NodeID,
+	}
+}
+
 func isTaskCompleted(t *api.Task, restartPolicy api.RestartPolicy_RestartCondition) bool {
 	if t == nil || t.DesiredState <= api.TaskStateRunning {
 		return false
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/services.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/services.go
index 101976d..f4d0511 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/services.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/services.go
@@ -87,7 +87,7 @@
 }
 
 func (r *Orchestrator) reconcile(ctx context.Context, service *api.Service) {
-	runningSlots, deadSlots, err := orchestrator.GetRunnableAndDeadSlots(r.store, service.ID)
+	runningSlots, deadSlots, err := r.updatableAndDeadSlots(ctx, service)
 	if err != nil {
 		log.G(ctx).WithError(err).Errorf("reconcile failed finding tasks")
 		return
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/slot.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/slot.go
index 1f1fd3e..bdc25d9 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/slot.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/replicated/slot.go
@@ -3,6 +3,8 @@
 import (
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/manager/orchestrator"
+	"github.com/docker/swarmkit/manager/state/store"
+	"golang.org/x/net/context"
 )
 
 type slotsByRunningState []orchestrator.Slot
@@ -53,3 +55,46 @@
 	}
 	return is[i].index < is[j].index
 }
+
+// updatableAndDeadSlots returns two maps of slots. The first contains slots
+// that have at least one task with a desired state above NEW and lesser or
+// equal to RUNNING, or a task that shouldn't be restarted. The second contains
+// all other slots with at least one task.
+func (r *Orchestrator) updatableAndDeadSlots(ctx context.Context, service *api.Service) (map[uint64]orchestrator.Slot, map[uint64]orchestrator.Slot, error) {
+	var (
+		tasks []*api.Task
+		err   error
+	)
+	r.store.View(func(tx store.ReadTx) {
+		tasks, err = store.FindTasks(tx, store.ByServiceID(service.ID))
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	updatableSlots := make(map[uint64]orchestrator.Slot)
+	for _, t := range tasks {
+		updatableSlots[t.Slot] = append(updatableSlots[t.Slot], t)
+	}
+
+	deadSlots := make(map[uint64]orchestrator.Slot)
+	for slotID, slot := range updatableSlots {
+		updatable := r.restarts.UpdatableTasksInSlot(ctx, slot, service)
+		if len(updatable) != 0 {
+			updatableSlots[slotID] = updatable
+		} else {
+			delete(updatableSlots, slotID)
+			deadSlots[slotID] = slot
+		}
+	}
+
+	return updatableSlots, deadSlots, nil
+}
+
+// SlotTuple returns a slot tuple for the replicated service task.
+func (r *Orchestrator) SlotTuple(t *api.Task) orchestrator.SlotTuple {
+	return orchestrator.SlotTuple{
+		ServiceID: t.ServiceID,
+		Slot:      t.Slot,
+	}
+}
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/restart/restart.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/restart/restart.go
index 6167552..6af44b7 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/restart/restart.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/restart/restart.go
@@ -30,6 +30,13 @@
 	// Restart.MaxAttempts and Restart.Window are both
 	// nonzero.
 	restartedInstances *list.List
+	// Why is specVersion in this structure and not in the map key? While
+	// putting it in the key would be a very simple solution, it wouldn't
+	// be easy to clean up map entries corresponding to old specVersions.
+	// Making the key version-agnostic and clearing the value whenever the
+	// version changes avoids the issue of stale map entries for old
+	// versions.
+	specVersion api.Version
 }
 
 type delayedStart struct {
@@ -42,20 +49,13 @@
 	waiter bool
 }
 
-type instanceTuple struct {
-	instance  uint64 // unset for global tasks
-	serviceID string
-	nodeID    string // unset for replicated tasks
-}
-
 // Supervisor initiates and manages restarts. It's responsible for
 // delaying restarts when applicable.
 type Supervisor struct {
 	mu               sync.Mutex
 	store            *store.MemoryStore
 	delays           map[string]*delayedStart
-	history          map[instanceTuple]*instanceRestartInfo
-	historyByService map[string]map[instanceTuple]struct{}
+	historyByService map[string]map[orchestrator.SlotTuple]*instanceRestartInfo
 	TaskTimeout      time.Duration
 }
 
@@ -64,8 +64,7 @@
 	return &Supervisor{
 		store:            store,
 		delays:           make(map[string]*delayedStart),
-		history:          make(map[instanceTuple]*instanceRestartInfo),
-		historyByService: make(map[string]map[instanceTuple]struct{}),
+		historyByService: make(map[string]map[orchestrator.SlotTuple]*instanceRestartInfo),
 		TaskTimeout:      defaultOldTaskTimeout,
 	}
 }
@@ -180,15 +179,21 @@
 		return err
 	}
 
-	r.recordRestartHistory(restartTask)
+	tuple := orchestrator.SlotTuple{
+		Slot:      restartTask.Slot,
+		ServiceID: restartTask.ServiceID,
+		NodeID:    restartTask.NodeID,
+	}
+	r.RecordRestartHistory(tuple, restartTask)
 
 	r.DelayStart(ctx, tx, &t, restartTask.ID, restartDelay, waitStop)
 	return nil
 }
 
+// shouldRestart returns true if a task should be restarted according to the
+// restart policy.
 func (r *Supervisor) shouldRestart(ctx context.Context, t *api.Task, service *api.Service) bool {
 	// TODO(aluzzardi): This function should not depend on `service`.
-
 	condition := orchestrator.RestartCondition(t)
 
 	if condition != api.RestartOnAny &&
@@ -200,22 +205,22 @@
 		return true
 	}
 
-	instanceTuple := instanceTuple{
-		instance:  t.Slot,
-		serviceID: t.ServiceID,
+	instanceTuple := orchestrator.SlotTuple{
+		Slot:      t.Slot,
+		ServiceID: t.ServiceID,
 	}
 
-	// Instance is not meaningful for "global" tasks, so they need to be
+	// Slot is not meaningful for "global" tasks, so they need to be
 	// indexed by NodeID.
 	if orchestrator.IsGlobalService(service) {
-		instanceTuple.nodeID = t.NodeID
+		instanceTuple.NodeID = t.NodeID
 	}
 
 	r.mu.Lock()
 	defer r.mu.Unlock()
 
-	restartInfo := r.history[instanceTuple]
-	if restartInfo == nil {
+	restartInfo := r.historyByService[t.ServiceID][instanceTuple]
+	if restartInfo == nil || (t.SpecVersion != nil && *t.SpecVersion != restartInfo.specVersion) {
 		return true
 	}
 
@@ -232,8 +237,32 @@
 		log.G(ctx).WithError(err).Error("invalid restart lookback window")
 		return restartInfo.totalRestarts < t.Spec.Restart.MaxAttempts
 	}
-	lookback := time.Now().Add(-window)
 
+	var timestamp time.Time
+	// Prefer the manager's timestamp over the agent's, since manager
+	// clocks are more trustworthy.
+	if t.Status.AppliedAt != nil {
+		timestamp, err = gogotypes.TimestampFromProto(t.Status.AppliedAt)
+		if err != nil {
+			log.G(ctx).WithError(err).Error("invalid task status AppliedAt timestamp")
+			return restartInfo.totalRestarts < t.Spec.Restart.MaxAttempts
+		}
+	} else {
+		// It's safe to call TimestampFromProto with a nil timestamp
+		timestamp, err = gogotypes.TimestampFromProto(t.Status.Timestamp)
+		if t.Status.Timestamp == nil || err != nil {
+			log.G(ctx).WithError(err).Error("invalid task completion timestamp")
+			return restartInfo.totalRestarts < t.Spec.Restart.MaxAttempts
+		}
+	}
+	lookback := timestamp.Add(-window)
+
+	numRestarts := uint64(restartInfo.restartedInstances.Len())
+
+	// Disregard any restarts that happened before the lookback window,
+	// and remove them from the linked list since they will no longer
+	// be relevant to figuring out if tasks should be restarted going
+	// forward.
 	var next *list.Element
 	for e := restartInfo.restartedInstances.Front(); e != nil; e = next {
 		next = e.Next()
@@ -242,51 +271,115 @@
 			break
 		}
 		restartInfo.restartedInstances.Remove(e)
+		numRestarts--
 	}
 
-	numRestarts := uint64(restartInfo.restartedInstances.Len())
+	// Ignore restarts that didn't happen before the task we're looking at.
+	for e2 := restartInfo.restartedInstances.Back(); e2 != nil; e2 = e2.Prev() {
+		if e2.Value.(restartedInstance).timestamp.Before(timestamp) {
+			break
+		}
+		numRestarts--
+	}
 
-	if numRestarts == 0 {
+	if restartInfo.restartedInstances.Len() == 0 {
 		restartInfo.restartedInstances = nil
 	}
 
 	return numRestarts < t.Spec.Restart.MaxAttempts
 }
 
-func (r *Supervisor) recordRestartHistory(restartTask *api.Task) {
-	if restartTask.Spec.Restart == nil || restartTask.Spec.Restart.MaxAttempts == 0 {
+// UpdatableTasksInSlot returns the set of tasks that should be passed to the
+// updater from this slot, or an empty slice if none should be.  An updatable
+// slot has either at least one task that with desired state <= RUNNING, or its
+// most recent task has stopped running and should not be restarted. The latter
+// case is for making sure that tasks that shouldn't normally be restarted will
+// still be handled by rolling updates when they become outdated.  There is a
+// special case for rollbacks to make sure that a rollback always takes the
+// service to a converged state, instead of ignoring tasks with the original
+// spec that stopped running and shouldn't be restarted according to the
+// restart policy.
+func (r *Supervisor) UpdatableTasksInSlot(ctx context.Context, slot orchestrator.Slot, service *api.Service) orchestrator.Slot {
+	if len(slot) < 1 {
+		return nil
+	}
+
+	var updatable orchestrator.Slot
+	for _, t := range slot {
+		if t.DesiredState <= api.TaskStateRunning {
+			updatable = append(updatable, t)
+		}
+	}
+	if len(updatable) > 0 {
+		return updatable
+	}
+
+	if service.UpdateStatus != nil && service.UpdateStatus.State == api.UpdateStatus_ROLLBACK_STARTED {
+		return nil
+	}
+
+	// Find most recent task
+	byTimestamp := orchestrator.TasksByTimestamp(slot)
+	newestIndex := 0
+	for i := 1; i != len(slot); i++ {
+		if byTimestamp.Less(newestIndex, i) {
+			newestIndex = i
+		}
+	}
+
+	if !r.shouldRestart(ctx, slot[newestIndex], service) {
+		return orchestrator.Slot{slot[newestIndex]}
+	}
+	return nil
+}
+
+// RecordRestartHistory updates the historyByService map to reflect the restart
+// of restartedTask.
+func (r *Supervisor) RecordRestartHistory(tuple orchestrator.SlotTuple, replacementTask *api.Task) {
+	if replacementTask.Spec.Restart == nil || replacementTask.Spec.Restart.MaxAttempts == 0 {
 		// No limit on the number of restarts, so no need to record
 		// history.
 		return
 	}
-	tuple := instanceTuple{
-		instance:  restartTask.Slot,
-		serviceID: restartTask.ServiceID,
-		nodeID:    restartTask.NodeID,
-	}
 
 	r.mu.Lock()
 	defer r.mu.Unlock()
 
-	if r.history[tuple] == nil {
-		r.history[tuple] = &instanceRestartInfo{}
+	serviceID := replacementTask.ServiceID
+	if r.historyByService[serviceID] == nil {
+		r.historyByService[serviceID] = make(map[orchestrator.SlotTuple]*instanceRestartInfo)
+	}
+	if r.historyByService[serviceID][tuple] == nil {
+		r.historyByService[serviceID][tuple] = &instanceRestartInfo{}
 	}
 
-	restartInfo := r.history[tuple]
+	restartInfo := r.historyByService[serviceID][tuple]
+
+	if replacementTask.SpecVersion != nil && *replacementTask.SpecVersion != restartInfo.specVersion {
+		// This task has a different SpecVersion from the one we're
+		// tracking. Most likely, the service was updated. Past failures
+		// shouldn't count against the new service definition, so clear
+		// the history for this instance.
+		*restartInfo = instanceRestartInfo{
+			specVersion: *replacementTask.SpecVersion,
+		}
+	}
+
 	restartInfo.totalRestarts++
 
-	if r.historyByService[restartTask.ServiceID] == nil {
-		r.historyByService[restartTask.ServiceID] = make(map[instanceTuple]struct{})
-	}
-	r.historyByService[restartTask.ServiceID][tuple] = struct{}{}
-
-	if restartTask.Spec.Restart.Window != nil && (restartTask.Spec.Restart.Window.Seconds != 0 || restartTask.Spec.Restart.Window.Nanos != 0) {
+	if replacementTask.Spec.Restart.Window != nil && (replacementTask.Spec.Restart.Window.Seconds != 0 || replacementTask.Spec.Restart.Window.Nanos != 0) {
 		if restartInfo.restartedInstances == nil {
 			restartInfo.restartedInstances = list.New()
 		}
 
+		// it's okay to call TimestampFromProto with a nil argument
+		timestamp, err := gogotypes.TimestampFromProto(replacementTask.Meta.CreatedAt)
+		if replacementTask.Meta.CreatedAt == nil || err != nil {
+			timestamp = time.Now()
+		}
+
 		restartedInstance := restartedInstance{
-			timestamp: time.Now(),
+			timestamp: timestamp,
 		}
 
 		restartInfo.restartedInstances.PushBack(restartedInstance)
@@ -323,7 +416,9 @@
 	var watch chan events.Event
 	cancelWatch := func() {}
 
-	if waitStop && oldTask != nil {
+	waitForTask := waitStop && oldTask != nil && oldTask.Status.State <= api.TaskStateRunning
+
+	if waitForTask {
 		// Wait for either the old task to complete, or the old task's
 		// node to become unavailable.
 		watch, cancelWatch = state.Watch(
@@ -364,7 +459,7 @@
 			}
 		}
 
-		if waitStop && oldTask != nil {
+		if waitForTask {
 			select {
 			case <-watch:
 			case <-oldTaskTimer.C:
@@ -432,16 +527,6 @@
 // ClearServiceHistory forgets restart history related to a given service ID.
 func (r *Supervisor) ClearServiceHistory(serviceID string) {
 	r.mu.Lock()
-	defer r.mu.Unlock()
-
-	tuples := r.historyByService[serviceID]
-	if tuples == nil {
-		return
-	}
-
 	delete(r.historyByService, serviceID)
-
-	for t := range tuples {
-		delete(r.history, t)
-	}
+	r.mu.Unlock()
 }
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/slot.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/slot.go
index ce34713..7839a75 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/slot.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/slot.go
@@ -2,7 +2,6 @@
 
 import (
 	"github.com/docker/swarmkit/api"
-	"github.com/docker/swarmkit/manager/state/store"
 )
 
 // Slot is a list of the running tasks occupying a certain slot. Generally this
@@ -12,35 +11,11 @@
 // is also considered a slot for global services.
 type Slot []*api.Task
 
-// GetRunnableAndDeadSlots returns two maps of slots. The first contains slots
-// that have at least one task with a desired state above NEW and lesser or
-// equal to RUNNING. The second is for slots that only contain tasks with a
-// desired state above RUNNING.
-func GetRunnableAndDeadSlots(s *store.MemoryStore, serviceID string) (map[uint64]Slot, map[uint64]Slot, error) {
-	var (
-		tasks []*api.Task
-		err   error
-	)
-	s.View(func(tx store.ReadTx) {
-		tasks, err = store.FindTasks(tx, store.ByServiceID(serviceID))
-	})
-	if err != nil {
-		return nil, nil, err
-	}
-
-	runningSlots := make(map[uint64]Slot)
-	for _, t := range tasks {
-		if t.DesiredState <= api.TaskStateRunning {
-			runningSlots[t.Slot] = append(runningSlots[t.Slot], t)
-		}
-	}
-
-	deadSlots := make(map[uint64]Slot)
-	for _, t := range tasks {
-		if _, exists := runningSlots[t.Slot]; !exists {
-			deadSlots[t.Slot] = append(deadSlots[t.Slot], t)
-		}
-	}
-
-	return runningSlots, deadSlots, nil
+// SlotTuple identifies a unique slot, in the broad sense described above. It's
+// a combination of either a service ID and a slot number (replicated services),
+// or a service ID and a node ID (global services).
+type SlotTuple struct {
+	Slot      uint64 // unset for global service tasks
+	ServiceID string
+	NodeID    string // unset for replicated service tasks
 }
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go
index 32a22d5..ebfeee2 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/task.go
@@ -67,7 +67,29 @@
 		return false
 	}
 
-	return !reflect.DeepEqual(s.Spec.Task, t.Spec) ||
+	// Make a deep copy of the service and task spec for the comparison.
+	serviceTaskSpec := *s.Spec.Task.Copy()
+
+	// For non-failed tasks with a container spec runtime that have already
+	// pulled the required image (i.e., current state is between READY and
+	// RUNNING inclusively), ignore the value of the `PullOptions` field by
+	// setting the copied service to have the same PullOptions value as the
+	// task. A difference in only the `PullOptions` field should not cause
+	// a running (or ready to run) task to be considered 'dirty' when we
+	// handle updates.
+	// See https://github.com/docker/swarmkit/issues/971
+	currentState := t.Status.State
+	// Ignore PullOpts if the task is desired to be in a "runnable" state
+	// and its last known current state is between READY and RUNNING in
+	// which case we know that the task either successfully pulled its
+	// container image or didn't need to.
+	ignorePullOpts := t.DesiredState <= api.TaskStateRunning && currentState >= api.TaskStateReady && currentState <= api.TaskStateRunning
+	if ignorePullOpts && serviceTaskSpec.GetContainer() != nil && t.Spec.GetContainer() != nil {
+		// Modify the service's container spec.
+		serviceTaskSpec.GetContainer().PullOptions = t.Spec.GetContainer().PullOptions
+	}
+
+	return !reflect.DeepEqual(serviceTaskSpec, t.Spec) ||
 		(t.Endpoint != nil && !reflect.DeepEqual(s.Spec.Endpoint, t.Endpoint.Spec))
 }
 
@@ -77,3 +99,44 @@
 		n.Status.State == api.NodeStatus_DOWN ||
 		n.Spec.Availability == api.NodeAvailabilityDrain
 }
+
+// TasksByTimestamp sorts tasks by applied timestamp if available, otherwise
+// status timestamp.
+type TasksByTimestamp []*api.Task
+
+// Len implements the Len method for sorting.
+func (t TasksByTimestamp) Len() int {
+	return len(t)
+}
+
+// Swap implements the Swap method for sorting.
+func (t TasksByTimestamp) Swap(i, j int) {
+	t[i], t[j] = t[j], t[i]
+}
+
+// Less implements the Less method for sorting.
+func (t TasksByTimestamp) Less(i, j int) bool {
+	iTimestamp := t[i].Status.Timestamp
+	if t[i].Status.AppliedAt != nil {
+		iTimestamp = t[i].Status.AppliedAt
+	}
+
+	jTimestamp := t[j].Status.Timestamp
+	if t[j].Status.AppliedAt != nil {
+		iTimestamp = t[j].Status.AppliedAt
+	}
+
+	if iTimestamp == nil {
+		return true
+	}
+	if jTimestamp == nil {
+		return false
+	}
+	if iTimestamp.Seconds < jTimestamp.Seconds {
+		return true
+	}
+	if iTimestamp.Seconds > jTimestamp.Seconds {
+		return false
+	}
+	return iTimestamp.Nanos < jTimestamp.Nanos
+}
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go
index 33558a4..b893428 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/taskinit/init.go
@@ -1,11 +1,13 @@
 package taskinit
 
 import (
+	"sort"
 	"time"
 
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/api/defaults"
 	"github.com/docker/swarmkit/log"
+	"github.com/docker/swarmkit/manager/orchestrator"
 	"github.com/docker/swarmkit/manager/orchestrator/restart"
 	"github.com/docker/swarmkit/manager/state/store"
 	gogotypes "github.com/gogo/protobuf/types"
@@ -16,11 +18,13 @@
 type InitHandler interface {
 	IsRelatedService(service *api.Service) bool
 	FixTask(ctx context.Context, batch *store.Batch, t *api.Task)
+	SlotTuple(t *api.Task) orchestrator.SlotTuple
 }
 
 // CheckTasks fixes tasks in the store before orchestrator runs. The previous leader might
 // not have finished processing their updates and left them in an inconsistent state.
 func CheckTasks(ctx context.Context, s *store.MemoryStore, readTx store.ReadTx, initHandler InitHandler, startSupervisor *restart.Supervisor) error {
+	instances := make(map[orchestrator.SlotTuple][]*api.Task)
 	err := s.Batch(func(batch *store.Batch) error {
 		tasks, err := store.FindTasks(readTx, store.All)
 		if err != nil {
@@ -47,6 +51,9 @@
 				continue
 			}
 
+			tuple := initHandler.SlotTuple(t)
+			instances[tuple] = append(instances[tuple], t)
+
 			// handle task updates from agent which should have been triggered by task update events
 			initHandler.FixTask(ctx, batch, t)
 
@@ -65,7 +72,12 @@
 				}
 			}
 			if restartDelay != 0 {
-				timestamp, err := gogotypes.TimestampFromProto(t.Status.Timestamp)
+				var timestamp time.Time
+				if t.Status.AppliedAt != nil {
+					timestamp, err = gogotypes.TimestampFromProto(t.Status.AppliedAt)
+				} else {
+					timestamp, err = gogotypes.TimestampFromProto(t.Status.Timestamp)
+				}
 				if err == nil {
 					restartTime := timestamp.Add(restartDelay)
 					calculatedRestartDelay := restartTime.Sub(time.Now())
@@ -99,5 +111,64 @@
 		}
 		return nil
 	})
-	return err
+	if err != nil {
+		return err
+	}
+
+	for tuple, instance := range instances {
+		// Find the most current spec version. That's the only one
+		// we care about for the purpose of reconstructing restart
+		// history.
+		maxVersion := uint64(0)
+		for _, t := range instance {
+			if t.SpecVersion != nil && t.SpecVersion.Index > maxVersion {
+				maxVersion = t.SpecVersion.Index
+			}
+		}
+
+		// Create a new slice with just the current spec version tasks.
+		var upToDate []*api.Task
+		for _, t := range instance {
+			if t.SpecVersion != nil && t.SpecVersion.Index == maxVersion {
+				upToDate = append(upToDate, t)
+			}
+		}
+
+		// Sort by creation timestamp
+		sort.Sort(tasksByCreationTimestamp(upToDate))
+
+		// All up-to-date tasks in this instance except the first one
+		// should be considered restarted.
+		if len(upToDate) < 2 {
+			continue
+		}
+		for _, t := range upToDate[1:] {
+			startSupervisor.RecordRestartHistory(tuple, t)
+		}
+	}
+	return nil
+}
+
+type tasksByCreationTimestamp []*api.Task
+
+func (t tasksByCreationTimestamp) Len() int {
+	return len(t)
+}
+func (t tasksByCreationTimestamp) Swap(i, j int) {
+	t[i], t[j] = t[j], t[i]
+}
+func (t tasksByCreationTimestamp) Less(i, j int) bool {
+	if t[i].Meta.CreatedAt == nil {
+		return true
+	}
+	if t[j].Meta.CreatedAt == nil {
+		return false
+	}
+	if t[i].Meta.CreatedAt.Seconds < t[j].Meta.CreatedAt.Seconds {
+		return true
+	}
+	if t[i].Meta.CreatedAt.Seconds > t[j].Meta.CreatedAt.Seconds {
+		return false
+	}
+	return t[i].Meta.CreatedAt.Nanos < t[j].Meta.CreatedAt.Nanos
 }
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go
index edb771c..577319c 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/taskreaper/task_reaper.go
@@ -6,6 +6,7 @@
 
 	"github.com/docker/swarmkit/api"
 	"github.com/docker/swarmkit/log"
+	"github.com/docker/swarmkit/manager/orchestrator"
 	"github.com/docker/swarmkit/manager/state"
 	"github.com/docker/swarmkit/manager/state/store"
 	"golang.org/x/net/context"
@@ -18,19 +19,13 @@
 	reaperBatchingInterval = 250 * time.Millisecond
 )
 
-type instanceTuple struct {
-	instance  uint64 // unset for global tasks
-	serviceID string
-	nodeID    string // unset for replicated tasks
-}
-
 // A TaskReaper deletes old tasks when more than TaskHistoryRetentionLimit tasks
 // exist for the same service/instance or service/nodeid combination.
 type TaskReaper struct {
 	store *store.MemoryStore
 	// taskHistory is the number of tasks to keep
 	taskHistory int64
-	dirty       map[instanceTuple]struct{}
+	dirty       map[orchestrator.SlotTuple]struct{}
 	orphaned    []string
 	stopChan    chan struct{}
 	doneChan    chan struct{}
@@ -40,7 +35,7 @@
 func New(store *store.MemoryStore) *TaskReaper {
 	return &TaskReaper{
 		store:    store,
-		dirty:    make(map[instanceTuple]struct{}),
+		dirty:    make(map[orchestrator.SlotTuple]struct{}),
 		stopChan: make(chan struct{}),
 		doneChan: make(chan struct{}),
 	}
@@ -93,10 +88,10 @@
 			switch v := event.(type) {
 			case api.EventCreateTask:
 				t := v.Task
-				tr.dirty[instanceTuple{
-					instance:  t.Slot,
-					serviceID: t.ServiceID,
-					nodeID:    t.NodeID,
+				tr.dirty[orchestrator.SlotTuple{
+					Slot:      t.Slot,
+					ServiceID: t.ServiceID,
+					NodeID:    t.NodeID,
 				}] = struct{}{}
 			case api.EventUpdateTask:
 				t := v.Task
@@ -138,13 +133,29 @@
 	}
 	tr.store.View(func(tx store.ReadTx) {
 		for dirty := range tr.dirty {
-			service := store.GetService(tx, dirty.serviceID)
+			service := store.GetService(tx, dirty.ServiceID)
 			if service == nil {
 				continue
 			}
 
 			taskHistory := tr.taskHistory
 
+			// If MaxAttempts is set, keep at least one more than
+			// that number of tasks. This is necessary reconstruct
+			// restart history when the orchestrator starts up.
+			// TODO(aaronl): Consider hiding tasks beyond the normal
+			// retention limit in the UI.
+			// TODO(aaronl): There are some ways to cut down the
+			// number of retained tasks at the cost of more
+			// complexity:
+			//   - Don't force retention of tasks with an older spec
+			//     version.
+			//   - Don't force retention of tasks outside of the
+			//     time window configured for restart lookback.
+			if service.Spec.Task.Restart != nil && service.Spec.Task.Restart.MaxAttempts > 0 {
+				taskHistory = int64(service.Spec.Task.Restart.MaxAttempts) + 1
+			}
+
 			if taskHistory < 0 {
 				continue
 			}
@@ -154,19 +165,19 @@
 			switch service.Spec.GetMode().(type) {
 			case *api.ServiceSpec_Replicated:
 				var err error
-				historicTasks, err = store.FindTasks(tx, store.BySlot(dirty.serviceID, dirty.instance))
+				historicTasks, err = store.FindTasks(tx, store.BySlot(dirty.ServiceID, dirty.Slot))
 				if err != nil {
 					continue
 				}
 
 			case *api.ServiceSpec_Global:
-				tasksByNode, err := store.FindTasks(tx, store.ByNodeID(dirty.nodeID))
+				tasksByNode, err := store.FindTasks(tx, store.ByNodeID(dirty.NodeID))
 				if err != nil {
 					continue
 				}
 
 				for _, t := range tasksByNode {
-					if t.ServiceID == dirty.serviceID {
+					if t.ServiceID == dirty.ServiceID {
 						historicTasks = append(historicTasks, t)
 					}
 				}
@@ -178,7 +189,9 @@
 
 			// TODO(aaronl): This could filter for non-running tasks and use quickselect
 			// instead of sorting the whole slice.
-			sort.Sort(tasksByTimestamp(historicTasks))
+			// TODO(aaronl): This sort should really use lamport time instead of wall
+			// clock time. We should store a Version in the Status field.
+			sort.Sort(orchestrator.TasksByTimestamp(historicTasks))
 
 			runningTasks := 0
 			for _, t := range historicTasks {
@@ -219,27 +232,3 @@
 	close(tr.stopChan)
 	<-tr.doneChan
 }
-
-type tasksByTimestamp []*api.Task
-
-func (t tasksByTimestamp) Len() int {
-	return len(t)
-}
-func (t tasksByTimestamp) Swap(i, j int) {
-	t[i], t[j] = t[j], t[i]
-}
-func (t tasksByTimestamp) Less(i, j int) bool {
-	if t[i].Status.Timestamp == nil {
-		return true
-	}
-	if t[j].Status.Timestamp == nil {
-		return false
-	}
-	if t[i].Status.Timestamp.Seconds < t[j].Status.Timestamp.Seconds {
-		return true
-	}
-	if t[i].Status.Timestamp.Seconds > t[j].Status.Timestamp.Seconds {
-		return false
-	}
-	return t[i].Status.Timestamp.Nanos < t[j].Status.Timestamp.Nanos
-}
diff --git a/vendor/github.com/docker/swarmkit/manager/orchestrator/update/updater.go b/vendor/github.com/docker/swarmkit/manager/orchestrator/update/updater.go
index 2b1f55d..f7e4ff5 100644
--- a/vendor/github.com/docker/swarmkit/manager/orchestrator/update/updater.go
+++ b/vendor/github.com/docker/swarmkit/manager/orchestrator/update/updater.go
@@ -384,10 +384,7 @@
 				return errors.New("service was deleted")
 			}
 
-			if err := store.CreateTask(tx, updated); err != nil {
-				return err
-			}
-			return nil
+			return store.CreateTask(tx, updated)
 		})
 		if err != nil {
 			return err
@@ -430,7 +427,7 @@
 				u.updatedTasks[updated.ID] = time.Now()
 				u.updatedTasksMu.Unlock()
 
-				if startThenStop {
+				if startThenStop && updated.Status.State == api.TaskStateRunning {
 					err := u.store.Batch(func(batch *store.Batch) error {
 						_, err := u.removeOldTasks(ctx, batch, slot)
 						if err != nil {
@@ -496,6 +493,9 @@
 		removedTask *api.Task
 	)
 	for _, original := range removeTasks {
+		if original.DesiredState > api.TaskStateRunning {
+			continue
+		}
 		err := batch.Update(func(tx store.Tx) error {
 			t := store.GetTask(tx, original.ID)
 			if t == nil {
@@ -583,9 +583,8 @@
 func (u *Updater) rollbackUpdate(ctx context.Context, serviceID, message string) {
 	log.G(ctx).Debugf("starting rollback of service %s", serviceID)
 
-	var service *api.Service
 	err := u.store.Update(func(tx store.Tx) error {
-		service = store.GetService(tx, serviceID)
+		service := store.GetService(tx, serviceID)
 		if service == nil {
 			return nil
 		}
@@ -601,7 +600,9 @@
 			return errors.New("cannot roll back service because no previous spec is available")
 		}
 		service.Spec = *service.PreviousSpec
+		service.SpecVersion = service.PreviousSpecVersion.Copy()
 		service.PreviousSpec = nil
+		service.PreviousSpecVersion = nil
 
 		return store.UpdateService(tx, service)
 	})
diff --git a/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go b/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go
index 73349e3..9968595 100644
--- a/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go
+++ b/vendor/github.com/docker/swarmkit/manager/scheduler/scheduler.go
@@ -92,11 +92,7 @@
 		tasksByNode[t.NodeID][t.ID] = t
 	}
 
-	if err := s.buildNodeSet(tx, tasksByNode); err != nil {
-		return err
-	}
-
-	return nil
+	return s.buildNodeSet(tx, tasksByNode)
 }
 
 // Run is the scheduler event loop.
diff --git a/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go b/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
index b793374..ec2c9c0 100644
--- a/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
+++ b/vendor/github.com/docker/swarmkit/manager/state/raft/raft.go
@@ -9,7 +9,6 @@
 	"sync/atomic"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/coreos/etcd/pkg/idutil"
 	"github.com/coreos/etcd/raft"
 	"github.com/coreos/etcd/raft/raftpb"
@@ -28,6 +27,7 @@
 	"github.com/gogo/protobuf/proto"
 	"github.com/pivotal-golang/clock"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/time/rate"
 	"google.golang.org/grpc"
@@ -166,6 +166,8 @@
 	// JoinAddr is the cluster to join. May be an empty string to create
 	// a standalone cluster.
 	JoinAddr string
+	// ForceJoin tells us to join even if already part of a cluster.
+	ForceJoin bool
 	// Config is the raft config.
 	Config *raft.Config
 	// StateDir is the directory to store durable state.
@@ -393,8 +395,10 @@
 
 	// restore from snapshot
 	if loadAndStartErr == nil {
-		if n.opts.JoinAddr != "" {
-			log.G(ctx).Warning("ignoring request to join cluster, because raft state already exists")
+		if n.opts.JoinAddr != "" && n.opts.ForceJoin {
+			if err := n.joinCluster(ctx); err != nil {
+				return errors.Wrap(err, "failed to rejoin cluster")
+			}
 		}
 		n.campaignWhenAble = true
 		n.initTransport()
@@ -402,7 +406,6 @@
 		return nil
 	}
 
-	// first member of cluster
 	if n.opts.JoinAddr == "" {
 		// First member in the cluster, self-assign ID
 		n.Config.ID = uint64(rand.Int63()) + 1
@@ -417,6 +420,22 @@
 	}
 
 	// join to existing cluster
+
+	if err := n.joinCluster(ctx); err != nil {
+		return err
+	}
+
+	if _, err := n.newRaftLogs(n.opts.ID); err != nil {
+		return err
+	}
+
+	n.initTransport()
+	n.raftNode = raft.StartNode(n.Config, nil)
+
+	return nil
+}
+
+func (n *Node) joinCluster(ctx context.Context) error {
 	if n.opts.Addr == "" {
 		return errors.New("attempted to join raft cluster without knowing own address")
 	}
@@ -438,15 +457,7 @@
 	}
 
 	n.Config.ID = resp.RaftID
-
-	if _, err := n.newRaftLogs(n.opts.ID); err != nil {
-		return err
-	}
 	n.bootstrapMembers = resp.Members
-
-	n.initTransport()
-	n.raftNode = raft.StartNode(n.Config, nil)
-
 	return nil
 }
 
@@ -909,24 +920,6 @@
 		return nil, grpc.Errorf(codes.FailedPrecondition, "%s", ErrLostLeadership.Error())
 	}
 
-	// A single manager must not be able to join the raft cluster twice. If
-	// it did, that would cause the quorum to be computed incorrectly. This
-	// could happen if the WAL was deleted from an active manager.
-	for _, m := range n.cluster.Members() {
-		if m.NodeID == nodeInfo.NodeID {
-			return nil, grpc.Errorf(codes.AlreadyExists, "%s", "a raft member with this node ID already exists")
-		}
-	}
-
-	// Find a unique ID for the joining member.
-	var raftID uint64
-	for {
-		raftID = uint64(rand.Int63()) + 1
-		if n.cluster.GetMember(raftID) == nil && !n.cluster.IsIDRemoved(raftID) {
-			break
-		}
-	}
-
 	remoteAddr := req.Addr
 
 	// If the joining node sent an address like 0.0.0.0:4242, automatically
@@ -953,12 +946,54 @@
 		return nil, err
 	}
 
+	// If the peer is already a member of the cluster, we will only update
+	// its information, not add it as a new member. Adding it again would
+	// cause the quorum to be computed incorrectly.
+	for _, m := range n.cluster.Members() {
+		if m.NodeID == nodeInfo.NodeID {
+			if remoteAddr == m.Addr {
+				return n.joinResponse(m.RaftID), nil
+			}
+			updatedRaftMember := &api.RaftMember{
+				RaftID: m.RaftID,
+				NodeID: m.NodeID,
+				Addr:   remoteAddr,
+			}
+			if err := n.cluster.UpdateMember(m.RaftID, updatedRaftMember); err != nil {
+				return nil, err
+			}
+
+			if err := n.updateNodeBlocking(ctx, m.RaftID, remoteAddr); err != nil {
+				log.WithError(err).Error("failed to update node address")
+				return nil, err
+			}
+
+			log.Info("updated node address")
+			return n.joinResponse(m.RaftID), nil
+		}
+	}
+
+	// Find a unique ID for the joining member.
+	var raftID uint64
+	for {
+		raftID = uint64(rand.Int63()) + 1
+		if n.cluster.GetMember(raftID) == nil && !n.cluster.IsIDRemoved(raftID) {
+			break
+		}
+	}
+
 	err = n.addMember(ctx, remoteAddr, raftID, nodeInfo.NodeID)
 	if err != nil {
 		log.WithError(err).Errorf("failed to add member %x", raftID)
 		return nil, err
 	}
 
+	log.Debug("node joined")
+
+	return n.joinResponse(raftID), nil
+}
+
+func (n *Node) joinResponse(raftID uint64) *api.JoinResponse {
 	var nodes []*api.RaftMember
 	for _, node := range n.cluster.Members() {
 		nodes = append(nodes, &api.RaftMember{
@@ -967,9 +1002,8 @@
 			Addr:   node.Addr,
 		})
 	}
-	log.Debugf("node joined")
 
-	return &api.JoinResponse{Members: nodes, RaftID: raftID}, nil
+	return &api.JoinResponse{Members: nodes, RaftID: raftID}
 }
 
 // checkHealth tries to contact an aspiring member through its advertised address
@@ -1249,10 +1283,7 @@
 		return err
 	}
 	newAddr := net.JoinHostPort(newHost, officialPort)
-	if err := n.transport.UpdatePeerAddr(id, newAddr); err != nil {
-		return err
-	}
-	return nil
+	return n.transport.UpdatePeerAddr(id, newAddr)
 }
 
 // ProcessRaftMessage calls 'Step' which advances the
@@ -1814,10 +1845,7 @@
 		return nil
 	}
 
-	if err = n.registerNode(member); err != nil {
-		return err
-	}
-	return nil
+	return n.registerNode(member)
 }
 
 // applyUpdateNode is called when we receive a ConfChange from a member in the
diff --git a/vendor/github.com/docker/swarmkit/manager/state/raft/storage/storage.go b/vendor/github.com/docker/swarmkit/manager/state/raft/storage/storage.go
index a737aab..539e05d 100644
--- a/vendor/github.com/docker/swarmkit/manager/state/raft/storage/storage.go
+++ b/vendor/github.com/docker/swarmkit/manager/state/raft/storage/storage.go
@@ -226,10 +226,7 @@
 	if err := snapshotter.SaveSnap(snapshot); err != nil {
 		return err
 	}
-	if err := e.wal.ReleaseLockTo(snapshot.Metadata.Index); err != nil {
-		return err
-	}
-	return nil
+	return e.wal.ReleaseLockTo(snapshot.Metadata.Index)
 }
 
 // GC garbage collects snapshots and wals older than the provided index and term
diff --git a/vendor/github.com/docker/swarmkit/manager/state/raft/transport/transport.go b/vendor/github.com/docker/swarmkit/manager/state/raft/transport/transport.go
index 69057f6..b259013 100644
--- a/vendor/github.com/docker/swarmkit/manager/state/raft/transport/transport.go
+++ b/vendor/github.com/docker/swarmkit/manager/state/raft/transport/transport.go
@@ -235,10 +235,7 @@
 	if !ok {
 		return ErrIsNotFound
 	}
-	if err := p.updateAddr(addr); err != nil {
-		return err
-	}
-	return nil
+	return p.updateAddr(addr)
 }
 
 // PeerConn returns raw grpc connection to peer.
diff --git a/vendor/github.com/docker/swarmkit/manager/watchapi/server.go b/vendor/github.com/docker/swarmkit/manager/watchapi/server.go
index 07cdedb..6d49dca 100644
--- a/vendor/github.com/docker/swarmkit/manager/watchapi/server.go
+++ b/vendor/github.com/docker/swarmkit/manager/watchapi/server.go
@@ -1,12 +1,24 @@
 package watchapi
 
 import (
+	"errors"
+	"sync"
+
 	"github.com/docker/swarmkit/manager/state/store"
+	"golang.org/x/net/context"
+)
+
+var (
+	errAlreadyRunning = errors.New("broker is already running")
+	errNotRunning     = errors.New("broker is not running")
 )
 
 // Server is the store API gRPC server.
 type Server struct {
-	store *store.MemoryStore
+	store     *store.MemoryStore
+	mu        sync.Mutex
+	pctx      context.Context
+	cancelAll func()
 }
 
 // NewServer creates a store API server.
@@ -15,3 +27,30 @@
 		store: store,
 	}
 }
+
+// Start starts the watch server.
+func (s *Server) Start(ctx context.Context) error {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	if s.cancelAll != nil {
+		return errAlreadyRunning
+	}
+
+	s.pctx, s.cancelAll = context.WithCancel(ctx)
+	return nil
+}
+
+// Stop stops the watch server.
+func (s *Server) Stop() error {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	if s.cancelAll == nil {
+		return errNotRunning
+	}
+	s.cancelAll()
+	s.cancelAll = nil
+
+	return nil
+}
diff --git a/vendor/github.com/docker/swarmkit/manager/watchapi/watch.go b/vendor/github.com/docker/swarmkit/manager/watchapi/watch.go
index 555b899..53bed49 100644
--- a/vendor/github.com/docker/swarmkit/manager/watchapi/watch.go
+++ b/vendor/github.com/docker/swarmkit/manager/watchapi/watch.go
@@ -17,6 +17,13 @@
 func (s *Server) Watch(request *api.WatchRequest, stream api.Watch_WatchServer) error {
 	ctx := stream.Context()
 
+	s.mu.Lock()
+	pctx := s.pctx
+	s.mu.Unlock()
+	if pctx == nil {
+		return errNotRunning
+	}
+
 	watchArgs, err := api.ConvertWatchArgs(request.Entries)
 	if err != nil {
 		return grpc.Errorf(codes.InvalidArgument, "%s", err.Error())
@@ -39,6 +46,8 @@
 		select {
 		case <-ctx.Done():
 			return ctx.Err()
+		case <-pctx.Done():
+			return pctx.Err()
 		case event := <-watch:
 			if commitEvent, ok := event.(state.EventCommit); ok && len(events) > 0 {
 				if err := stream.Send(&api.WatchMessage{Events: events, Version: commitEvent.Version}); err != nil {
diff --git a/vendor/github.com/docker/swarmkit/node/node.go b/vendor/github.com/docker/swarmkit/node/node.go
index 77fe5b3..adad42b 100644
--- a/vendor/github.com/docker/swarmkit/node/node.go
+++ b/vendor/github.com/docker/swarmkit/node/node.go
@@ -14,7 +14,6 @@
 	"sync"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/boltdb/bolt"
 	"github.com/docker/docker/pkg/plugingetter"
 	metrics "github.com/docker/go-metrics"
@@ -31,6 +30,7 @@
 	"github.com/docker/swarmkit/xnet"
 	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -308,8 +308,6 @@
 			case <-agentDone:
 				return
 			case nodeChanges := <-n.notifyNodeChange:
-				currentRole := n.currentRole()
-
 				if nodeChanges.Node != nil {
 					// This is a bit complex to be backward compatible with older CAs that
 					// don't support the Node.Role field. They only use what's presently
@@ -335,10 +333,7 @@
 				}
 
 				if nodeChanges.RootCert != nil {
-					// We only want to update the root CA if this is a worker node.  Manager nodes directly watch the raft
-					// store and update the root CA, with the necessary signer, from the raft store (since the managers
-					// need the CA key as well to potentially issue new TLS certificates).
-					if currentRole == api.NodeRoleManager || bytes.Equal(nodeChanges.RootCert, securityConfig.RootCA().Certs) {
+					if bytes.Equal(nodeChanges.RootCert, securityConfig.RootCA().Certs) {
 						continue
 					}
 					newRootCA, err := ca.NewRootCA(nodeChanges.RootCert, nil, nil, ca.DefaultNodeCertExpiration, nil)
@@ -346,7 +341,7 @@
 						log.G(ctx).WithError(err).Error("invalid new root certificate from the dispatcher")
 						continue
 					}
-					if err := securityConfig.UpdateRootCA(&newRootCA, newRootCA.Pool); err != nil {
+					if err := securityConfig.UpdateRootCA(&newRootCA); err != nil {
 						log.G(ctx).WithError(err).Error("could not use new root CA from dispatcher")
 						continue
 					}
@@ -828,14 +823,22 @@
 		}
 	}
 
-	remoteAddr, _ := n.remotes.Select(n.NodeID())
+	joinAddr := n.config.JoinAddr
+	if joinAddr == "" {
+		remoteAddr, err := n.remotes.Select(n.NodeID())
+		if err == nil {
+			joinAddr = remoteAddr.Addr
+		}
+	}
+
 	m, err := manager.New(&manager.Config{
 		ForceNewCluster:  n.config.ForceNewCluster,
 		RemoteAPI:        remoteAPI,
 		ControlAPI:       n.config.ListenControlAPI,
 		SecurityConfig:   securityConfig,
 		ExternalCAs:      n.config.ExternalCAs,
-		JoinRaft:         remoteAddr.Addr,
+		JoinRaft:         joinAddr,
+		ForceJoin:        n.config.JoinAddr != "",
 		StateDir:         n.config.StateDir,
 		HeartbeatTick:    n.config.HeartbeatTick,
 		ElectionTick:     n.config.ElectionTick,
diff --git a/vendor/github.com/docker/swarmkit/protobuf/plugin/gen.go b/vendor/github.com/docker/swarmkit/protobuf/plugin/gen.go
deleted file mode 100644
index b68b837..0000000
--- a/vendor/github.com/docker/swarmkit/protobuf/plugin/gen.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package plugin
-
-//go:generate protoc -I.:/usr/local --gogoswarm_out=import_path=github.com/docker/swarmkit/protobuf/plugin,Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:. plugin.proto
diff --git a/vendor/github.com/docker/swarmkit/protobuf/plugin/plugin.pb.go b/vendor/github.com/docker/swarmkit/protobuf/plugin/plugin.pb.go
index 9cafe73..549ceba 100644
--- a/vendor/github.com/docker/swarmkit/protobuf/plugin/plugin.pb.go
+++ b/vendor/github.com/docker/swarmkit/protobuf/plugin/plugin.pb.go
@@ -1,12 +1,12 @@
 // Code generated by protoc-gen-gogo.
-// source: plugin.proto
+// source: github.com/docker/swarmkit/protobuf/plugin/plugin.proto
 // DO NOT EDIT!
 
 /*
 	Package plugin is a generated protocol buffer package.
 
 	It is generated from these files:
-		plugin.proto
+		github.com/docker/swarmkit/protobuf/plugin/plugin.proto
 
 	It has these top-level messages:
 		WatchSelectors
@@ -20,6 +20,8 @@
 import math "math"
 import google_protobuf "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
 
+import github_com_docker_swarmkit_api_deepcopy "github.com/docker/swarmkit/api/deepcopy"
+
 import github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto"
 
 import strings "strings"
@@ -92,7 +94,7 @@
 	Field:         70000,
 	Name:          "docker.protobuf.plugin.deepcopy",
 	Tag:           "varint,70000,opt,name=deepcopy,def=1",
-	Filename:      "plugin.proto",
+	Filename:      "github.com/docker/swarmkit/protobuf/plugin/plugin.proto",
 }
 
 var E_StoreObject = &proto.ExtensionDesc{
@@ -101,7 +103,7 @@
 	Field:         70001,
 	Name:          "docker.protobuf.plugin.store_object",
 	Tag:           "bytes,70001,opt,name=store_object,json=storeObject",
-	Filename:      "plugin.proto",
+	Filename:      "github.com/docker/swarmkit/protobuf/plugin/plugin.proto",
 }
 
 var E_TlsAuthorization = &proto.ExtensionDesc{
@@ -110,7 +112,7 @@
 	Field:         73626345,
 	Name:          "docker.protobuf.plugin.tls_authorization",
 	Tag:           "bytes,73626345,opt,name=tls_authorization,json=tlsAuthorization",
-	Filename:      "plugin.proto",
+	Filename:      "github.com/docker/swarmkit/protobuf/plugin/plugin.proto",
 }
 
 func init() {
@@ -121,6 +123,61 @@
 	proto.RegisterExtension(E_StoreObject)
 	proto.RegisterExtension(E_TlsAuthorization)
 }
+
+func (m *WatchSelectors) Copy() *WatchSelectors {
+	if m == nil {
+		return nil
+	}
+	o := &WatchSelectors{}
+	o.CopyFrom(m)
+	return o
+}
+
+func (m *WatchSelectors) CopyFrom(src interface{}) {
+
+	o := src.(*WatchSelectors)
+	*m = *o
+}
+
+func (m *StoreObject) Copy() *StoreObject {
+	if m == nil {
+		return nil
+	}
+	o := &StoreObject{}
+	o.CopyFrom(m)
+	return o
+}
+
+func (m *StoreObject) CopyFrom(src interface{}) {
+
+	o := src.(*StoreObject)
+	*m = *o
+	if o.WatchSelectors != nil {
+		m.WatchSelectors = &WatchSelectors{}
+		github_com_docker_swarmkit_api_deepcopy.Copy(m.WatchSelectors, o.WatchSelectors)
+	}
+}
+
+func (m *TLSAuthorization) Copy() *TLSAuthorization {
+	if m == nil {
+		return nil
+	}
+	o := &TLSAuthorization{}
+	o.CopyFrom(m)
+	return o
+}
+
+func (m *TLSAuthorization) CopyFrom(src interface{}) {
+
+	o := src.(*TLSAuthorization)
+	*m = *o
+	if o.Roles != nil {
+		m.Roles = make([]string, len(o.Roles))
+		copy(m.Roles, o.Roles)
+	}
+
+}
+
 func (m *WatchSelectors) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -378,6 +435,7 @@
 	dAtA[offset] = uint8(v)
 	return offset + 1
 }
+
 func (m *WatchSelectors) Size() (n int) {
 	var l int
 	_ = l
@@ -1143,43 +1201,46 @@
 	ErrIntOverflowPlugin   = fmt.Errorf("proto: integer overflow")
 )
 
-func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) }
+func init() {
+	proto.RegisterFile("github.com/docker/swarmkit/protobuf/plugin/plugin.proto", fileDescriptorPlugin)
+}
 
 var fileDescriptorPlugin = []byte{
-	// 551 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xc1, 0x6e, 0xd3, 0x40,
-	0x10, 0xad, 0xd3, 0x36, 0x4d, 0xc6, 0x69, 0x29, 0x2b, 0x54, 0xad, 0x7a, 0xb0, 0xab, 0x46, 0x42,
-	0x41, 0x42, 0xa9, 0xd4, 0x63, 0x6e, 0x94, 0x5c, 0x22, 0x01, 0x45, 0x0e, 0x12, 0x37, 0x2c, 0xd7,
-	0x3b, 0x4d, 0x96, 0x3a, 0x5e, 0x6b, 0x77, 0x4d, 0x0b, 0x27, 0x7e, 0x80, 0x0f, 0xe0, 0xca, 0xd7,
-	0xf4, 0xc8, 0x91, 0x53, 0x44, 0x2d, 0x71, 0xe0, 0x06, 0x7f, 0x80, 0x76, 0xd7, 0x69, 0x09, 0x6a,
-	0xc5, 0xc9, 0x33, 0x6f, 0xe6, 0xcd, 0xcc, 0xdb, 0x67, 0xe8, 0x14, 0x59, 0x39, 0xe1, 0x79, 0xbf,
-	0x90, 0x42, 0x0b, 0xb2, 0xc3, 0x44, 0x7a, 0x86, 0xd2, 0x65, 0x27, 0xe5, 0x69, 0xdf, 0x55, 0x77,
-	0xf7, 0x26, 0x42, 0x4c, 0x32, 0x3c, 0x58, 0xe0, 0x07, 0x0c, 0x55, 0x2a, 0x79, 0xa1, 0x45, 0xdd,
-	0xbb, 0xff, 0x79, 0x15, 0xb6, 0x5e, 0x27, 0x3a, 0x9d, 0x8e, 0x31, 0xc3, 0x54, 0x0b, 0xa9, 0xc8,
-	0x0e, 0x34, 0x38, 0xa3, 0xde, 0x9e, 0xd7, 0x6b, 0x1d, 0x35, 0xab, 0x79, 0xd8, 0x18, 0x0d, 0xa3,
-	0x06, 0x67, 0xe4, 0x11, 0xb4, 0x39, 0x8b, 0x0b, 0x89, 0xa7, 0xfc, 0x82, 0x36, 0x6c, 0xb9, 0x53,
-	0xcd, 0xc3, 0xd6, 0x68, 0xf8, 0xd2, 0x62, 0x51, 0x8b, 0x33, 0x17, 0x11, 0x02, 0x6b, 0x79, 0x32,
-	0x43, 0xba, 0x6a, 0xba, 0x22, 0x1b, 0x93, 0x10, 0x7c, 0xf3, 0x5d, 0x0c, 0x58, 0xb3, 0x25, 0x30,
-	0x50, 0x4d, 0xda, 0x81, 0x66, 0x5a, 0x2a, 0x2d, 0x66, 0x74, 0xdd, 0xd6, 0xea, 0x8c, 0x74, 0x61,
-	0xd3, 0x45, 0x0b, 0x6a, 0xd3, 0x96, 0x3b, 0x0e, 0xac, 0xc9, 0x8f, 0x01, 0x14, 0xca, 0x77, 0x3c,
-	0xc5, 0x98, 0x33, 0xba, 0x61, 0xaf, 0xdb, 0xac, 0xe6, 0x61, 0x7b, 0xec, 0xd0, 0xd1, 0x30, 0x6a,
-	0xd7, 0x0d, 0x23, 0x46, 0xba, 0xb0, 0x91, 0x0b, 0x66, 0x5b, 0x5b, 0xb6, 0x15, 0xaa, 0x79, 0xd8,
-	0x7c, 0x21, 0x98, 0xe9, 0x6b, 0x9a, 0xd2, 0x88, 0x19, 0x11, 0x2a, 0x13, 0x9a, 0xb6, 0x9d, 0x08,
-	0x13, 0x9b, 0x5b, 0x18, 0x2a, 0x2e, 0x91, 0xc5, 0x4a, 0x27, 0x1a, 0x29, 0xb8, 0x5b, 0x6a, 0x70,
-	0x6c, 0x30, 0x43, 0x94, 0x22, 0x43, 0xea, 0x3b, 0xa2, 0x89, 0x49, 0x00, 0x30, 0xc3, 0xd9, 0x09,
-	0x4a, 0x35, 0xe5, 0x05, 0xed, 0x38, 0xf1, 0x37, 0x88, 0xe1, 0x9c, 0xf1, 0x9c, 0xd1, 0x4d, 0xc7,
-	0x31, 0xf1, 0xfe, 0x1b, 0xf0, 0xc7, 0x5a, 0x48, 0x3c, 0x3e, 0x79, 0x8b, 0xa9, 0x26, 0xc7, 0x70,
-	0xef, 0xdc, 0x38, 0x15, 0xab, 0x85, 0x55, 0xd4, 0xdb, 0x6b, 0xf4, 0xfc, 0xc3, 0x87, 0xfd, 0xdb,
-	0xed, 0xef, 0x2f, 0x1b, 0x1b, 0x6d, 0x9d, 0x2f, 0xe5, 0xfb, 0x43, 0xd8, 0x7e, 0xf5, 0x6c, 0xfc,
-	0xa4, 0xd4, 0x53, 0x21, 0xf9, 0x87, 0x44, 0x73, 0x91, 0x93, 0x07, 0xb0, 0x6e, 0xee, 0x35, 0xa3,
-	0x57, 0x7b, 0xed, 0xc8, 0x25, 0x64, 0x17, 0x5a, 0x3c, 0x57, 0x98, 0x96, 0x12, 0x9d, 0xf3, 0xd1,
-	0x75, 0x3e, 0x78, 0x0a, 0x2d, 0x86, 0x58, 0xa4, 0xa2, 0x78, 0x4f, 0xc2, 0xbe, 0xfb, 0xe1, 0x6e,
-	0x2e, 0x79, 0x8e, 0x4a, 0x25, 0x13, 0x3c, 0x2e, 0xcc, 0x74, 0x45, 0x7f, 0x7d, 0xb1, 0xbe, 0x0f,
-	0xd6, 0xb4, 0x2c, 0x31, 0xba, 0x26, 0x0e, 0x38, 0x74, 0x94, 0x91, 0x1a, 0x0b, 0xa7, 0xf5, 0xbf,
-	0x83, 0x7e, 0xdb, 0x41, 0xfe, 0x61, 0xf7, 0x2e, 0xed, 0x7f, 0xbd, 0x5c, 0xe4, 0xab, 0x9b, 0x64,
-	0x70, 0x01, 0xf7, 0x75, 0xa6, 0xe2, 0x64, 0x49, 0x76, 0x70, 0xcb, 0x3e, 0x3d, 0x15, 0x6c, 0xb1,
-	0xee, 0xe7, 0x8f, 0x4f, 0x5d, 0xbb, 0xaf, 0x77, 0xd7, 0xbe, 0x7f, 0x5f, 0x32, 0xda, 0xd6, 0x99,
-	0x5a, 0x42, 0x8e, 0xe8, 0xe5, 0x55, 0xb0, 0xf2, 0xed, 0x2a, 0x58, 0xf9, 0x58, 0x05, 0xde, 0x65,
-	0x15, 0x78, 0x5f, 0xab, 0xc0, 0xfb, 0x5e, 0x05, 0xde, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x94,
-	0xd6, 0x21, 0x73, 0xce, 0x03, 0x00, 0x00,
+	// 575 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0xc1, 0x6e, 0xd3, 0x4c,
+	0x10, 0xae, 0xd3, 0x36, 0x4d, 0x26, 0x69, 0xff, 0xfe, 0x2b, 0x54, 0xad, 0x7a, 0x70, 0xaa, 0x46,
+	0x42, 0x41, 0x42, 0x8e, 0xd4, 0x0b, 0x52, 0x6e, 0x94, 0x5c, 0x22, 0x01, 0x45, 0x0e, 0x12, 0x37,
+	0x22, 0xc7, 0x3b, 0x4d, 0x96, 0x3a, 0x5e, 0x6b, 0x77, 0x4d, 0x0a, 0x27, 0x5e, 0x80, 0x07, 0xe0,
+	0xca, 0xd3, 0xf4, 0xc8, 0x91, 0x53, 0x44, 0x2d, 0x71, 0xe0, 0x06, 0x6f, 0x80, 0x76, 0xd7, 0x69,
+	0x08, 0x6a, 0xc5, 0xc9, 0x33, 0xdf, 0x7c, 0xdf, 0xcc, 0x7c, 0x3b, 0x86, 0x47, 0x13, 0xae, 0xa7,
+	0xf9, 0x38, 0x88, 0xc5, 0xac, 0xcb, 0x44, 0x7c, 0x81, 0xb2, 0xab, 0xe6, 0x91, 0x9c, 0x5d, 0x70,
+	0xdd, 0xcd, 0xa4, 0xd0, 0x62, 0x9c, 0x9f, 0x77, 0xb3, 0x24, 0x9f, 0xf0, 0xb4, 0xfc, 0x04, 0x16,
+	0x26, 0x07, 0x8e, 0x1d, 0x2c, 0x49, 0x81, 0xab, 0x1e, 0x1e, 0x4d, 0x84, 0x98, 0x24, 0xb8, 0x12,
+	0x33, 0x54, 0xb1, 0xe4, 0x99, 0x16, 0x25, 0xf7, 0xf8, 0xd3, 0x26, 0xec, 0xbd, 0x8a, 0x74, 0x3c,
+	0x1d, 0x62, 0x82, 0xb1, 0x16, 0x52, 0x91, 0x03, 0xa8, 0x70, 0x46, 0xbd, 0x23, 0xaf, 0x53, 0x3b,
+	0xad, 0x16, 0x8b, 0x56, 0x65, 0xd0, 0x0f, 0x2b, 0x9c, 0x91, 0x07, 0x50, 0xe7, 0x6c, 0x94, 0x49,
+	0x3c, 0xe7, 0x97, 0xb4, 0x62, 0xcb, 0xcd, 0x62, 0xd1, 0xaa, 0x0d, 0xfa, 0x2f, 0x2c, 0x16, 0xd6,
+	0x38, 0x73, 0x11, 0x21, 0xb0, 0x95, 0x46, 0x33, 0xa4, 0x9b, 0x86, 0x15, 0xda, 0x98, 0xb4, 0xa0,
+	0x61, 0xbe, 0xcb, 0x06, 0x5b, 0xb6, 0x04, 0x06, 0x2a, 0x45, 0x07, 0x50, 0x8d, 0x73, 0xa5, 0xc5,
+	0x8c, 0x6e, 0xdb, 0x5a, 0x99, 0x91, 0x36, 0xec, 0xba, 0x68, 0x29, 0xad, 0xda, 0x72, 0xd3, 0x81,
+	0xa5, 0xf8, 0x21, 0x80, 0x42, 0xf9, 0x96, 0xc7, 0x38, 0xe2, 0x8c, 0xee, 0xd8, 0xed, 0x76, 0x8b,
+	0x45, 0xab, 0x3e, 0x74, 0xe8, 0xa0, 0x1f, 0xd6, 0x4b, 0xc2, 0x80, 0x91, 0x36, 0xec, 0xa4, 0x82,
+	0x59, 0x6a, 0xcd, 0x52, 0xa1, 0x58, 0xb4, 0xaa, 0xcf, 0x05, 0x33, 0xbc, 0xaa, 0x29, 0x0d, 0x98,
+	0x31, 0xa1, 0x12, 0xa1, 0x69, 0xdd, 0x99, 0x30, 0xb1, 0xd9, 0x85, 0xa1, 0xe2, 0x12, 0xd9, 0x48,
+	0xe9, 0x48, 0x23, 0x05, 0xb7, 0x4b, 0x09, 0x0e, 0x0d, 0x66, 0x84, 0x52, 0x24, 0x48, 0x1b, 0x4e,
+	0x68, 0x62, 0xe2, 0x03, 0xcc, 0x70, 0x36, 0x46, 0xa9, 0xa6, 0x3c, 0xa3, 0x4d, 0x67, 0x7e, 0x85,
+	0x18, 0xcd, 0x05, 0x4f, 0x19, 0xdd, 0x75, 0x1a, 0x13, 0x1f, 0xbf, 0x86, 0xc6, 0x50, 0x0b, 0x89,
+	0x67, 0xe3, 0x37, 0x18, 0x6b, 0x72, 0x06, 0xff, 0xcd, 0xcd, 0xa5, 0x46, 0x6a, 0x79, 0x2a, 0xea,
+	0x1d, 0x55, 0x3a, 0x8d, 0x93, 0xfb, 0xc1, 0xed, 0xe7, 0x0f, 0xd6, 0x0f, 0x1b, 0xee, 0xcd, 0xd7,
+	0xf2, 0xe3, 0x3e, 0xec, 0xbf, 0x7c, 0x3a, 0x7c, 0x9c, 0xeb, 0xa9, 0x90, 0xfc, 0x7d, 0xa4, 0xb9,
+	0x48, 0xc9, 0x3d, 0xd8, 0x36, 0xfb, 0x9a, 0xd6, 0x9b, 0x9d, 0x7a, 0xe8, 0x12, 0x72, 0x08, 0x35,
+	0x9e, 0x2a, 0x8c, 0x73, 0x89, 0xee, 0xf2, 0xe1, 0x4d, 0xde, 0x7b, 0x02, 0x35, 0x86, 0x98, 0xc5,
+	0x22, 0x7b, 0x47, 0x5a, 0x81, 0xfb, 0xe1, 0x56, 0x9b, 0x3c, 0x43, 0xa5, 0xa2, 0x09, 0x9e, 0x65,
+	0xa6, 0xbb, 0xa2, 0x3f, 0x3f, 0xdb, 0xbb, 0xf7, 0xb6, 0xb4, 0xcc, 0x31, 0xbc, 0x11, 0xf6, 0x38,
+	0x34, 0x95, 0xb1, 0x3a, 0x12, 0xce, 0xeb, 0x3f, 0x1b, 0xfd, 0xb2, 0x8d, 0x1a, 0x27, 0xed, 0xbb,
+	0xbc, 0xff, 0xf1, 0x72, 0x61, 0x43, 0xad, 0x92, 0xde, 0x25, 0xfc, 0xaf, 0x13, 0x35, 0x8a, 0xd6,
+	0x6c, 0xfb, 0xb7, 0xcc, 0xd3, 0x53, 0xc1, 0x96, 0xe3, 0x7e, 0x7c, 0xff, 0xd8, 0xb6, 0xf3, 0x3a,
+	0x77, 0xcd, 0xfb, 0xfb, 0x25, 0xc3, 0x7d, 0x9d, 0xa8, 0x35, 0xe4, 0x94, 0x5e, 0x5d, 0xfb, 0x1b,
+	0x5f, 0xaf, 0xfd, 0x8d, 0x0f, 0x85, 0xef, 0x5d, 0x15, 0xbe, 0xf7, 0xa5, 0xf0, 0xbd, 0x6f, 0x85,
+	0xef, 0xfd, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x99, 0x7d, 0xfb, 0xf9, 0x03, 0x00, 0x00,
 }
diff --git a/vendor/github.com/docker/swarmkit/template/context.go b/vendor/github.com/docker/swarmkit/template/context.go
index e3badef..8485fc4 100644
--- a/vendor/github.com/docker/swarmkit/template/context.go
+++ b/vendor/github.com/docker/swarmkit/template/context.go
@@ -107,9 +107,10 @@
 	t                 *api.Task
 	restrictedSecrets exec.SecretGetter
 	restrictedConfigs exec.ConfigGetter
+	sensitive         bool
 }
 
-func (ctx PayloadContext) secretGetter(target string) (string, error) {
+func (ctx *PayloadContext) secretGetter(target string) (string, error) {
 	if ctx.restrictedSecrets == nil {
 		return "", errors.New("secrets unavailable")
 	}
@@ -126,6 +127,7 @@
 			if err != nil {
 				return "", err
 			}
+			ctx.sensitive = true
 			return string(secret.Spec.Data), nil
 		}
 	}
@@ -133,7 +135,7 @@
 	return "", errors.Errorf("secret target %s not found", target)
 }
 
-func (ctx PayloadContext) configGetter(target string) (string, error) {
+func (ctx *PayloadContext) configGetter(target string) (string, error) {
 	if ctx.restrictedConfigs == nil {
 		return "", errors.New("configs unavailable")
 	}
@@ -157,7 +159,7 @@
 	return "", errors.Errorf("config target %s not found", target)
 }
 
-func (ctx PayloadContext) envGetter(variable string) (string, error) {
+func (ctx *PayloadContext) envGetter(variable string) (string, error) {
 	container := ctx.t.Spec.GetContainer()
 	if container == nil {
 		return "", errors.New("task is not a container")
diff --git a/vendor/github.com/docker/swarmkit/template/expand.go b/vendor/github.com/docker/swarmkit/template/expand.go
index 45ca971..0957c25 100644
--- a/vendor/github.com/docker/swarmkit/template/expand.go
+++ b/vendor/github.com/docker/swarmkit/template/expand.go
@@ -119,7 +119,7 @@
 	return result, nil
 }
 
-func expandPayload(ctx PayloadContext, payload []byte) ([]byte, error) {
+func expandPayload(ctx *PayloadContext, payload []byte) ([]byte, error) {
 	result, err := ctx.Expand(string(payload))
 	if err != nil {
 		return payload, err
@@ -138,7 +138,7 @@
 		secretSpec := s.Spec.Copy()
 
 		var err error
-		secretSpec.Data, err = expandPayload(ctx, secretSpec.Data)
+		secretSpec.Data, err = expandPayload(&ctx, secretSpec.Data)
 		return secretSpec, err
 	}
 	return &s.Spec, errors.New("unrecognized template type")
@@ -146,17 +146,17 @@
 
 // ExpandConfigSpec expands the template inside the config payload, if any.
 // Templating is evaluated on the agent-side.
-func ExpandConfigSpec(c *api.Config, node *api.NodeDescription, t *api.Task, dependencies exec.DependencyGetter) (*api.ConfigSpec, error) {
+func ExpandConfigSpec(c *api.Config, node *api.NodeDescription, t *api.Task, dependencies exec.DependencyGetter) (*api.ConfigSpec, bool, error) {
 	if c.Spec.Templating == nil {
-		return &c.Spec, nil
+		return &c.Spec, false, nil
 	}
 	if c.Spec.Templating.Name == "golang" {
 		ctx := NewPayloadContextFromTask(node, t, dependencies)
 		configSpec := c.Spec.Copy()
 
 		var err error
-		configSpec.Data, err = expandPayload(ctx, configSpec.Data)
-		return configSpec, err
+		configSpec.Data, err = expandPayload(&ctx, configSpec.Data)
+		return configSpec, ctx.sensitive, err
 	}
-	return &c.Spec, errors.New("unrecognized template type")
+	return &c.Spec, false, errors.New("unrecognized template type")
 }
diff --git a/vendor/github.com/docker/swarmkit/template/getter.go b/vendor/github.com/docker/swarmkit/template/getter.go
index 05e5de7..58c1875 100644
--- a/vendor/github.com/docker/swarmkit/template/getter.go
+++ b/vendor/github.com/docker/swarmkit/template/getter.go
@@ -42,6 +42,18 @@
 	return &secretCopy, nil
 }
 
+// TemplatedConfigGetter is a ConfigGetter with an additional method to expose
+// whether a config contains sensitive data.
+type TemplatedConfigGetter interface {
+	exec.ConfigGetter
+
+	// GetAndFlagSecretData returns the interpolated config, and also
+	// returns true if the config has been interpolated with data from a
+	// secret. In this case, the config should be handled specially and
+	// should not be written to disk.
+	GetAndFlagSecretData(configID string) (*api.Config, bool, error)
+}
+
 type templatedConfigGetter struct {
 	dependencies exec.DependencyGetter
 	t            *api.Task
@@ -49,38 +61,43 @@
 }
 
 // NewTemplatedConfigGetter returns a ConfigGetter that evaluates templates.
-func NewTemplatedConfigGetter(dependencies exec.DependencyGetter, t *api.Task, node *api.NodeDescription) exec.ConfigGetter {
+func NewTemplatedConfigGetter(dependencies exec.DependencyGetter, t *api.Task, node *api.NodeDescription) TemplatedConfigGetter {
 	return templatedConfigGetter{dependencies: dependencies, t: t, node: node}
 }
 
 func (t templatedConfigGetter) Get(configID string) (*api.Config, error) {
+	config, _, err := t.GetAndFlagSecretData(configID)
+	return config, err
+}
+
+func (t templatedConfigGetter) GetAndFlagSecretData(configID string) (*api.Config, bool, error) {
 	if t.dependencies == nil {
-		return nil, errors.New("no config provider available")
+		return nil, false, errors.New("no config provider available")
 	}
 
 	configs := t.dependencies.Configs()
 	if configs == nil {
-		return nil, errors.New("no config provider available")
+		return nil, false, errors.New("no config provider available")
 	}
 
 	config, err := configs.Get(configID)
 	if err != nil {
-		return config, err
+		return config, false, err
 	}
 
-	newSpec, err := ExpandConfigSpec(config, t.node, t.t, t.dependencies)
+	newSpec, sensitive, err := ExpandConfigSpec(config, t.node, t.t, t.dependencies)
 	if err != nil {
-		return config, errors.Wrapf(err, "failed to expand templated config %s", configID)
+		return config, false, errors.Wrapf(err, "failed to expand templated config %s", configID)
 	}
 
 	configCopy := *config
 	configCopy.Spec = *newSpec
-	return &configCopy, nil
+	return &configCopy, sensitive, nil
 }
 
 type templatedDependencyGetter struct {
 	secrets exec.SecretGetter
-	configs exec.ConfigGetter
+	configs TemplatedConfigGetter
 }
 
 // NewTemplatedDependencyGetter returns a DependencyGetter that evaluates templates.
diff --git a/vendor/github.com/docker/swarmkit/vendor.conf b/vendor/github.com/docker/swarmkit/vendor.conf
index 73692ee..abb1a6c 100644
--- a/vendor/github.com/docker/swarmkit/vendor.conf
+++ b/vendor/github.com/docker/swarmkit/vendor.conf
@@ -19,26 +19,27 @@
 github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5
 
 github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621
-github.com/docker/docker 77c9728847358a3ed3581d828fb0753017e1afd3
-github.com/docker/go-connections 34b5052da6b11e27f5f2e357b38b571ddddd3928
-github.com/docker/go-events 37d35add5005832485c0225ec870121b78fcff1c
+github.com/docker/docker 8af4db6f002ac907b6ef8610b237879dfcaa5b7a
+github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
+github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
 github.com/docker/go-units 954fed01cc617c55d838fa2230073f2cb17386c8
 github.com/docker/libkv 9fd56606e928ff1f309808f5d5a0b7a2ef73f9a8
-github.com/docker/libnetwork 37e20af882e13dd01ade3658b7aabdae3412118b
+github.com/docker/libnetwork 19ac3ea7f52bb46e0eb10669756cdae0c441a5b1 
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
-github.com/opencontainers/runc b6b70e53451794e8333e9b602cc096b47a20bd0f
-github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb
-github.com/opencontainers/image-spec 372ad780f63454fbbbbcc7cf80e5b90245c13e13
+github.com/opencontainers/runc d40db12e72a40109dfcf28539f5ee0930d2f0277
+github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448 
+github.com/opencontainers/image-spec v1.0.0
 
 # containerd executor
-github.com/containerd/containerd 76697ac8cbf357a19beb58e4805a81fe48cf7974
+github.com/containerd/containerd 29a4dd7f46e0780d0bff2a237dc600a5b90a4dd5
 github.com/containerd/fifo 69b99525e472735860a5269b75af1970142b3062
-github.com/opencontainers/runtime-spec v1.0.0-rc5
+github.com/opencontainers/runtime-spec v1.0.0
 golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
+github.com/containerd/continuity cf279e6ac893682272b4479d4c67fd3abf878b4e
 
 github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
 github.com/Microsoft/go-winio v0.4.2
-github.com/Sirupsen/logrus v0.11.0
+github.com/sirupsen/logrus v1.0.1
 github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
 github.com/boltdb/bolt e72f08ddb5a52992c0a44c7dda9316c7333938b2
 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a
@@ -58,6 +59,6 @@
 github.com/stretchr/testify v1.1.4
 golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2
 golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6
-golang.org/x/sys 5eaf0df67e70d6997a9fe0ed24383fa1b01638d3
+golang.org/x/sys 739734461d1c916b6c72a63d7efda2b27edb369f
 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756
 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb
diff --git a/vendor/github.com/docker/swarmkit/watch/queue/queue.go b/vendor/github.com/docker/swarmkit/watch/queue/queue.go
index 10bdb92..bb6f92d 100644
--- a/vendor/github.com/docker/swarmkit/watch/queue/queue.go
+++ b/vendor/github.com/docker/swarmkit/watch/queue/queue.go
@@ -5,8 +5,8 @@
 	"fmt"
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/go-events"
+	"github.com/sirupsen/logrus"
 )
 
 // ErrQueueFull is returned by a Write operation when that Write causes the
diff --git a/vendor/github.com/fsnotify/fsnotify/README.md b/vendor/github.com/fsnotify/fsnotify/README.md
index fee2a36..3c891e3 100644
--- a/vendor/github.com/fsnotify/fsnotify/README.md
+++ b/vendor/github.com/fsnotify/fsnotify/README.md
@@ -1,8 +1,12 @@
 # File system notifications for Go
 
-[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify) [![Coverage](http://gocover.io/_badge/github.com/fsnotify/fsnotify)](http://gocover.io/github.com/fsnotify/fsnotify) 
+[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify)
 
-Go 1.3+ required.
+fsnotify utilizes [golang.org/x/sys](https://godoc.org/golang.org/x/sys) rather than `syscall` from the standard library. Ensure you have the latest version installed by running:
+
+```console
+go get -u golang.org/x/sys/...
+```
 
 Cross platform: Windows, Linux, BSD and OS X.
 
@@ -27,7 +31,7 @@
 
 All [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/). Further API changes are [planned](https://github.com/fsnotify/fsnotify/milestones), and will be tagged with a new major revision number.
 
-Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project.
+Go 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.
 
 ## Contributing
 
diff --git a/vendor/github.com/fsnotify/fsnotify/fsnotify.go b/vendor/github.com/fsnotify/fsnotify/fsnotify.go
index d1d39a0..e7f55fe 100644
--- a/vendor/github.com/fsnotify/fsnotify/fsnotify.go
+++ b/vendor/github.com/fsnotify/fsnotify/fsnotify.go
@@ -30,33 +30,33 @@
 	Chmod
 )
 
-// String returns a string representation of the event in the form
-// "file: REMOVE|WRITE|..."
-func (e Event) String() string {
+func (op Op) String() string {
 	// Use a buffer for efficient string concatenation
 	var buffer bytes.Buffer
 
-	if e.Op&Create == Create {
+	if op&Create == Create {
 		buffer.WriteString("|CREATE")
 	}
-	if e.Op&Remove == Remove {
+	if op&Remove == Remove {
 		buffer.WriteString("|REMOVE")
 	}
-	if e.Op&Write == Write {
+	if op&Write == Write {
 		buffer.WriteString("|WRITE")
 	}
-	if e.Op&Rename == Rename {
+	if op&Rename == Rename {
 		buffer.WriteString("|RENAME")
 	}
-	if e.Op&Chmod == Chmod {
+	if op&Chmod == Chmod {
 		buffer.WriteString("|CHMOD")
 	}
-
-	// If buffer remains empty, return no event names
 	if buffer.Len() == 0 {
-		return fmt.Sprintf("%q: ", e.Name)
+		return ""
 	}
+	return buffer.String()[1:] // Strip leading pipe
+}
 
-	// Return a list of event names, with leading pipe character stripped
-	return fmt.Sprintf("%q: %s", e.Name, buffer.String()[1:])
+// String returns a string representation of the event in the form
+// "file: REMOVE|WRITE|..."
+func (e Event) String() string {
+	return fmt.Sprintf("%q: %s", e.Name, e.Op.String())
 }
diff --git a/vendor/github.com/fsnotify/fsnotify/inotify.go b/vendor/github.com/fsnotify/fsnotify/inotify.go
index 780b2a0..f3b74c5 100644
--- a/vendor/github.com/fsnotify/fsnotify/inotify.go
+++ b/vendor/github.com/fsnotify/fsnotify/inotify.go
@@ -14,8 +14,9 @@
 	"path/filepath"
 	"strings"
 	"sync"
-	"syscall"
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 // Watcher watches a set of files, delivering events to a channel.
@@ -35,14 +36,14 @@
 // NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.
 func NewWatcher() (*Watcher, error) {
 	// Create inotify fd
-	fd, errno := syscall.InotifyInit()
+	fd, errno := unix.InotifyInit1(unix.IN_CLOEXEC)
 	if fd == -1 {
 		return nil, errno
 	}
 	// Create epoll
 	poller, err := newFdPoller(fd)
 	if err != nil {
-		syscall.Close(fd)
+		unix.Close(fd)
 		return nil, err
 	}
 	w := &Watcher{
@@ -95,9 +96,9 @@
 		return errors.New("inotify instance already closed")
 	}
 
-	const agnosticEvents = syscall.IN_MOVED_TO | syscall.IN_MOVED_FROM |
-		syscall.IN_CREATE | syscall.IN_ATTRIB | syscall.IN_MODIFY |
-		syscall.IN_MOVE_SELF | syscall.IN_DELETE | syscall.IN_DELETE_SELF
+	const agnosticEvents = unix.IN_MOVED_TO | unix.IN_MOVED_FROM |
+		unix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY |
+		unix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF
 
 	var flags uint32 = agnosticEvents
 
@@ -106,9 +107,9 @@
 	w.mu.Unlock()
 	if found {
 		watchEntry.flags |= flags
-		flags |= syscall.IN_MASK_ADD
+		flags |= unix.IN_MASK_ADD
 	}
-	wd, errno := syscall.InotifyAddWatch(w.fd, name, flags)
+	wd, errno := unix.InotifyAddWatch(w.fd, name, flags)
 	if wd == -1 {
 		return errno
 	}
@@ -140,7 +141,7 @@
 	// by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE
 	// so that EINVAL means that the wd is being rm_watch()ed or its file removed
 	// by another thread and we have not received IN_IGNORE event.
-	success, errno := syscall.InotifyRmWatch(w.fd, watch.wd)
+	success, errno := unix.InotifyRmWatch(w.fd, watch.wd)
 	if success == -1 {
 		// TODO: Perhaps it's not helpful to return an error here in every case.
 		// the only two possible errors are:
@@ -170,16 +171,16 @@
 // received events into Event objects and sends them via the Events channel
 func (w *Watcher) readEvents() {
 	var (
-		buf   [syscall.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
-		n     int                                     // Number of bytes read with read()
-		errno error                                   // Syscall errno
-		ok    bool                                    // For poller.wait
+		buf   [unix.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events
+		n     int                                  // Number of bytes read with read()
+		errno error                                // Syscall errno
+		ok    bool                                 // For poller.wait
 	)
 
 	defer close(w.doneResp)
 	defer close(w.Errors)
 	defer close(w.Events)
-	defer syscall.Close(w.fd)
+	defer unix.Close(w.fd)
 	defer w.poller.close()
 
 	for {
@@ -202,20 +203,20 @@
 			continue
 		}
 
-		n, errno = syscall.Read(w.fd, buf[:])
+		n, errno = unix.Read(w.fd, buf[:])
 		// If a signal interrupted execution, see if we've been asked to close, and try again.
 		// http://man7.org/linux/man-pages/man7/signal.7.html :
 		// "Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable"
-		if errno == syscall.EINTR {
+		if errno == unix.EINTR {
 			continue
 		}
 
-		// syscall.Read might have been woken up by Close. If so, we're done.
+		// unix.Read might have been woken up by Close. If so, we're done.
 		if w.isClosed() {
 			return
 		}
 
-		if n < syscall.SizeofInotifyEvent {
+		if n < unix.SizeofInotifyEvent {
 			var err error
 			if n == 0 {
 				// If EOF is received. This should really never happen.
@@ -238,9 +239,9 @@
 		var offset uint32
 		// We don't know how many events we just read into the buffer
 		// While the offset points to at least one whole event...
-		for offset <= uint32(n-syscall.SizeofInotifyEvent) {
+		for offset <= uint32(n-unix.SizeofInotifyEvent) {
 			// Point "raw" to the event in the buffer
-			raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset]))
+			raw := (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset]))
 
 			mask := uint32(raw.Mask)
 			nameLen := uint32(raw.Len)
@@ -253,7 +254,7 @@
 			w.mu.Unlock()
 			if nameLen > 0 {
 				// Point "bytes" at the first byte of the filename
-				bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent]))
+				bytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))
 				// The filename is padded with NULL bytes. TrimRight() gets rid of those.
 				name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000")
 			}
@@ -270,7 +271,7 @@
 			}
 
 			// Move to the next event in the buffer
-			offset += syscall.SizeofInotifyEvent + nameLen
+			offset += unix.SizeofInotifyEvent + nameLen
 		}
 	}
 }
@@ -280,7 +281,7 @@
 // against files that do not exist.
 func (e *Event) ignoreLinux(w *Watcher, wd int32, mask uint32) bool {
 	// Ignore anything the inotify API says to ignore
-	if mask&syscall.IN_IGNORED == syscall.IN_IGNORED {
+	if mask&unix.IN_IGNORED == unix.IN_IGNORED {
 		w.mu.Lock()
 		defer w.mu.Unlock()
 		name := w.paths[int(wd)]
@@ -305,19 +306,19 @@
 // newEvent returns an platform-independent Event based on an inotify mask.
 func newEvent(name string, mask uint32) Event {
 	e := Event{Name: name}
-	if mask&syscall.IN_CREATE == syscall.IN_CREATE || mask&syscall.IN_MOVED_TO == syscall.IN_MOVED_TO {
+	if mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO {
 		e.Op |= Create
 	}
-	if mask&syscall.IN_DELETE_SELF == syscall.IN_DELETE_SELF || mask&syscall.IN_DELETE == syscall.IN_DELETE {
+	if mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF || mask&unix.IN_DELETE == unix.IN_DELETE {
 		e.Op |= Remove
 	}
-	if mask&syscall.IN_MODIFY == syscall.IN_MODIFY {
+	if mask&unix.IN_MODIFY == unix.IN_MODIFY {
 		e.Op |= Write
 	}
-	if mask&syscall.IN_MOVE_SELF == syscall.IN_MOVE_SELF || mask&syscall.IN_MOVED_FROM == syscall.IN_MOVED_FROM {
+	if mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM {
 		e.Op |= Rename
 	}
-	if mask&syscall.IN_ATTRIB == syscall.IN_ATTRIB {
+	if mask&unix.IN_ATTRIB == unix.IN_ATTRIB {
 		e.Op |= Chmod
 	}
 	return e
diff --git a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
index 23a5ca1..cc7db4b 100644
--- a/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
+++ b/vendor/github.com/fsnotify/fsnotify/inotify_poller.go
@@ -8,7 +8,8 @@
 
 import (
 	"errors"
-	"syscall"
+
+	"golang.org/x/sys/unix"
 )
 
 type fdPoller struct {
@@ -39,32 +40,32 @@
 	poller.fd = fd
 
 	// Create epoll fd
-	poller.epfd, errno = syscall.EpollCreate1(0)
+	poller.epfd, errno = unix.EpollCreate1(0)
 	if poller.epfd == -1 {
 		return nil, errno
 	}
 	// Create pipe; pipe[0] is the read end, pipe[1] the write end.
-	errno = syscall.Pipe2(poller.pipe[:], syscall.O_NONBLOCK)
+	errno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK)
 	if errno != nil {
 		return nil, errno
 	}
 
 	// Register inotify fd with epoll
-	event := syscall.EpollEvent{
+	event := unix.EpollEvent{
 		Fd:     int32(poller.fd),
-		Events: syscall.EPOLLIN,
+		Events: unix.EPOLLIN,
 	}
-	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.fd, &event)
+	errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.fd, &event)
 	if errno != nil {
 		return nil, errno
 	}
 
 	// Register pipe fd with epoll
-	event = syscall.EpollEvent{
+	event = unix.EpollEvent{
 		Fd:     int32(poller.pipe[0]),
-		Events: syscall.EPOLLIN,
+		Events: unix.EPOLLIN,
 	}
-	errno = syscall.EpollCtl(poller.epfd, syscall.EPOLL_CTL_ADD, poller.pipe[0], &event)
+	errno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.pipe[0], &event)
 	if errno != nil {
 		return nil, errno
 	}
@@ -80,11 +81,11 @@
 	// I don't know whether epoll_wait returns the number of events returned,
 	// or the total number of events ready.
 	// I decided to catch both by making the buffer one larger than the maximum.
-	events := make([]syscall.EpollEvent, 7)
+	events := make([]unix.EpollEvent, 7)
 	for {
-		n, errno := syscall.EpollWait(poller.epfd, events, -1)
+		n, errno := unix.EpollWait(poller.epfd, events, -1)
 		if n == -1 {
-			if errno == syscall.EINTR {
+			if errno == unix.EINTR {
 				continue
 			}
 			return false, errno
@@ -103,31 +104,31 @@
 		epollin := false
 		for _, event := range ready {
 			if event.Fd == int32(poller.fd) {
-				if event.Events&syscall.EPOLLHUP != 0 {
+				if event.Events&unix.EPOLLHUP != 0 {
 					// This should not happen, but if it does, treat it as a wakeup.
 					epollhup = true
 				}
-				if event.Events&syscall.EPOLLERR != 0 {
+				if event.Events&unix.EPOLLERR != 0 {
 					// If an error is waiting on the file descriptor, we should pretend
-					// something is ready to read, and let syscall.Read pick up the error.
+					// something is ready to read, and let unix.Read pick up the error.
 					epollerr = true
 				}
-				if event.Events&syscall.EPOLLIN != 0 {
+				if event.Events&unix.EPOLLIN != 0 {
 					// There is data to read.
 					epollin = true
 				}
 			}
 			if event.Fd == int32(poller.pipe[0]) {
-				if event.Events&syscall.EPOLLHUP != 0 {
+				if event.Events&unix.EPOLLHUP != 0 {
 					// Write pipe descriptor was closed, by us. This means we're closing down the
 					// watcher, and we should wake up.
 				}
-				if event.Events&syscall.EPOLLERR != 0 {
+				if event.Events&unix.EPOLLERR != 0 {
 					// If an error is waiting on the pipe file descriptor.
 					// This is an absolute mystery, and should never ever happen.
 					return false, errors.New("Error on the pipe descriptor.")
 				}
-				if event.Events&syscall.EPOLLIN != 0 {
+				if event.Events&unix.EPOLLIN != 0 {
 					// This is a regular wakeup, so we have to clear the buffer.
 					err := poller.clearWake()
 					if err != nil {
@@ -147,9 +148,9 @@
 // Close the write end of the poller.
 func (poller *fdPoller) wake() error {
 	buf := make([]byte, 1)
-	n, errno := syscall.Write(poller.pipe[1], buf)
+	n, errno := unix.Write(poller.pipe[1], buf)
 	if n == -1 {
-		if errno == syscall.EAGAIN {
+		if errno == unix.EAGAIN {
 			// Buffer is full, poller will wake.
 			return nil
 		}
@@ -161,9 +162,9 @@
 func (poller *fdPoller) clearWake() error {
 	// You have to be woken up a LOT in order to get to 100!
 	buf := make([]byte, 100)
-	n, errno := syscall.Read(poller.pipe[0], buf)
+	n, errno := unix.Read(poller.pipe[0], buf)
 	if n == -1 {
-		if errno == syscall.EAGAIN {
+		if errno == unix.EAGAIN {
 			// Buffer is empty, someone else cleared our wake.
 			return nil
 		}
@@ -175,12 +176,12 @@
 // Close all poller file descriptors, but not the one passed to it.
 func (poller *fdPoller) close() {
 	if poller.pipe[1] != -1 {
-		syscall.Close(poller.pipe[1])
+		unix.Close(poller.pipe[1])
 	}
 	if poller.pipe[0] != -1 {
-		syscall.Close(poller.pipe[0])
+		unix.Close(poller.pipe[0])
 	}
 	if poller.epfd != -1 {
-		syscall.Close(poller.epfd)
+		unix.Close(poller.epfd)
 	}
 }
diff --git a/vendor/github.com/fsnotify/fsnotify/kqueue.go b/vendor/github.com/fsnotify/fsnotify/kqueue.go
index b8ea308..c2b4acb 100644
--- a/vendor/github.com/fsnotify/fsnotify/kqueue.go
+++ b/vendor/github.com/fsnotify/fsnotify/kqueue.go
@@ -13,8 +13,9 @@
 	"os"
 	"path/filepath"
 	"sync"
-	"syscall"
 	"time"
+
+	"golang.org/x/sys/unix"
 )
 
 // Watcher watches a set of files, delivering events to a channel.
@@ -113,12 +114,12 @@
 		return fmt.Errorf("can't remove non-existent kevent watch for: %s", name)
 	}
 
-	const registerRemove = syscall.EV_DELETE
+	const registerRemove = unix.EV_DELETE
 	if err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil {
 		return err
 	}
 
-	syscall.Close(watchfd)
+	unix.Close(watchfd)
 
 	w.mu.Lock()
 	isDir := w.paths[watchfd].isDir
@@ -152,7 +153,7 @@
 }
 
 // Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)
-const noteAllEvents = syscall.NOTE_DELETE | syscall.NOTE_WRITE | syscall.NOTE_ATTRIB | syscall.NOTE_RENAME
+const noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME
 
 // keventWaitTime to block on each read from kevent
 var keventWaitTime = durationToTimespec(100 * time.Millisecond)
@@ -219,7 +220,7 @@
 			}
 		}
 
-		watchfd, err = syscall.Open(name, openMode, 0700)
+		watchfd, err = unix.Open(name, openMode, 0700)
 		if watchfd == -1 {
 			return "", err
 		}
@@ -227,9 +228,9 @@
 		isDir = fi.IsDir()
 	}
 
-	const registerAdd = syscall.EV_ADD | syscall.EV_CLEAR | syscall.EV_ENABLE
+	const registerAdd = unix.EV_ADD | unix.EV_CLEAR | unix.EV_ENABLE
 	if err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil {
-		syscall.Close(watchfd)
+		unix.Close(watchfd)
 		return "", err
 	}
 
@@ -245,8 +246,8 @@
 		// or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)
 		w.mu.Lock()
 
-		watchDir := (flags&syscall.NOTE_WRITE) == syscall.NOTE_WRITE &&
-			(!alreadyWatching || (w.dirFlags[name]&syscall.NOTE_WRITE) != syscall.NOTE_WRITE)
+		watchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE &&
+			(!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE)
 		// Store flags so this watch can be updated later
 		w.dirFlags[name] = flags
 		w.mu.Unlock()
@@ -263,13 +264,13 @@
 // readEvents reads from kqueue and converts the received kevents into
 // Event values that it sends down the Events channel.
 func (w *Watcher) readEvents() {
-	eventBuffer := make([]syscall.Kevent_t, 10)
+	eventBuffer := make([]unix.Kevent_t, 10)
 
 	for {
 		// See if there is a message on the "done" channel
 		select {
 		case <-w.done:
-			err := syscall.Close(w.kq)
+			err := unix.Close(w.kq)
 			if err != nil {
 				w.Errors <- err
 			}
@@ -282,7 +283,7 @@
 		// Get new events
 		kevents, err := read(w.kq, eventBuffer, &keventWaitTime)
 		// EINTR is okay, the syscall was interrupted before timeout expired.
-		if err != nil && err != syscall.EINTR {
+		if err != nil && err != unix.EINTR {
 			w.Errors <- err
 			continue
 		}
@@ -356,16 +357,16 @@
 // newEvent returns an platform-independent Event based on kqueue Fflags.
 func newEvent(name string, mask uint32) Event {
 	e := Event{Name: name}
-	if mask&syscall.NOTE_DELETE == syscall.NOTE_DELETE {
+	if mask&unix.NOTE_DELETE == unix.NOTE_DELETE {
 		e.Op |= Remove
 	}
-	if mask&syscall.NOTE_WRITE == syscall.NOTE_WRITE {
+	if mask&unix.NOTE_WRITE == unix.NOTE_WRITE {
 		e.Op |= Write
 	}
-	if mask&syscall.NOTE_RENAME == syscall.NOTE_RENAME {
+	if mask&unix.NOTE_RENAME == unix.NOTE_RENAME {
 		e.Op |= Rename
 	}
-	if mask&syscall.NOTE_ATTRIB == syscall.NOTE_ATTRIB {
+	if mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB {
 		e.Op |= Chmod
 	}
 	return e
@@ -451,7 +452,7 @@
 		flags := w.dirFlags[name]
 		w.mu.Unlock()
 
-		flags |= syscall.NOTE_DELETE | syscall.NOTE_RENAME
+		flags |= unix.NOTE_DELETE | unix.NOTE_RENAME
 		return w.addWatch(name, flags)
 	}
 
@@ -461,7 +462,7 @@
 
 // kqueue creates a new kernel event queue and returns a descriptor.
 func kqueue() (kq int, err error) {
-	kq, err = syscall.Kqueue()
+	kq, err = unix.Kqueue()
 	if kq == -1 {
 		return kq, err
 	}
@@ -470,16 +471,16 @@
 
 // register events with the queue
 func register(kq int, fds []int, flags int, fflags uint32) error {
-	changes := make([]syscall.Kevent_t, len(fds))
+	changes := make([]unix.Kevent_t, len(fds))
 
 	for i, fd := range fds {
 		// SetKevent converts int to the platform-specific types:
-		syscall.SetKevent(&changes[i], fd, syscall.EVFILT_VNODE, flags)
+		unix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags)
 		changes[i].Fflags = fflags
 	}
 
 	// register the events
-	success, err := syscall.Kevent(kq, changes, nil, nil)
+	success, err := unix.Kevent(kq, changes, nil, nil)
 	if success == -1 {
 		return err
 	}
@@ -488,8 +489,8 @@
 
 // read retrieves pending events, or waits until an event occurs.
 // A timeout of nil blocks indefinitely, while 0 polls the queue.
-func read(kq int, events []syscall.Kevent_t, timeout *syscall.Timespec) ([]syscall.Kevent_t, error) {
-	n, err := syscall.Kevent(kq, nil, events, timeout)
+func read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]unix.Kevent_t, error) {
+	n, err := unix.Kevent(kq, nil, events, timeout)
 	if err != nil {
 		return nil, err
 	}
@@ -497,6 +498,6 @@
 }
 
 // durationToTimespec prepares a timeout value
-func durationToTimespec(d time.Duration) syscall.Timespec {
-	return syscall.NsecToTimespec(d.Nanoseconds())
+func durationToTimespec(d time.Duration) unix.Timespec {
+	return unix.NsecToTimespec(d.Nanoseconds())
 }
diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
index c57ccb4..7d8de14 100644
--- a/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
+++ b/vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go
@@ -6,6 +6,6 @@
 
 package fsnotify
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
-const openMode = syscall.O_NONBLOCK | syscall.O_RDONLY
+const openMode = unix.O_NONBLOCK | unix.O_RDONLY
diff --git a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
index 174b2c3..9139e17 100644
--- a/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
+++ b/vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go
@@ -6,7 +6,7 @@
 
 package fsnotify
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
 // note: this constant is not defined on BSD
-const openMode = syscall.O_EVTONLY
+const openMode = unix.O_EVTONLY
diff --git a/vendor/github.com/fsnotify/fsnotify/windows.go b/vendor/github.com/fsnotify/fsnotify/windows.go
index c836bdb..09436f3 100644
--- a/vendor/github.com/fsnotify/fsnotify/windows.go
+++ b/vendor/github.com/fsnotify/fsnotify/windows.go
@@ -306,7 +306,7 @@
 		watch.mask = 0
 	} else {
 		name := filepath.Base(pathname)
-		w.sendEvent(watch.path+"\\"+name, watch.names[name]&sysFSIGNORED)
+		w.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED)
 		delete(watch.names, name)
 	}
 	return w.startRead(watch)
@@ -316,7 +316,7 @@
 func (w *Watcher) deleteWatch(watch *watch) {
 	for name, mask := range watch.names {
 		if mask&provisional == 0 {
-			w.sendEvent(watch.path+"\\"+name, mask&sysFSIGNORED)
+			w.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED)
 		}
 		delete(watch.names, name)
 	}
@@ -453,7 +453,7 @@
 			raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset]))
 			buf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName))
 			name := syscall.UTF16ToString(buf[:raw.FileNameLength/2])
-			fullname := watch.path + "\\" + name
+			fullname := filepath.Join(watch.path, name)
 
 			var mask uint64
 			switch raw.Action {
@@ -491,7 +491,7 @@
 				}
 			}
 			if raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME {
-				fullname = watch.path + "\\" + watch.rename
+				fullname = filepath.Join(watch.path, watch.rename)
 				sendNameEvent()
 			}
 
diff --git a/vendor/github.com/gotestyourself/gotestyourself/LICENSE b/vendor/github.com/gotestyourself/gotestyourself/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/LICENSE
@@ -0,0 +1,202 @@
+
+                                 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/gotestyourself/gotestyourself/README.md b/vendor/github.com/gotestyourself/gotestyourself/README.md
new file mode 100644
index 0000000..037fba6
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/README.md
@@ -0,0 +1,33 @@
+# Go Test Yourself
+
+A collection of packages compatible with `go test` to support common testing
+patterns.
+
+[![GoDoc](https://godoc.org/github.com/gotestyourself/gotestyourself?status.svg)](https://godoc.org/github.com/gotestyourself/gotestyourself)
+[![CircleCI](https://circleci.com/gh/gotestyourself/gotestyourself/tree/master.svg?style=shield)](https://circleci.com/gh/gotestyourself/gotestyourself/tree/master)
+[![Go Reportcard](https://goreportcard.com/badge/github.com/gotestyourself/gotestyourself)](https://goreportcard.com/report/github.com/gotestyourself/gotestyourself)
+
+
+## Packages
+
+* [fs](http://godoc.org/github.com/gotestyourself/gotestyourself/fs) -
+  create test files and directories
+* [golden](http://godoc.org/github.com/gotestyourself/gotestyourself/golden) -
+  compare large multi-line strings
+* [testsum](http://godoc.org/github.com/gotestyourself/gotestyourself/testsum) -
+  a program to summarize `go test` output and test failures
+* [icmd](http://godoc.org/github.com/gotestyourself/gotestyourself/icmd) -
+  execute binaries and test the output
+* [poll](http://godoc.org/github.com/gotestyourself/gotestyourself/poll) -
+  test asynchronous code by polling until a desired state is reached
+* [skip](http://godoc.org/github.com/gotestyourself/gotestyourself/skip) -
+  skip tests based on conditions
+
+## Related
+
+* [testify/assert](https://godoc.org/github.com/stretchr/testify/assert) and 
+  [testify/require](https://godoc.org/github.com/stretchr/testify/require) -
+  assertion libraries with common assertions
+* [golang/mock](https://github.com/golang/mock) - generate mocks for interfaces
+* [testify/suite](https://godoc.org/github.com/stretchr/testify/suite) - 
+  group test into suites to share common setup/teardown logic
diff --git a/vendor/github.com/gotestyourself/gotestyourself/fs/file.go b/vendor/github.com/gotestyourself/gotestyourself/fs/file.go
new file mode 100644
index 0000000..dcda10a
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/fs/file.go
@@ -0,0 +1,81 @@
+/*Package fs provides tools for creating and working with temporary files and
+directories.
+*/
+package fs
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+
+	"github.com/stretchr/testify/require"
+)
+
+// Path objects return their filesystem path. Both File and Dir implement Path.
+type Path interface {
+	Path() string
+}
+
+// File is a temporary file on the filesystem
+type File struct {
+	path string
+}
+
+// NewFile creates a new file in a temporary directory using prefix as part of
+// the filename. The PathOps are applied to the before returning the File.
+func NewFile(t require.TestingT, prefix string, ops ...PathOp) *File {
+	tempfile, err := ioutil.TempFile("", prefix+"-")
+	require.NoError(t, err)
+	file := &File{path: tempfile.Name()}
+	require.NoError(t, tempfile.Close())
+
+	for _, op := range ops {
+		require.NoError(t, op(file))
+	}
+	return file
+}
+
+// Path returns the full path to the file
+func (f *File) Path() string {
+	return f.path
+}
+
+// Remove the file
+func (f *File) Remove() {
+	// nolint: errcheck
+	os.Remove(f.path)
+}
+
+// Dir is a temporary directory
+type Dir struct {
+	path string
+}
+
+// NewDir returns a new temporary directory using prefix as part of the directory
+// name. The PathOps are applied before returning the Dir.
+func NewDir(t require.TestingT, prefix string, ops ...PathOp) *Dir {
+	path, err := ioutil.TempDir("", prefix+"-")
+	require.NoError(t, err)
+	dir := &Dir{path: path}
+
+	for _, op := range ops {
+		require.NoError(t, op(dir))
+	}
+	return dir
+}
+
+// Path returns the full path to the directory
+func (d *Dir) Path() string {
+	return d.path
+}
+
+// Remove the directory
+func (d *Dir) Remove() {
+	// nolint: errcheck
+	os.RemoveAll(d.path)
+}
+
+// Join returns a new path with this directory as the base of the path
+func (d *Dir) Join(parts ...string) string {
+	return filepath.Join(append([]string{d.Path()}, parts...)...)
+}
diff --git a/vendor/github.com/gotestyourself/gotestyourself/fs/ops.go b/vendor/github.com/gotestyourself/gotestyourself/fs/ops.go
new file mode 100644
index 0000000..4fbc40f
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/fs/ops.go
@@ -0,0 +1,94 @@
+package fs
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+)
+
+// PathOp is a function which accepts a Path to perform some operation
+type PathOp func(path Path) error
+
+// WithContent writes content to a file at Path
+func WithContent(content string) PathOp {
+	return func(path Path) error {
+		return ioutil.WriteFile(path.Path(), []byte(content), 0644)
+	}
+}
+
+// WithBytes write bytes to a file at Path
+func WithBytes(raw []byte) PathOp {
+	return func(path Path) error {
+		return ioutil.WriteFile(path.Path(), raw, 0644)
+	}
+}
+
+// AsUser changes ownership of the file system object at Path
+func AsUser(uid, gid int) PathOp {
+	return func(path Path) error {
+		return os.Chown(path.Path(), uid, gid)
+	}
+}
+
+// WithFile creates a file in the directory at path with content
+func WithFile(filename, content string) PathOp {
+	return func(path Path) error {
+		return createFile(path.Path(), filename, content)
+	}
+}
+
+func createFile(dir, filename, content string) error {
+	fullpath := filepath.Join(dir, filepath.FromSlash(filename))
+	return ioutil.WriteFile(fullpath, []byte(content), 0644)
+}
+
+// WithFiles creates all the files in the directory at path with their content
+func WithFiles(files map[string]string) PathOp {
+	return func(path Path) error {
+		for filename, content := range files {
+			if err := createFile(path.Path(), filename, content); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+}
+
+// FromDir copies the directory tree from the source path into the new Dir
+func FromDir(source string) PathOp {
+	return func(path Path) error {
+		return copyDirectory(source, path.Path())
+	}
+}
+
+func copyDirectory(source, dest string) error {
+	entries, err := ioutil.ReadDir(source)
+	if err != nil {
+		return err
+	}
+	for _, entry := range entries {
+		sourcePath := filepath.Join(source, entry.Name())
+		destPath := filepath.Join(dest, entry.Name())
+		if entry.IsDir() {
+			if err := os.Mkdir(destPath, 0755); err != nil {
+				return err
+			}
+			if err := copyDirectory(sourcePath, destPath); err != nil {
+				return err
+			}
+			continue
+		}
+		if err := copyFile(sourcePath, destPath); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func copyFile(source, dest string) error {
+	content, err := ioutil.ReadFile(source)
+	if err != nil {
+		return err
+	}
+	return ioutil.WriteFile(dest, content, 0644)
+}
diff --git a/pkg/testutil/cmd/command.go b/vendor/github.com/gotestyourself/gotestyourself/icmd/command.go
similarity index 78%
rename from pkg/testutil/cmd/command.go
rename to vendor/github.com/gotestyourself/gotestyourself/icmd/command.go
index 6f36d67..8729457 100644
--- a/pkg/testutil/cmd/command.go
+++ b/vendor/github.com/gotestyourself/gotestyourself/icmd/command.go
@@ -1,4 +1,6 @@
-package cmd
+/*Package icmd executes binaries and provides convenient assertions for testing the results.
+ */
+package icmd
 
 import (
 	"bytes"
@@ -10,19 +12,14 @@
 	"strings"
 	"sync"
 	"time"
-
-	"github.com/docker/docker/pkg/system"
-	"github.com/go-check/check"
 )
 
 type testingT interface {
 	Fatalf(string, ...interface{})
 }
 
-const (
-	// None is a token to inform Result.Assert that the output should be empty
-	None string = "<NOTHING>"
-)
+// None is a token to inform Result.Assert that the output should be empty
+const None string = "[NOTHING]"
 
 type lockedBuffer struct {
 	m   sync.RWMutex
@@ -61,7 +58,7 @@
 	}
 	_, file, line, ok := runtime.Caller(1)
 	if ok {
-		t.Fatalf("at %s:%d - %s", filepath.Base(file), line, err.Error())
+		t.Fatalf("at %s:%d - %s\n", filepath.Base(file), line, err.Error())
 	} else {
 		t.Fatalf("(no file/line info) - %s", err.Error())
 	}
@@ -70,6 +67,7 @@
 
 // Compare returns a formatted error with the command, stdout, stderr, exit
 // code, and any failed expectations
+// nolint: gocyclo
 func (r *Result) Compare(exp Expected) error {
 	errors := []string{}
 	add := func(format string, args ...interface{}) {
@@ -108,7 +106,7 @@
 	if len(errors) == 0 {
 		return nil
 	}
-	return fmt.Errorf("%s\nFailures:\n%s\n", r, strings.Join(errors, "\n"))
+	return fmt.Errorf("%s\nFailures:\n%s", r, strings.Join(errors, "\n"))
 }
 
 func matchOutput(expected string, actual string) bool {
@@ -151,7 +149,8 @@
 	Err      string
 }
 
-// Success is the default expected result
+// Success is the default expected result. A Success result is one with a 0
+// ExitCode.
 var Success = Expected{}
 
 // Stdout returns the stdout of the process as a string
@@ -169,46 +168,14 @@
 	return r.outBuffer.String() + r.errBuffer.String()
 }
 
-// SetExitError sets Error and ExitCode based on Error
-func (r *Result) SetExitError(err error) {
+func (r *Result) setExitError(err error) {
 	if err == nil {
 		return
 	}
 	r.Error = err
-	r.ExitCode = system.ProcessExitCode(err)
+	r.ExitCode = processExitCode(err)
 }
 
-type matches struct{}
-
-// Info returns the CheckerInfo
-func (m *matches) Info() *check.CheckerInfo {
-	return &check.CheckerInfo{
-		Name:   "CommandMatches",
-		Params: []string{"result", "expected"},
-	}
-}
-
-// Check compares a result against the expected
-func (m *matches) Check(params []interface{}, names []string) (bool, string) {
-	result, ok := params[0].(*Result)
-	if !ok {
-		return false, fmt.Sprintf("result must be a *Result, not %T", params[0])
-	}
-	expected, ok := params[1].(Expected)
-	if !ok {
-		return false, fmt.Sprintf("expected must be an Expected, not %T", params[1])
-	}
-
-	err := result.Compare(expected)
-	if err == nil {
-		return true, ""
-	}
-	return false, err.Error()
-}
-
-// Matches is a gocheck.Checker for comparing a Result against an Expected
-var Matches = &matches{}
-
 // Cmd contains the arguments and options for a process to run as part of a test
 // suite.
 type Cmd struct {
@@ -226,7 +193,7 @@
 }
 
 // RunCmd runs a command and returns a Result
-func RunCmd(cmd Cmd, cmdOperators ...func(*Cmd)) *Result {
+func RunCmd(cmd Cmd, cmdOperators ...CmdOp) *Result {
 	for _, op := range cmdOperators {
 		op(&cmd)
 	}
@@ -237,7 +204,7 @@
 	return WaitOnCmd(cmd.Timeout, result)
 }
 
-// RunCommand parses a command line and runs it, returning a result
+// RunCommand runs a command with default options, and returns a result
 func RunCommand(command string, args ...string) *Result {
 	return RunCmd(Command(command, args...))
 }
@@ -248,7 +215,7 @@
 	if result.Error != nil {
 		return result
 	}
-	result.SetExitError(result.Cmd.Start())
+	result.setExitError(result.Cmd.Start())
 	return result
 }
 
@@ -283,7 +250,7 @@
 // only wait until the timeout.
 func WaitOnCmd(timeout time.Duration, result *Result) *Result {
 	if timeout == time.Duration(0) {
-		result.SetExitError(result.Cmd.Wait())
+		result.setExitError(result.Cmd.Wait())
 		return result
 	}
 
@@ -301,7 +268,7 @@
 		}
 		result.Timeout = true
 	case err := <-done:
-		result.SetExitError(err)
+		result.setExitError(err)
 	}
 	return result
 }
diff --git a/vendor/github.com/gotestyourself/gotestyourself/icmd/exitcode.go b/vendor/github.com/gotestyourself/gotestyourself/icmd/exitcode.go
new file mode 100644
index 0000000..9356dbc
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/icmd/exitcode.go
@@ -0,0 +1,32 @@
+package icmd
+
+import (
+	"os/exec"
+	"syscall"
+
+	"github.com/pkg/errors"
+)
+
+// getExitCode returns the ExitStatus of a process from the error returned by
+// exec.Run(). If the exit status could not be parsed an error is returned.
+func getExitCode(err error) (int, error) {
+	if exiterr, ok := err.(*exec.ExitError); ok {
+		if procExit, ok := exiterr.Sys().(syscall.WaitStatus); ok {
+			return procExit.ExitStatus(), nil
+		}
+	}
+	return 0, errors.Wrap(err, "failed to get exit code")
+}
+
+func processExitCode(err error) (exitCode int) {
+	if err == nil {
+		return 0
+	}
+	exitCode, exiterr := getExitCode(err)
+	if exiterr != nil {
+		// TODO: Fix this so we check the error's text.
+		// we've failed to retrieve exit code, so we set it to 127
+		return 127
+	}
+	return exitCode
+}
diff --git a/vendor/github.com/gotestyourself/gotestyourself/icmd/ops.go b/vendor/github.com/gotestyourself/gotestyourself/icmd/ops.go
new file mode 100644
index 0000000..02b1d84
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/icmd/ops.go
@@ -0,0 +1,4 @@
+package icmd
+
+// CmdOp is an operation which modified a Cmd structure used to execute commands
+type CmdOp func(*Cmd)
diff --git a/vendor/github.com/gotestyourself/gotestyourself/poll/poll.go b/vendor/github.com/gotestyourself/gotestyourself/poll/poll.go
new file mode 100644
index 0000000..3838d38
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/poll/poll.go
@@ -0,0 +1,133 @@
+/*Package poll provides tools for testing asynchronous code.
+ */
+package poll
+
+import (
+	"fmt"
+	"time"
+)
+
+// TestingT is the subset of testing.T used by WaitOn
+type TestingT interface {
+	LogT
+	Fatalf(format string, args ...interface{})
+}
+
+// LogT is a logging interface that is passed to the WaitOn check function
+type LogT interface {
+	Log(args ...interface{})
+	Logf(format string, args ...interface{})
+}
+
+// Settings are used to configure the behaviour of WaitOn
+type Settings struct {
+	// Timeout is the maximum time to wait for the condition. Defaults to 10s
+	Timeout time.Duration
+	// Delay is the time to sleep between checking the condition. Detaults to
+	// 1ms
+	Delay time.Duration
+}
+
+func defaultConfig() *Settings {
+	return &Settings{Timeout: 10 * time.Second, Delay: time.Millisecond}
+}
+
+// SettingOp is a function which accepts and modifies Settings
+type SettingOp func(config *Settings)
+
+// WithDelay sets the delay to wait between polls
+func WithDelay(delay time.Duration) SettingOp {
+	return func(config *Settings) {
+		config.Delay = delay
+	}
+}
+
+// WithTimeout sets the timeout
+func WithTimeout(timeout time.Duration) SettingOp {
+	return func(config *Settings) {
+		config.Timeout = timeout
+	}
+}
+
+// Result of a check performed by WaitOn
+type Result interface {
+	// Error indicates that the check failed and polling should stop, and the
+	// the has failed
+	Error() error
+	// Done indicates that polling should stop, and the test should proceed
+	Done() bool
+	// Message provides the most recent state when polling has not completed
+	Message() string
+}
+
+type result struct {
+	done    bool
+	message string
+	err     error
+}
+
+func (r result) Done() bool {
+	return r.done
+}
+
+func (r result) Message() string {
+	return r.message
+}
+
+func (r result) Error() error {
+	return r.err
+}
+
+// Continue returns a Result that indicates to WaitOn that it should continue
+// polling. The message text will be used as the failure message if the timeout
+// is reached.
+func Continue(message string, args ...interface{}) Result {
+	return result{message: fmt.Sprintf(message, args...)}
+}
+
+// Success returns a Result where Done() returns true, which indicates to WaitOn
+// that it should stop polling and exit without an error.
+func Success() Result {
+	return result{done: true}
+}
+
+// Error returns a Result that indicates to WaitOn that it should fail the test
+// and stop polling.
+func Error(err error) Result {
+	return result{err: err}
+}
+
+// WaitOn a condition or until a timeout. Poll by calling check and exit when
+// check returns a done Result. To fail a test and exit polling with an error
+// return a error result.
+func WaitOn(t TestingT, check func(t LogT) Result, pollOps ...SettingOp) {
+	config := defaultConfig()
+	for _, pollOp := range pollOps {
+		pollOp(config)
+	}
+
+	var lastMessage string
+	after := time.After(config.Timeout)
+	chResult := make(chan Result)
+	for {
+		go func() {
+			chResult <- check(t)
+		}()
+		select {
+		case <-after:
+			if lastMessage == "" {
+				lastMessage = "first check never completed"
+			}
+			t.Fatalf("timeout hit after %s: %s", config.Timeout, lastMessage)
+		case result := <-chResult:
+			switch {
+			case result.Error() != nil:
+				t.Fatalf("polling check failed: %s", result.Error())
+			case result.Done():
+				return
+			}
+			time.Sleep(config.Delay)
+			lastMessage = result.Message()
+		}
+	}
+}
diff --git a/vendor/github.com/gotestyourself/gotestyourself/skip/skip.go b/vendor/github.com/gotestyourself/gotestyourself/skip/skip.go
new file mode 100644
index 0000000..d92110b
--- /dev/null
+++ b/vendor/github.com/gotestyourself/gotestyourself/skip/skip.go
@@ -0,0 +1,133 @@
+/*Package skip provides functions for skipping based on a condition.
+ */
+package skip
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"path"
+	"reflect"
+	"runtime"
+	"strings"
+
+	"github.com/pkg/errors"
+)
+
+type skipT interface {
+	Skip(args ...interface{})
+	Log(args ...interface{})
+}
+
+// If skips the test if the check function returns true. The skip message will
+// contain the name of the check function. Extra message text can be passed as a
+// format string with args
+func If(t skipT, check func() bool, msgAndArgs ...interface{}) {
+	if check() {
+		t.Skip(formatWithCustomMessage(
+			getFunctionName(check),
+			formatMessage(msgAndArgs...)))
+	}
+}
+
+func getFunctionName(function func() bool) string {
+	funcPath := runtime.FuncForPC(reflect.ValueOf(function).Pointer()).Name()
+	return strings.SplitN(path.Base(funcPath), ".", 2)[1]
+}
+
+// IfCondition skips the test if the condition is true. The skip message will
+// contain the source of the expression passed as the condition. Extra message
+// text can be passed as a format string with args.
+func IfCondition(t skipT, condition bool, msgAndArgs ...interface{}) {
+	if !condition {
+		return
+	}
+	source, err := getConditionSource()
+	if err != nil {
+		t.Log(err.Error())
+		t.Skip(formatMessage(msgAndArgs...))
+	}
+	t.Skip(formatWithCustomMessage(source, formatMessage(msgAndArgs...)))
+}
+
+func getConditionSource() (string, error) {
+	const callstackIndex = 3
+	lines, err := getSourceLine(callstackIndex)
+	if err != nil {
+		return "", err
+	}
+
+	for i := range lines {
+		source := strings.Join(lines[len(lines)-i-1:], "\n")
+		node, err := parser.ParseExpr(source)
+		if err == nil {
+			return getConditionArgFromAST(node)
+		}
+	}
+	return "", errors.Wrapf(err, "failed to parse source")
+}
+
+// maxContextLines is the maximum number of lines to scan for a complete
+// skip.If() statement
+const maxContextLines = 10
+
+// getSourceLines returns the source line which called skip.If() along with a
+// few preceding lines. To properly parse the AST a complete statement is
+// required, and that statement may be split across multiple lines, so include
+// up to maxContextLines.
+func getSourceLine(stackIndex int) ([]string, error) {
+	_, filename, line, ok := runtime.Caller(stackIndex)
+	if !ok {
+		return nil, errors.New("failed to get caller info")
+	}
+
+	raw, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, errors.Wrapf(err, "failed to read source file: %s", filename)
+	}
+
+	lines := strings.Split(string(raw), "\n")
+	if len(lines) < line {
+		return nil, errors.Errorf("file %s does not have line %d", filename, line)
+	}
+	firstLine := line - maxContextLines
+	if firstLine < 0 {
+		firstLine = 0
+	}
+	return lines[firstLine:line], nil
+}
+
+func getConditionArgFromAST(node ast.Expr) (string, error) {
+	switch expr := node.(type) {
+	case *ast.CallExpr:
+		buf := new(bytes.Buffer)
+		err := format.Node(buf, token.NewFileSet(), expr.Args[1])
+		return buf.String(), err
+	}
+	return "", errors.New("unexpected ast")
+}
+
+func formatMessage(msgAndArgs ...interface{}) string {
+	switch len(msgAndArgs) {
+	case 0:
+		return ""
+	case 1:
+		return msgAndArgs[0].(string)
+	default:
+		return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
+	}
+}
+
+func formatWithCustomMessage(source, custom string) string {
+	switch {
+	case custom == "":
+		return source
+	case source == "":
+		return custom
+	}
+	return fmt.Sprintf("%s: %s", source, custom)
+}
diff --git a/vendor/github.com/jhowardmsft/opengcs/LICENSE b/vendor/github.com/jhowardmsft/opengcs/LICENSE
deleted file mode 100644
index 8739a02..0000000
--- a/vendor/github.com/jhowardmsft/opengcs/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2017 Microsoft
-
-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.
\ No newline at end of file
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/config.go b/vendor/github.com/jhowardmsft/opengcs/gogcs/client/config.go
deleted file mode 100644
index fedb563..0000000
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/config.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// +build windows
-
-package client
-
-import (
-	"encoding/json"
-	"fmt"
-	"os"
-	"path/filepath"
-	"strconv"
-	"strings"
-
-	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
-)
-
-// Mode is the operational mode, both requested, and actual after verification
-type Mode uint
-
-const (
-	// Constants for the actual mode after validation
-
-	// ModeActualError means an error has occurred during validation
-	ModeActualError = iota
-	// ModeActualVhdx means that we are going to use VHDX boot after validation
-	ModeActualVhdx
-	// ModeActualKernelInitrd means that we are going to use kernel+initrd for boot after validation
-	ModeActualKernelInitrd
-
-	// Constants for the requested mode
-
-	// ModeRequestAuto means auto-select the boot mode for a utility VM
-	ModeRequestAuto = iota // VHDX will be priority over kernel+initrd
-	// ModeRequestVhdx means request VHDX boot if possible
-	ModeRequestVhdx
-	// ModeRequestKernelInitrd means request Kernel+initrd boot if possible
-	ModeRequestKernelInitrd
-
-	// defaultUvmTimeoutSeconds is the default time to wait for utility VM operations
-	defaultUvmTimeoutSeconds = 5 * 60
-
-	// DefaultSandboxSizeMB is the size of the default sandbox size in MB
-	DefaultSandboxSizeMB = 20 * 1024 * 1024
-)
-
-// Config is the structure used to configuring a utility VM to be used
-// as a service VM. There are two ways of starting. Either supply a VHD,
-// or a Kernel+Initrd. For the latter, both must be supplied, and both
-// must be in the same directory.
-//
-// VHD is the priority.
-type Config struct {
-	KirdPath           string                      // Path to where kernel/initrd are found (defaults to c:\program files\Linux Containers)
-	KernelFile         string                      // Kernel for Utility VM (embedded in a UEFI bootloader) - does NOT include full path, just filename
-	InitrdFile         string                      // Initrd image for Utility VM - does NOT include full path, just filename
-	Vhdx               string                      // VHD for booting the utility VM - is a full path
-	Name               string                      // Name of the utility VM
-	RequestedMode      Mode                        // What mode is preferred when validating
-	ActualMode         Mode                        // What mode was obtained during validation
-	UvmTimeoutSeconds  int                         // How long to wait for the utility VM to respond in seconds
-	Uvm                hcsshim.Container           // The actual container
-	MappedVirtualDisks []hcsshim.MappedVirtualDisk // Data-disks to be attached
-}
-
-// GenerateDefault generates a default config from a set of options
-// If baseDir is not supplied, defaults to $env:ProgramFiles\Linux Containers
-func (config *Config) GenerateDefault(options []string) error {
-	if config.UvmTimeoutSeconds < 0 {
-		return fmt.Errorf("opengcs: cannot generate a config when supplied a negative utility VM timeout")
-	}
-
-	envTimeoutSeconds := 0
-	optTimeoutSeconds := 0
-
-	if config.UvmTimeoutSeconds != 0 {
-		envTimeout := os.Getenv("OPENGCS_UVM_TIMEOUT_SECONDS")
-		if len(envTimeout) > 0 {
-			var err error
-			if envTimeoutSeconds, err = strconv.Atoi(envTimeout); err != nil {
-				return fmt.Errorf("opengcs: OPENGCS_UVM_TIMEOUT_SECONDS could not be interpreted as an integer")
-			}
-			if envTimeoutSeconds < 0 {
-				return fmt.Errorf("opengcs: OPENGCS_UVM_TIMEOUT_SECONDS cannot be negative")
-			}
-		}
-	}
-
-	for _, v := range options {
-		opt := strings.SplitN(v, "=", 2)
-		if len(opt) == 2 {
-			switch strings.ToLower(opt[0]) {
-			case "opengcskirdpath":
-				config.KirdPath = opt[1]
-			case "opengcskernel":
-				config.KernelFile = opt[1]
-			case "opengcsinitrd":
-				config.InitrdFile = opt[1]
-			case "opengcsvhdx":
-				config.Vhdx = opt[1]
-			case "opengcstimeoutsecs":
-				var err error
-				if optTimeoutSeconds, err = strconv.Atoi(opt[1]); err != nil {
-					return fmt.Errorf("opengcs: opengcstimeoutsecs option could not be interpreted as an integer")
-				}
-				if optTimeoutSeconds < 0 {
-					return fmt.Errorf("opengcs: opengcstimeoutsecs option cannot be negative")
-				}
-			}
-		}
-	}
-
-	if config.KirdPath == "" {
-		config.KirdPath = filepath.Join(os.Getenv("ProgramFiles"), "Linux Containers")
-	}
-
-	if config.Vhdx == "" {
-		config.Vhdx = filepath.Join(config.KirdPath, `uvm.vhdx`)
-	}
-	if config.KernelFile == "" {
-		config.KernelFile = `bootx64.efi`
-	}
-	if config.InitrdFile == "" {
-		config.InitrdFile = `initrd.img`
-	}
-
-	// Which timeout are we going to take? If not through option or environment,
-	// then use the default constant, otherwise the maximum of the option or
-	// environment supplied setting. A requested on in the config supplied
-	// overrides all of this.
-	if config.UvmTimeoutSeconds == 0 {
-		config.UvmTimeoutSeconds = defaultUvmTimeoutSeconds
-		if optTimeoutSeconds != 0 || envTimeoutSeconds != 0 {
-			config.UvmTimeoutSeconds = optTimeoutSeconds
-			if envTimeoutSeconds > optTimeoutSeconds {
-				config.UvmTimeoutSeconds = envTimeoutSeconds
-			}
-		}
-	}
-
-	config.MappedVirtualDisks = nil
-
-	return nil
-}
-
-// validate validates a Config structure for starting a utility VM.
-func (config *Config) validate() error {
-	config.ActualMode = ModeActualError
-
-	if config.RequestedMode == ModeRequestVhdx && config.Vhdx == "" {
-		return fmt.Errorf("opengcs: config is invalid - request for VHDX mode did not supply a VHDX")
-	}
-	if config.RequestedMode == ModeRequestKernelInitrd && (config.KernelFile == "" || config.InitrdFile == "") {
-		return fmt.Errorf("opengcs: config is invalid - request for Kernel+Initrd mode must supply both kernel and initrd")
-	}
-
-	// Validate that if VHDX requested or auto, it exists.
-	if config.RequestedMode == ModeRequestAuto || config.RequestedMode == ModeRequestVhdx {
-		if _, err := os.Stat(config.Vhdx); os.IsNotExist(err) {
-			if config.RequestedMode == ModeRequestVhdx {
-				return fmt.Errorf("opengcs: mode requested was VHDX but '%s' could not be found", config.Vhdx)
-			}
-		} else {
-			config.ActualMode = ModeActualVhdx
-			return nil
-		}
-	}
-
-	// So must be kernel+initrd, or auto where we fallback as the VHDX doesn't exist
-	if config.InitrdFile == "" || config.KernelFile == "" {
-		if config.RequestedMode == ModeRequestKernelInitrd {
-			return fmt.Errorf("opengcs: both initrd and kernel options for utility VM boot must be supplied")
-		}
-		return fmt.Errorf("opengcs: configuration is invalid")
-	}
-
-	if _, err := os.Stat(filepath.Join(config.KirdPath, config.KernelFile)); os.IsNotExist(err) {
-		return fmt.Errorf("opengcs: kernel '%s' was not found", filepath.Join(config.KirdPath, config.KernelFile))
-	}
-	if _, err := os.Stat(filepath.Join(config.KirdPath, config.InitrdFile)); os.IsNotExist(err) {
-		return fmt.Errorf("opengcs: initrd '%s' was not found", filepath.Join(config.KirdPath, config.InitrdFile))
-	}
-
-	config.ActualMode = ModeActualKernelInitrd
-
-	// Ensure all the MappedVirtualDisks exist on the host
-	for _, mvd := range config.MappedVirtualDisks {
-		if _, err := os.Stat(mvd.HostPath); err != nil {
-			return fmt.Errorf("opengcs: MappedVirtualDisk '%s' was not found", mvd.HostPath)
-		}
-		if mvd.ContainerPath == "" {
-			return fmt.Errorf("opengcs: MappedVirtualDisk '%s' has no container path", mvd.HostPath)
-		}
-	}
-
-	return nil
-}
-
-// Create creates a utility VM from a configuration.
-func (config *Config) Create() error {
-	logrus.Debugf("opengcs Create: %+v", config)
-
-	if err := config.validate(); err != nil {
-		return err
-	}
-
-	configuration := &hcsshim.ContainerConfig{
-		HvPartition:                 true,
-		Name:                        config.Name,
-		SystemType:                  "container",
-		ContainerType:               "linux",
-		TerminateOnLastHandleClosed: true,
-		MappedVirtualDisks:          config.MappedVirtualDisks,
-	}
-
-	if config.ActualMode == ModeActualVhdx {
-		configuration.HvRuntime = &hcsshim.HvRuntime{
-			ImagePath: config.Vhdx,
-		}
-	} else {
-		configuration.HvRuntime = &hcsshim.HvRuntime{
-			ImagePath:       config.KirdPath,
-			LinuxInitrdFile: config.InitrdFile,
-			LinuxKernelFile: config.KernelFile,
-		}
-	}
-
-	configurationS, _ := json.Marshal(configuration)
-	logrus.Debugf("opengcs Create: calling HCS with '%s'", string(configurationS))
-	uvm, err := hcsshim.CreateContainer(config.Name, configuration)
-	if err != nil {
-		return err
-	}
-	logrus.Debugf("opengcs Create: uvm created, starting...")
-	err = uvm.Start()
-	if err != nil {
-		logrus.Debugf("opengcs Create: uvm failed to start: %s", err)
-		// Make sure we don't leave it laying around as it's been created in HCS
-		uvm.Terminate()
-		return err
-	}
-
-	config.Uvm = uvm
-	logrus.Debugf("opengcs Create: uvm %s is running", config.Name)
-	return nil
-}
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/createsandbox.go b/vendor/github.com/jhowardmsft/opengcs/gogcs/client/createsandbox.go
deleted file mode 100644
index 6597160..0000000
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/createsandbox.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// +build windows
-
-package client
-
-import (
-	"fmt"
-	"os"
-
-	"github.com/Sirupsen/logrus"
-)
-
-// CreateSandbox does what it says on the tin. This is done by copying a prebuilt-sandbox from the ServiceVM.
-// It is the responsibility of the caller to synchronise simultaneous attempts to create the cache file.
-// TODO: @jhowardmsft maxSizeInMB isn't hooked up in GCS. Needs a platform change which is in flight.
-func (config *Config) CreateSandbox(destFile string, maxSizeInMB uint32, cacheFile string) error {
-	// Smallest we can accept is the default sandbox size as we can't size down, only expand.
-	if maxSizeInMB < DefaultSandboxSizeMB {
-		maxSizeInMB = DefaultSandboxSizeMB
-	}
-
-	logrus.Debugf("opengcs: CreateSandbox: %s size:%dMB cache:%s", destFile, maxSizeInMB, cacheFile)
-
-	// Retrieve from cache if the default size and already on disk
-	if cacheFile != "" && maxSizeInMB == DefaultSandboxSizeMB {
-		if _, err := os.Stat(cacheFile); err == nil {
-			if err := CopyFile(cacheFile, destFile, false); err != nil {
-				return fmt.Errorf("opengcs: CreateSandbox: Failed to copy cached sandbox '%s' to '%s': %s", cacheFile, destFile, err)
-			}
-			logrus.Debugf("opengcs: CreateSandbox: %s fulfilled from cache", destFile)
-			return nil
-		}
-	}
-
-	if config.Uvm == nil {
-		return fmt.Errorf("opengcs: CreateSandbox: No utility VM has been created")
-	}
-
-	// TODO @jhowardmsft - needs a platform change so that can specify size. eg fmt.Sprintf("createSandbox -size %d", maxSizeInMB))
-	process, err := config.createUtilsProcess("createSandbox")
-	if err != nil {
-		return fmt.Errorf("opengcs: CreateSandbox: %s: failed to create utils process: %s", destFile, err)
-	}
-
-	defer func() {
-		process.Process.Close()
-	}()
-
-	logrus.Debugf("opengcs: CreateSandbox: %s: writing from stdout", destFile)
-	// Get back the sandbox VHDx stream from the service VM and write it to file
-	resultSize, err := writeFileFromReader(destFile, process.Stdout, config.UvmTimeoutSeconds, fmt.Sprintf("createSandbox %s", destFile))
-	if err != nil {
-		return fmt.Errorf("opengcs: CreateSandbox: %s: failed writing %d bytes to target file: %s", destFile, resultSize, err)
-	}
-
-	// Populate the cache
-	if cacheFile != "" && maxSizeInMB == DefaultSandboxSizeMB {
-		// It may already exist due to being created on another thread, in which case no copy back needed.
-		if _, err := os.Stat(cacheFile); os.IsNotExist(err) {
-			if err := CopyFile(destFile, cacheFile, false); err != nil {
-				return fmt.Errorf("opengcs: CreateSandbox: Failed to seed sandbox cache '%s' from '%s': %s", destFile, cacheFile, err)
-			}
-		}
-	}
-
-	logrus.Debugf("opengcs: CreateSandbox: %s created (non-cache)", destFile)
-	return nil
-}
diff --git a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/process.go b/vendor/github.com/jhowardmsft/opengcs/gogcs/client/process.go
deleted file mode 100644
index 0265522..0000000
--- a/vendor/github.com/jhowardmsft/opengcs/gogcs/client/process.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// +build windows
-
-package client
-
-import (
-	"fmt"
-	"io"
-
-	"github.com/Microsoft/hcsshim"
-	"github.com/Sirupsen/logrus"
-)
-
-// Process is the structure pertaining to a process running in a utility VM.
-type process struct {
-	Process hcsshim.Process
-	Stdin   io.WriteCloser
-	Stdout  io.ReadCloser
-}
-
-// createUtilsProcess is a convenient wrapper for hcsshim.createUtilsProcess to use when
-// communicating with a utility VM.
-func (config *Config) createUtilsProcess(commandLine string) (process, error) {
-	logrus.Debugf("opengcs: createUtilsProcess")
-
-	if config.Uvm == nil {
-		return process{}, fmt.Errorf("cannot create utils process as no utility VM is in configuration")
-	}
-
-	var (
-		err  error
-		proc process
-	)
-
-	env := make(map[string]string)
-	env["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:"
-	processConfig := &hcsshim.ProcessConfig{
-		EmulateConsole:    false,
-		CreateStdInPipe:   true,
-		CreateStdOutPipe:  true,
-		CreateStdErrPipe:  true,
-		CreateInUtilityVm: true,
-		WorkingDirectory:  "/bin",
-		Environment:       env,
-		CommandLine:       commandLine,
-	}
-	proc.Process, err = config.Uvm.CreateProcess(processConfig)
-	if err != nil {
-		return process{}, fmt.Errorf("opengcs: createUtilsProcess: CreateProcess %+v failed %s", config, err)
-	}
-
-	if proc.Stdin, proc.Stdout, _, err = proc.Process.Stdio(); err != nil {
-		proc.Process.Kill() // Should this have a timeout?
-		proc.Process.Close()
-		return process{}, fmt.Errorf("opengcs: createUtilsProcess: failed to get Stdio pipes %s", err)
-	}
-
-	logrus.Debugf("opengcs: createUtilsProcess success: pid %d", proc.Process.Pid())
-	return proc, nil
-}
-
-// RunProcess runs the given command line program in the utilityVM. It takes in
-// an input to the reader to feed into stdin and returns stdout to output.
-func (config *Config) RunProcess(commandLine string, input io.Reader, output io.Writer) error {
-	logrus.Debugf("opengcs: RunProcess: %s", commandLine)
-	process, err := config.createUtilsProcess(commandLine)
-	if err != nil {
-		return err
-	}
-	defer process.Process.Close()
-
-	// Send the data into the process's stdin
-	if input != nil {
-		if _, err = copyWithTimeout(process.Stdin,
-			input,
-			0,
-			config.UvmTimeoutSeconds,
-			fmt.Sprintf("send to stdin of %s", commandLine)); err != nil {
-			return err
-		}
-
-		// Don't need stdin now we've sent everything. This signals GCS that we are finished sending data.
-		if err := process.Process.CloseStdin(); err != nil {
-			return err
-		}
-	}
-
-	if output != nil {
-		// Copy the data over to the writer.
-		if _, err := copyWithTimeout(output,
-			process.Stdout,
-			0,
-			config.UvmTimeoutSeconds,
-			fmt.Sprintf("RunProcess: copy back from %s", commandLine)); err != nil {
-			return err
-		}
-	}
-
-	logrus.Debugf("opengcs: runProcess success: %s", commandLine)
-	return nil
-}
diff --git a/vendor/github.com/moby/buildkit/LICENSE b/vendor/github.com/moby/buildkit/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/vendor/github.com/moby/buildkit/LICENSE
@@ -0,0 +1,201 @@
+                                 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/moby/buildkit/README.md b/vendor/github.com/moby/buildkit/README.md
new file mode 100644
index 0000000..4101bf4
--- /dev/null
+++ b/vendor/github.com/moby/buildkit/README.md
@@ -0,0 +1,133 @@
+### Important: This repository is in an early development phase
+
+[![asciicinema example](https://asciinema.org/a/gPEIEo1NzmDTUu2bEPsUboqmU.png)](https://asciinema.org/a/gPEIEo1NzmDTUu2bEPsUboqmU)
+
+
+## BuildKit
+
+<!-- godoc is mainly for LLB stuff -->
+[![GoDoc](https://godoc.org/github.com/moby/buildkit?status.svg)](https://godoc.org/github.com/moby/buildkit/client/llb)
+[![Build Status](https://travis-ci.org/moby/buildkit.svg?branch=master)](https://travis-ci.org/moby/buildkit)
+[![Go Report Card](https://goreportcard.com/badge/github.com/moby/buildkit)](https://goreportcard.com/report/github.com/moby/buildkit)
+
+
+BuildKit is a toolkit for converting source code to build artifacts in an efficient, expressive and repeatable manner.
+
+Key features:
+- Automatic garbage collection
+- Extendable frontend formats
+- Concurrent dependency resolution
+- Efficient instruction caching
+- Build cache import/export
+- Nested build job invocations
+- Distributable workers
+- Multiple output formats
+- Pluggable architecture
+
+
+Read the proposal from https://github.com/moby/moby/issues/32925
+
+#### Quick start
+
+BuildKit daemon can be built in two different versions: one that uses [containerd](https://github.com/containerd/containerd) for execution and distribution, and a standalone version that doesn't have other dependencies apart from [runc](https://github.com/opencontainers/runc). We are open for adding more backends. `buildd` is a CLI utility for serving the gRPC API. 
+
+```bash
+# buildd daemon (choose one)
+go build -o buildd-containerd -tags containerd ./cmd/buildd
+go build -o buildd-standalone -tags standalone ./cmd/buildd
+
+# buildctl utility
+go build -o buildctl ./cmd/buildctl
+```
+
+You can also use `make binaries` that prepares all binaries into the `bin/` directory.
+
+`examples/buildkit*` directory contains scripts that define how to build different configurations of BuildKit and its dependencies using the `client` package. Running one of these script generates a protobuf definition of a build graph. Note that the script itself does not execute any steps of the build.
+
+You can use `buildctl debug dump-llb` to see what data is in this definition. Add `--dot` to generate dot layout.
+
+```bash
+go run examples/buildkit0/buildkit.go | buildctl debug dump-llb | jq .
+```
+
+To start building use `buildctl build` command. The example script accepts `--target` flag to choose between `containerd` and `standalone` configurations. In standalone mode BuildKit binaries are built together with `runc`. In containerd mode, the `containerd` binary is built as well from the upstream repo.
+
+```bash
+go run examples/buildkit0/buildkit.go | buildctl build
+```
+
+`buildctl build` will show interactive progress bar by default while the build job is running. It will also show you the path to the trace file that contains all information about the timing of the individual steps and logs.
+
+Different versions of the example scripts show different ways of describing the build definition for this project to show the capabilities of the library. New versions have been added when new features have become available.
+
+- `./examples/buildkit0` - uses only exec operations, defines a full stage per component.
+- `./examples/buildkit1` - cloning git repositories has been separated for extra concurrency.
+- `./examples/buildkit2` - uses git sources directly instead of running `git clone`, allowing better performance and much safer caching.
+- `./examples/buildkit3` - allows using local source files for separate components eg. `./buildkit3 --runc=local | buildctl build --local runc-src=some/local/path`  
+- `./examples/dockerfile2llb` - can be used to convert a Dockerfile to LLB for debugging purposes
+- `./examples/gobuild` - shows how to use nested invocation to generate LLB for Go package internal dependencies
+
+
+#### Examples
+
+##### Starting the buildd daemon:
+
+```
+buildd-standalone --debug --root /var/lib/buildkit
+```
+
+##### Building a Dockerfile:
+
+```
+buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=.
+```
+
+`context` and `dockerfile` should point to local directories for build context and Dockerfile location.
+
+
+##### Exporting resulting image to containerd
+
+Containerd version of buildd needs to be used
+
+```
+buildctl build ... --exporter=image --exporter-opt name=docker.io/username/image
+ctr --namespace=buildkit images ls
+```
+
+##### Exporting build result back to client
+
+```
+buildctl build ... --exporter=local --exporter-opt output=path/to/output-dir
+```
+
+#### View build cache
+
+```
+buildctl du -v
+```
+
+#### Supported runc version
+
+During development buildkit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/d1e11f17ec7b325f89608dd46c128300b8727d50/RUNC.md) for more information.
+
+
+#### Contributing
+
+Running tests:
+
+```bash
+make test
+```
+
+Updating vendored dependencies:
+
+```bash
+# update vendor.conf
+make vendor
+```
+
+Validating your updates before submission:
+
+```bash
+make validate-all
+```
diff --git a/vendor/github.com/moby/buildkit/session/context.go b/vendor/github.com/moby/buildkit/session/context.go
new file mode 100644
index 0000000..31a29f0
--- /dev/null
+++ b/vendor/github.com/moby/buildkit/session/context.go
@@ -0,0 +1,22 @@
+package session
+
+import "context"
+
+type contextKeyT string
+
+var contextKey = contextKeyT("buildkit/session-id")
+
+func NewContext(ctx context.Context, id string) context.Context {
+	if id != "" {
+		return context.WithValue(ctx, contextKey, id)
+	}
+	return ctx
+}
+
+func FromContext(ctx context.Context) string {
+	v := ctx.Value(contextKey)
+	if v == nil {
+		return ""
+	}
+	return v.(string)
+}
diff --git a/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go b/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go
new file mode 100644
index 0000000..c5a3b5b
--- /dev/null
+++ b/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go
@@ -0,0 +1,55 @@
+package filesync
+
+import (
+	"os"
+	"time"
+
+	"github.com/sirupsen/logrus"
+	"github.com/tonistiigi/fsutil"
+	"google.golang.org/grpc"
+)
+
+func sendDiffCopy(stream grpc.Stream, dir string, includes, excludes []string, progress progressCb, _map func(*fsutil.Stat) bool) error {
+	return fsutil.Send(stream.Context(), stream, dir, &fsutil.WalkOpt{
+		ExcludePatterns: excludes,
+		IncludePatterns: includes,
+		Map:             _map,
+	}, progress)
+}
+
+func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progressCb) error {
+	st := time.Now()
+	defer func() {
+		logrus.Debugf("diffcopy took: %v", time.Since(st))
+	}()
+	var cf fsutil.ChangeFunc
+	var ch fsutil.ContentHasher
+	if cu != nil {
+		cu.MarkSupported(true)
+		cf = cu.HandleChange
+		ch = cu.ContentHasher()
+	}
+	return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
+		NotifyHashed:  cf,
+		ContentHasher: ch,
+		ProgressCb:    progress,
+	})
+}
+
+func syncTargetDiffCopy(ds grpc.Stream, dest string) error {
+	if err := os.MkdirAll(dest, 0700); err != nil {
+		return err
+	}
+	return fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{
+		Merge: true,
+		Filter: func() func(*fsutil.Stat) bool {
+			uid := os.Getuid()
+			gid := os.Getgid()
+			return func(st *fsutil.Stat) bool {
+				st.Uid = uint32(uid)
+				st.Gid = uint32(gid)
+				return true
+			}
+		}(),
+	})
+}
diff --git a/client/session/filesync/filesync.go b/vendor/github.com/moby/buildkit/session/filesync/filesync.go
similarity index 64%
rename from client/session/filesync/filesync.go
rename to vendor/github.com/moby/buildkit/session/filesync/filesync.go
index 9a2ffc8..5642f07 100644
--- a/client/session/filesync/filesync.go
+++ b/vendor/github.com/moby/buildkit/session/filesync/filesync.go
@@ -1,10 +1,11 @@
 package filesync
 
 import (
+	"fmt"
 	"os"
 	"strings"
 
-	"github.com/docker/docker/client/session"
+	"github.com/moby/buildkit/session"
 	"github.com/pkg/errors"
 	"github.com/tonistiigi/fsutil"
 	"golang.org/x/net/context"
@@ -15,20 +16,29 @@
 const (
 	keyOverrideExcludes = "override-excludes"
 	keyIncludePatterns  = "include-patterns"
+	keyDirName          = "dir-name"
 )
 
 type fsSyncProvider struct {
-	root     string
-	excludes []string
-	p        progressCb
-	doneCh   chan error
+	dirs   map[string]SyncedDir
+	p      progressCb
+	doneCh chan error
+}
+
+type SyncedDir struct {
+	Name     string
+	Dir      string
+	Excludes []string
+	Map      func(*fsutil.Stat) bool
 }
 
 // NewFSSyncProvider creates a new provider for sending files from client
-func NewFSSyncProvider(root string, excludes []string) session.Attachable {
+func NewFSSyncProvider(dirs []SyncedDir) session.Attachable {
 	p := &fsSyncProvider{
-		root:     root,
-		excludes: excludes,
+		dirs: map[string]SyncedDir{},
+	}
+	for _, d := range dirs {
+		p.dirs[d.Name] = d
 	}
 	return p
 }
@@ -58,9 +68,19 @@
 
 	opts, _ := metadata.FromContext(stream.Context()) // if no metadata continue with empty object
 
+	name, ok := opts[keyDirName]
+	if !ok || len(name) != 1 {
+		return errors.New("no dir name in request")
+	}
+
+	dir, ok := sp.dirs[name[0]]
+	if !ok {
+		return errors.Errorf("no access allowed to dir %q", name[0])
+	}
+
 	var excludes []string
 	if len(opts[keyOverrideExcludes]) == 0 || opts[keyOverrideExcludes][0] != "true" {
-		excludes = sp.excludes
+		excludes = dir.Excludes
 	}
 	includes := opts[keyIncludePatterns]
 
@@ -75,7 +95,7 @@
 		doneCh = sp.doneCh
 		sp.doneCh = nil
 	}
-	err := pr.sendFn(stream, sp.root, includes, excludes, progress)
+	err := pr.sendFn(stream, dir.Dir, includes, excludes, progress, dir.Map)
 	if doneCh != nil {
 		if err != nil {
 			doneCh <- err
@@ -94,8 +114,8 @@
 
 type protocol struct {
 	name   string
-	sendFn func(stream grpc.Stream, srcDir string, includes, excludes []string, progress progressCb) error
-	recvFn func(stream grpc.Stream, destDir string, cu CacheUpdater) error
+	sendFn func(stream grpc.Stream, srcDir string, includes, excludes []string, progress progressCb, _map func(*fsutil.Stat) bool) error
+	recvFn func(stream grpc.Stream, destDir string, cu CacheUpdater, progress progressCb) error
 }
 
 func isProtoSupported(p string) bool {
@@ -112,25 +132,23 @@
 		sendFn: sendDiffCopy,
 		recvFn: recvDiffCopy,
 	},
-	{
-		name:   "tarstream",
-		sendFn: sendTarStream,
-		recvFn: recvTarStream,
-	},
 }
 
 // FSSendRequestOpt defines options for FSSend request
 type FSSendRequestOpt struct {
+	Name             string
 	IncludePatterns  []string
 	OverrideExcludes bool
 	DestDir          string
 	CacheUpdater     CacheUpdater
+	ProgressCb       func(int, bool)
 }
 
 // CacheUpdater is an object capable of sending notifications for the cache hash changes
 type CacheUpdater interface {
 	MarkSupported(bool)
 	HandleChange(fsutil.ChangeKind, string, os.FileInfo, error) error
+	ContentHasher() fsutil.ContentHasher
 }
 
 // FSSync initializes a transfer of files
@@ -155,6 +173,8 @@
 		opts[keyIncludePatterns] = opt.IncludePatterns
 	}
 
+	opts[keyDirName] = []string{opt.Name}
+
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
 
@@ -177,7 +197,45 @@
 			return err
 		}
 		stream = cc
+	default:
+		panic(fmt.Sprintf("invalid protocol: %q", pr.name))
 	}
 
-	return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater)
+	return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb)
+}
+
+// NewFSSyncTarget allows writing into a directory
+func NewFSSyncTarget(outdir string) session.Attachable {
+	p := &fsSyncTarget{
+		outdir: outdir,
+	}
+	return p
+}
+
+type fsSyncTarget struct {
+	outdir string
+}
+
+func (sp *fsSyncTarget) Register(server *grpc.Server) {
+	RegisterFileSendServer(server, sp)
+}
+
+func (sp *fsSyncTarget) DiffCopy(stream FileSend_DiffCopyServer) error {
+	return syncTargetDiffCopy(stream, sp.outdir)
+}
+
+func CopyToCaller(ctx context.Context, srcPath string, c session.Caller, progress func(int, bool)) error {
+	method := session.MethodURL(_FileSend_serviceDesc.ServiceName, "diffcopy")
+	if !c.Supports(method) {
+		return errors.Errorf("method %s not supported by the client", method)
+	}
+
+	client := NewFileSendClient(c.Conn())
+
+	cc, err := client.DiffCopy(ctx)
+	if err != nil {
+		return err
+	}
+
+	return sendDiffCopy(cc, srcPath, nil, nil, progress, nil)
 }
diff --git a/client/session/filesync/filesync.pb.go b/vendor/github.com/moby/buildkit/session/filesync/filesync.pb.go
similarity index 82%
rename from client/session/filesync/filesync.pb.go
rename to vendor/github.com/moby/buildkit/session/filesync/filesync.pb.go
index c6ed666..69c7888 100644
--- a/client/session/filesync/filesync.pb.go
+++ b/vendor/github.com/moby/buildkit/session/filesync/filesync.pb.go
@@ -277,6 +277,102 @@
 	Metadata: "filesync.proto",
 }
 
+// Client API for FileSend service
+
+type FileSendClient interface {
+	DiffCopy(ctx context.Context, opts ...grpc.CallOption) (FileSend_DiffCopyClient, error)
+}
+
+type fileSendClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewFileSendClient(cc *grpc.ClientConn) FileSendClient {
+	return &fileSendClient{cc}
+}
+
+func (c *fileSendClient) DiffCopy(ctx context.Context, opts ...grpc.CallOption) (FileSend_DiffCopyClient, error) {
+	stream, err := grpc.NewClientStream(ctx, &_FileSend_serviceDesc.Streams[0], c.cc, "/moby.filesync.v1.FileSend/DiffCopy", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &fileSendDiffCopyClient{stream}
+	return x, nil
+}
+
+type FileSend_DiffCopyClient interface {
+	Send(*BytesMessage) error
+	Recv() (*BytesMessage, error)
+	grpc.ClientStream
+}
+
+type fileSendDiffCopyClient struct {
+	grpc.ClientStream
+}
+
+func (x *fileSendDiffCopyClient) Send(m *BytesMessage) error {
+	return x.ClientStream.SendMsg(m)
+}
+
+func (x *fileSendDiffCopyClient) Recv() (*BytesMessage, error) {
+	m := new(BytesMessage)
+	if err := x.ClientStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+// Server API for FileSend service
+
+type FileSendServer interface {
+	DiffCopy(FileSend_DiffCopyServer) error
+}
+
+func RegisterFileSendServer(s *grpc.Server, srv FileSendServer) {
+	s.RegisterService(&_FileSend_serviceDesc, srv)
+}
+
+func _FileSend_DiffCopy_Handler(srv interface{}, stream grpc.ServerStream) error {
+	return srv.(FileSendServer).DiffCopy(&fileSendDiffCopyServer{stream})
+}
+
+type FileSend_DiffCopyServer interface {
+	Send(*BytesMessage) error
+	Recv() (*BytesMessage, error)
+	grpc.ServerStream
+}
+
+type fileSendDiffCopyServer struct {
+	grpc.ServerStream
+}
+
+func (x *fileSendDiffCopyServer) Send(m *BytesMessage) error {
+	return x.ServerStream.SendMsg(m)
+}
+
+func (x *fileSendDiffCopyServer) Recv() (*BytesMessage, error) {
+	m := new(BytesMessage)
+	if err := x.ServerStream.RecvMsg(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _FileSend_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "moby.filesync.v1.FileSend",
+	HandlerType: (*FileSendServer)(nil),
+	Methods:     []grpc.MethodDesc{},
+	Streams: []grpc.StreamDesc{
+		{
+			StreamName:    "DiffCopy",
+			Handler:       _FileSend_DiffCopy_Handler,
+			ServerStreams: true,
+			ClientStreams: true,
+		},
+	},
+	Metadata: "filesync.proto",
+}
+
 func (m *BytesMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
@@ -558,7 +654,7 @@
 func init() { proto.RegisterFile("filesync.proto", fileDescriptorFilesync) }
 
 var fileDescriptorFilesync = []byte{
-	// 198 bytes of a gzipped FileDescriptorProto
+	// 208 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0xcb, 0xcc, 0x49,
 	0x2d, 0xae, 0xcc, 0x4b, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xc8, 0xcd, 0x4f, 0xaa,
 	0xd4, 0x83, 0x0b, 0x96, 0x19, 0x2a, 0x29, 0x71, 0xf1, 0x38, 0x55, 0x96, 0xa4, 0x16, 0xfb, 0xa6,
@@ -566,10 +662,10 @@
 	0x30, 0x6a, 0xf0, 0x04, 0x81, 0xd9, 0x46, 0xab, 0x19, 0xb9, 0x38, 0xdc, 0x32, 0x73, 0x52, 0x83,
 	0x2b, 0xf3, 0x92, 0x85, 0xfc, 0xb8, 0x38, 0x5c, 0x32, 0xd3, 0xd2, 0x9c, 0xf3, 0x0b, 0x2a, 0x85,
 	0xe4, 0xf4, 0xd0, 0xcd, 0xd3, 0x43, 0x36, 0x4c, 0x8a, 0x80, 0xbc, 0x06, 0xa3, 0x01, 0xa3, 0x90,
-	0x3f, 0x17, 0x67, 0x48, 0x62, 0x51, 0x70, 0x49, 0x51, 0x6a, 0x62, 0x2e, 0x35, 0x0c, 0x74, 0x32,
-	0xbb, 0xf0, 0x50, 0x8e, 0xe1, 0xc6, 0x43, 0x39, 0x86, 0x0f, 0x0f, 0xe5, 0x18, 0x1b, 0x1e, 0xc9,
-	0x31, 0xae, 0x78, 0x24, 0xc7, 0x78, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e,
-	0xc9, 0x31, 0xbe, 0x78, 0x24, 0xc7, 0xf0, 0xe1, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x51,
-	0x1c, 0x30, 0xb3, 0x92, 0xd8, 0xc0, 0x41, 0x64, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x0c,
-	0x8d, 0xc5, 0x34, 0x01, 0x00, 0x00,
+	0x3f, 0x17, 0x67, 0x48, 0x62, 0x51, 0x70, 0x49, 0x51, 0x6a, 0x62, 0x2e, 0x35, 0x0c, 0x34, 0x8a,
+	0x82, 0x3a, 0x36, 0x35, 0x2f, 0x85, 0xda, 0x8e, 0x75, 0x32, 0xbb, 0xf0, 0x50, 0x8e, 0xe1, 0xc6,
+	0x43, 0x39, 0x86, 0x0f, 0x0f, 0xe5, 0x18, 0x1b, 0x1e, 0xc9, 0x31, 0xae, 0x78, 0x24, 0xc7, 0x78,
+	0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0xbe, 0x78, 0x24, 0xc7,
+	0xf0, 0xe1, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x51, 0x1c, 0x30, 0xb3, 0x92, 0xd8, 0xc0,
+	0xc1, 0x6f, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x72, 0x81, 0x1a, 0x91, 0x90, 0x01, 0x00, 0x00,
 }
diff --git a/client/session/filesync/filesync.proto b/vendor/github.com/moby/buildkit/session/filesync/filesync.proto
similarity index 78%
rename from client/session/filesync/filesync.proto
rename to vendor/github.com/moby/buildkit/session/filesync/filesync.proto
index 2fd5b3e..0ae2937 100644
--- a/client/session/filesync/filesync.proto
+++ b/vendor/github.com/moby/buildkit/session/filesync/filesync.proto
@@ -9,6 +9,11 @@
   rpc TarStream(stream BytesMessage) returns (stream BytesMessage);
 }
 
+service FileSend{
+  rpc DiffCopy(stream BytesMessage) returns (stream BytesMessage);
+}
+
+
 // BytesMessage contains a chunk of byte data
 message BytesMessage{
 	bytes data = 1;
diff --git a/client/session/filesync/generate.go b/vendor/github.com/moby/buildkit/session/filesync/generate.go
similarity index 100%
rename from client/session/filesync/generate.go
rename to vendor/github.com/moby/buildkit/session/filesync/generate.go
diff --git a/client/session/grpc.go b/vendor/github.com/moby/buildkit/session/grpc.go
similarity index 97%
rename from client/session/grpc.go
rename to vendor/github.com/moby/buildkit/session/grpc.go
index 0f20b15..71d77bf 100644
--- a/client/session/grpc.go
+++ b/vendor/github.com/moby/buildkit/session/grpc.go
@@ -4,8 +4,8 @@
 	"net"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 	"golang.org/x/net/context"
 	"golang.org/x/net/http2"
 	"google.golang.org/grpc"
diff --git a/client/session/manager.go b/vendor/github.com/moby/buildkit/session/manager.go
similarity index 86%
rename from client/session/manager.go
rename to vendor/github.com/moby/buildkit/session/manager.go
index 9523e6f..b3e5955 100644
--- a/client/session/manager.go
+++ b/vendor/github.com/moby/buildkit/session/manager.go
@@ -49,14 +49,14 @@
 		return errors.New("handler does not support hijack")
 	}
 
-	uuid := r.Header.Get(headerSessionUUID)
+	id := r.Header.Get(headerSessionID)
 
 	proto := r.Header.Get("Upgrade")
 
 	sm.mu.Lock()
-	if _, ok := sm.sessions[uuid]; ok {
+	if _, ok := sm.sessions[id]; ok {
 		sm.mu.Unlock()
-		return errors.Errorf("session %s already exists", uuid)
+		return errors.Errorf("session %s already exists", id)
 	}
 
 	if proto == "" {
@@ -102,8 +102,10 @@
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
 
+	opts = canonicalHeaders(opts)
+
 	h := http.Header(opts)
-	uuid := h.Get(headerSessionUUID)
+	id := h.Get(headerSessionID)
 	name := h.Get(headerSessionName)
 	sharedKey := h.Get(headerSessionSharedKey)
 
@@ -115,7 +117,7 @@
 
 	c := &client{
 		Session: Session{
-			uuid:      uuid,
+			id:        id,
 			name:      name,
 			sharedKey: sharedKey,
 			ctx:       ctx,
@@ -129,13 +131,13 @@
 	for _, m := range opts[headerSessionMethod] {
 		c.supported[strings.ToLower(m)] = struct{}{}
 	}
-	sm.sessions[uuid] = c
+	sm.sessions[id] = c
 	sm.updateCondition.Broadcast()
 	sm.mu.Unlock()
 
 	defer func() {
 		sm.mu.Lock()
-		delete(sm.sessions, uuid)
+		delete(sm.sessions, id)
 		sm.mu.Unlock()
 	}()
 
@@ -146,8 +148,8 @@
 	return nil
 }
 
-// Get returns a session by UUID
-func (sm *Manager) Get(ctx context.Context, uuid string) (Caller, error) {
+// Get returns a session by ID
+func (sm *Manager) Get(ctx context.Context, id string) (Caller, error) {
 	ctx, cancel := context.WithCancel(ctx)
 	defer cancel()
 
@@ -165,11 +167,11 @@
 		select {
 		case <-ctx.Done():
 			sm.mu.Unlock()
-			return nil, errors.Wrapf(ctx.Err(), "no active session for %s", uuid)
+			return nil, errors.Wrapf(ctx.Err(), "no active session for %s", id)
 		default:
 		}
 		var ok bool
-		c, ok = sm.sessions[uuid]
+		c, ok = sm.sessions[id]
 		if !ok || c.closed() {
 			sm.updateCondition.Wait()
 			continue
@@ -200,3 +202,11 @@
 func (c *client) Conn() *grpc.ClientConn {
 	return c.cc
 }
+
+func canonicalHeaders(in map[string][]string) map[string][]string {
+	out := map[string][]string{}
+	for k := range in {
+		out[http.CanonicalHeaderKey(k)] = in[k]
+	}
+	return out
+}
diff --git a/client/session/session.go b/vendor/github.com/moby/buildkit/session/session.go
similarity index 89%
rename from client/session/session.go
rename to vendor/github.com/moby/buildkit/session/session.go
index 147486a..454c3d7 100644
--- a/client/session/session.go
+++ b/vendor/github.com/moby/buildkit/session/session.go
@@ -12,7 +12,7 @@
 )
 
 const (
-	headerSessionUUID      = "X-Docker-Expose-Session-Uuid"
+	headerSessionID        = "X-Docker-Expose-Session-Uuid"
 	headerSessionName      = "X-Docker-Expose-Session-Name"
 	headerSessionSharedKey = "X-Docker-Expose-Session-Sharedkey"
 	headerSessionMethod    = "X-Docker-Expose-Session-Grpc-Method"
@@ -28,7 +28,7 @@
 
 // Session is a long running connection between client and a daemon
 type Session struct {
-	uuid       string
+	id         string
 	name       string
 	sharedKey  string
 	ctx        context.Context
@@ -39,9 +39,9 @@
 
 // NewSession returns a new long running session
 func NewSession(name, sharedKey string) (*Session, error) {
-	uuid := stringid.GenerateRandomID()
+	id := stringid.GenerateRandomID()
 	s := &Session{
-		uuid:       uuid,
+		id:         id,
 		name:       name,
 		sharedKey:  sharedKey,
 		grpcServer: grpc.NewServer(),
@@ -57,9 +57,9 @@
 	a.Register(s.grpcServer)
 }
 
-// UUID returns unique identifier for the session
-func (s *Session) UUID() string {
-	return s.uuid
+// ID returns unique identifier for the session
+func (s *Session) ID() string {
+	return s.id
 }
 
 // Run activates the session
@@ -72,7 +72,7 @@
 	defer close(s.done)
 
 	meta := make(map[string][]string)
-	meta[headerSessionUUID] = []string{s.uuid}
+	meta[headerSessionID] = []string{s.id}
 	meta[headerSessionName] = []string{s.name}
 	meta[headerSessionSharedKey] = []string{s.sharedKey}
 
@@ -92,6 +92,7 @@
 // Close closes the session
 func (s *Session) Close() error {
 	if s.cancelCtx != nil && s.done != nil {
+		s.grpcServer.Stop()
 		s.cancelCtx()
 		<-s.done
 	}
diff --git a/vendor/github.com/moby/buildkit/vendor.conf b/vendor/github.com/moby/buildkit/vendor.conf
new file mode 100644
index 0000000..f3760bd
--- /dev/null
+++ b/vendor/github.com/moby/buildkit/vendor.conf
@@ -0,0 +1,46 @@
+github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
+github.com/pkg/errors c605e284fe17294bda444b34710735b29d1a9d90
+
+github.com/stretchr/testify v1.1.4
+github.com/davecgh/go-spew v1.1.0
+github.com/pmezard/go-difflib v1.0.0
+golang.org/x/sys 739734461d1c916b6c72a63d7efda2b27edb369f
+
+github.com/containerd/containerd d1e11f17ec7b325f89608dd46c128300b8727d50
+golang.org/x/sync f52d1811a62927559de87708c8913c1650ce4f26
+github.com/sirupsen/logrus v1.0.0
+google.golang.org/grpc v1.3.0
+github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
+golang.org/x/net 1f9224279e98554b6a6432d4dd998a739f8b2b7c
+github.com/gogo/protobuf d2e1ade2d719b78fe5b061b4c18a9f7111b5bdc8
+github.com/golang/protobuf 5a0f697c9ed9d68fef0116532c6e05cfeae00e55
+github.com/containerd/continuity 86cec1535a968310e7532819f699ff2830ed7463
+github.com/opencontainers/image-spec v1.0.0
+github.com/opencontainers/runc e775f0fba3ea329b8b766451c892c41a3d49594d
+github.com/Microsoft/go-winio v0.4.1
+github.com/containerd/fifo 69b99525e472735860a5269b75af1970142b3062
+github.com/opencontainers/runtime-spec 96de01bbb42c7af89bff100e10a9f0fb62e75bfb
+github.com/containerd/go-runc 2774a2ea124a5c2d0aba13b5c2dd8a5a9a48775d
+github.com/containerd/console 7fed77e673ca4abcd0cbd6d4d0e0e22137cbd778
+github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e
+google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
+golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
+github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
+
+github.com/urfave/cli d70f47eeca3afd795160003bc6e28b001d60c67c
+github.com/docker/go-units 0dadbb0345b35ec7ef35e228dabb8de89a65bf52
+github.com/google/shlex 6f45313302b9c56850fc17f99e40caebce98c716
+golang.org/x/time 8be79e1e0910c292df4e79c241bb7e8f7e725959
+
+github.com/BurntSushi/locker 392720b78f44e9d0249fcac6c43b111b47a370b8
+github.com/docker/docker 6f723db8c6f0c7f0b252674a9673a25b5978db04 https://github.com/tonistiigi/docker.git
+github.com/pkg/profile 5b67d428864e92711fcbd2f8629456121a56d91f
+
+github.com/tonistiigi/fsutil 1dedf6e90084bd88c4c518a15e68a37ed1370203
+github.com/stevvooe/continuity 86cec1535a968310e7532819f699ff2830ed7463
+github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf
+github.com/hashicorp/go-immutable-radix 826af9ccf0feeee615d546d69b11f8e98da8c8f1 git://github.com/tonistiigi/go-immutable-radix.git
+github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
+github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b
+github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d
+github.com/docker/distribution 30578ca32960a4d368bf6db67b0a33c2a1f3dc6f
diff --git a/vendor/github.com/opencontainers/runc/README.md b/vendor/github.com/opencontainers/runc/README.md
index a951f0d..eabfb98 100644
--- a/vendor/github.com/opencontainers/runc/README.md
+++ b/vendor/github.com/opencontainers/runc/README.md
@@ -145,11 +145,33 @@
                         "TERM=xterm"
                 ],
                 "cwd": "/",
-                "capabilities": [
-                        "CAP_AUDIT_WRITE",
-                        "CAP_KILL",
-                        "CAP_NET_BIND_SERVICE"
-                ],
+                "capabilities": {
+                        "bounding": [
+                                "CAP_AUDIT_WRITE",
+                                "CAP_KILL",
+                                "CAP_NET_BIND_SERVICE"
+                        ],
+                        "effective": [
+                                "CAP_AUDIT_WRITE",
+                                "CAP_KILL",
+                                "CAP_NET_BIND_SERVICE"
+                        ],
+                        "inheritable": [
+                                "CAP_AUDIT_WRITE",
+                                "CAP_KILL",
+                                "CAP_NET_BIND_SERVICE"
+                        ],
+                        "permitted": [
+                                "CAP_AUDIT_WRITE",
+                                "CAP_KILL",
+                                "CAP_NET_BIND_SERVICE"
+                        ],
+                        "ambient": [
+                                "CAP_AUDIT_WRITE",
+                                "CAP_KILL",
+                                "CAP_NET_BIND_SERVICE"
+                        ]
+                },
                 "rlimits": [
                         {
                                 "type": "RLIMIT_NOFILE",
@@ -161,7 +183,7 @@
         },
 ```
 
-Now we can go though the lifecycle operations in your shell.
+Now we can go through the lifecycle operations in your shell.
 
 
 ```bash
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/README.md b/vendor/github.com/opencontainers/runc/libcontainer/README.md
index d2a7d78..42f3efe 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/README.md
+++ b/vendor/github.com/opencontainers/runc/libcontainer/README.md
@@ -56,25 +56,91 @@
 struct describing how the container is to be created. A sample would look similar to this:
 
 ```go
-defaultMountFlags := syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
+defaultMountFlags := unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV
 config := &configs.Config{
 	Rootfs: "/your/path/to/rootfs",
-	Capabilities: []string{
-		"CAP_CHOWN",
-		"CAP_DAC_OVERRIDE",
-		"CAP_FSETID",
-		"CAP_FOWNER",
-		"CAP_MKNOD",
-		"CAP_NET_RAW",
-		"CAP_SETGID",
-		"CAP_SETUID",
-		"CAP_SETFCAP",
-		"CAP_SETPCAP",
-		"CAP_NET_BIND_SERVICE",
-		"CAP_SYS_CHROOT",
-		"CAP_KILL",
-		"CAP_AUDIT_WRITE",
-	},
+	Capabilities: &configs.Capabilities{
+                Bounding: []string{
+                        "CAP_CHOWN",
+                        "CAP_DAC_OVERRIDE",
+                        "CAP_FSETID",
+                        "CAP_FOWNER",
+                        "CAP_MKNOD",
+                        "CAP_NET_RAW",
+                        "CAP_SETGID",
+                        "CAP_SETUID",
+                        "CAP_SETFCAP",
+                        "CAP_SETPCAP",
+                        "CAP_NET_BIND_SERVICE",
+                        "CAP_SYS_CHROOT",
+                        "CAP_KILL",
+                        "CAP_AUDIT_WRITE",
+                },
+                Effective: []string{
+                        "CAP_CHOWN",
+                        "CAP_DAC_OVERRIDE",
+                        "CAP_FSETID",
+                        "CAP_FOWNER",
+                        "CAP_MKNOD",
+                        "CAP_NET_RAW",
+                        "CAP_SETGID",
+                        "CAP_SETUID",
+                        "CAP_SETFCAP",
+                        "CAP_SETPCAP",
+                        "CAP_NET_BIND_SERVICE",
+                        "CAP_SYS_CHROOT",
+                        "CAP_KILL",
+                        "CAP_AUDIT_WRITE",
+                },
+                Inheritable: []string{
+                        "CAP_CHOWN",
+                        "CAP_DAC_OVERRIDE",
+                        "CAP_FSETID",
+                        "CAP_FOWNER",
+                        "CAP_MKNOD",
+                        "CAP_NET_RAW",
+                        "CAP_SETGID",
+                        "CAP_SETUID",
+                        "CAP_SETFCAP",
+                        "CAP_SETPCAP",
+                        "CAP_NET_BIND_SERVICE",
+                        "CAP_SYS_CHROOT",
+                        "CAP_KILL",
+                        "CAP_AUDIT_WRITE",
+                },
+                Permitted: []string{
+                        "CAP_CHOWN",
+                        "CAP_DAC_OVERRIDE",
+                        "CAP_FSETID",
+                        "CAP_FOWNER",
+                        "CAP_MKNOD",
+                        "CAP_NET_RAW",
+                        "CAP_SETGID",
+                        "CAP_SETUID",
+                        "CAP_SETFCAP",
+                        "CAP_SETPCAP",
+                        "CAP_NET_BIND_SERVICE",
+                        "CAP_SYS_CHROOT",
+                        "CAP_KILL",
+                        "CAP_AUDIT_WRITE",
+                },
+                Ambient: []string{
+                        "CAP_CHOWN",
+                        "CAP_DAC_OVERRIDE",
+                        "CAP_FSETID",
+                        "CAP_FOWNER",
+                        "CAP_MKNOD",
+                        "CAP_NET_RAW",
+                        "CAP_SETGID",
+                        "CAP_SETUID",
+                        "CAP_SETFCAP",
+                        "CAP_SETPCAP",
+                        "CAP_NET_BIND_SERVICE",
+                        "CAP_SYS_CHROOT",
+                        "CAP_KILL",
+                        "CAP_AUDIT_WRITE",
+                },
+        },
 	Namespaces: configs.Namespaces([]configs.Namespace{
 		{Type: configs.NEWNS},
 		{Type: configs.NEWUTS},
@@ -112,14 +178,14 @@
 			Source:      "tmpfs",
 			Destination: "/dev",
 			Device:      "tmpfs",
-			Flags:       syscall.MS_NOSUID | syscall.MS_STRICTATIME,
+			Flags:       unix.MS_NOSUID | unix.MS_STRICTATIME,
 			Data:        "mode=755",
 		},
 		{
 			Source:      "devpts",
 			Destination: "/dev/pts",
 			Device:      "devpts",
-			Flags:       syscall.MS_NOSUID | syscall.MS_NOEXEC,
+			Flags:       unix.MS_NOSUID | unix.MS_NOEXEC,
 			Data:        "newinstance,ptmxmode=0666,mode=0620,gid=5",
 		},
 		{
@@ -139,7 +205,7 @@
 			Source:      "sysfs",
 			Destination: "/sys",
 			Device:      "sysfs",
-			Flags:       defaultMountFlags | syscall.MS_RDONLY,
+			Flags:       defaultMountFlags | unix.MS_RDONLY,
 		},
 	},
 	UidMappings: []configs.IDMap{
@@ -165,7 +231,7 @@
 	},
 	Rlimits: []configs.Rlimit{
 		{
-			Type: syscall.RLIMIT_NOFILE,
+			Type: unix.RLIMIT_NOFILE,
 			Hard: uint64(1025),
 			Soft: uint64(1025),
 		},
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
index b483f1b..8eeedc5 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go
@@ -51,6 +51,8 @@
 	KernelUsage MemoryData `json:"kernel_usage,omitempty"`
 	// usage of kernel TCP memory
 	KernelTCPUsage MemoryData `json:"kernel_tcp_usage,omitempty"`
+	// if true, memory usage is accounted for throughout a hierarchy of cgroups.
+	UseHierarchy bool `json:"use_hierarchy"`
 
 	Stats map[string]uint64 `json:"stats,omitempty"`
 }
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
index 5db3734..7c995ef 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go
@@ -66,6 +66,21 @@
 	return avail
 }
 
+func GetClosestMountpointAncestor(dir, mountinfo string) string {
+	deepestMountPoint := ""
+	for _, mountInfoEntry := range strings.Split(mountinfo, "\n") {
+		mountInfoParts := strings.Fields(mountInfoEntry)
+		if len(mountInfoParts) < 5 {
+			continue
+		}
+		mountPoint := mountInfoParts[4]
+		if strings.HasPrefix(mountPoint, deepestMountPoint) && strings.HasPrefix(dir, mountPoint) {
+			deepestMountPoint = mountPoint
+		}
+	}
+	return deepestMountPoint
+}
+
 func FindCgroupMountpointDir() (string, error) {
 	f, err := os.Open("/proc/self/mountinfo")
 	if err != nil {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go
similarity index 93%
rename from vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go
rename to vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go
index 7572289..e15a662 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go
@@ -1,5 +1,3 @@
-// +build linux freebsd
-
 package configs
 
 type FreezerState string
@@ -45,19 +43,19 @@
 	Devices []*Device `json:"devices"`
 
 	// Memory limit (in bytes)
-	Memory uint64 `json:"memory"`
+	Memory int64 `json:"memory"`
 
 	// Memory reservation or soft_limit (in bytes)
-	MemoryReservation uint64 `json:"memory_reservation"`
+	MemoryReservation int64 `json:"memory_reservation"`
 
 	// Total memory usage (memory + swap); set `-1` to enable unlimited swap
-	MemorySwap uint64 `json:"memory_swap"`
+	MemorySwap int64 `json:"memory_swap"`
 
 	// Kernel memory limit (in bytes)
-	KernelMemory uint64 `json:"kernel_memory"`
+	KernelMemory int64 `json:"kernel_memory"`
 
 	// Kernel memory limit for TCP use (in bytes)
-	KernelMemoryTCP uint64 `json:"kernel_memory_tcp"`
+	KernelMemoryTCP int64 `json:"kernel_memory_tcp"`
 
 	// CPU shares (relative weight vs. other containers)
 	CpuShares uint64 `json:"cpu_shares"`
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
index 98f4b85..3cae4fd 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
@@ -7,8 +7,9 @@
 	"os/exec"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/opencontainers/runtime-spec/specs-go"
+
+	"github.com/sirupsen/logrus"
 )
 
 type Rlimit struct {
@@ -186,6 +187,10 @@
 
 	// Rootless specifies whether the container is a rootless container.
 	Rootless bool `json:"rootless"`
+
+	// IntelRdt specifies settings for Intel RDT/CAT group that the container is placed into
+	// to limit the resources (e.g., L3 cache) the container has available
+	IntelRdt *IntelRdt `json:"intel_rdt,omitempty"`
 }
 
 type Hooks struct {
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_linux.go
similarity index 98%
rename from vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix.go
rename to vendor/github.com/opencontainers/runc/libcontainer/configs/config_linux.go
index 8446399..07da108 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config_linux.go
@@ -1,5 +1,3 @@
-// +build freebsd linux
-
 package configs
 
 import "fmt"
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/intelrdt.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/intelrdt.go
new file mode 100644
index 0000000..36bd5f9
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/intelrdt.go
@@ -0,0 +1,7 @@
+package configs
+
+type IntelRdt struct {
+	// The schema for L3 cache id and capacity bitmask (CBM)
+	// Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
+	L3CacheSchema string `json:"l3_cache_schema,omitempty"`
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
similarity index 97%
rename from vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unix.go
rename to vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
index 1f0b3ee..5fc171a 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
@@ -1,5 +1,3 @@
-// +build linux freebsd
-
 package configs
 
 import (
@@ -81,9 +79,6 @@
 }
 
 func (n *Namespace) GetPath(pid int) string {
-	if n.Path != "" {
-		return n.Path
-	}
 	return fmt.Sprintf("/proc/%d/ns/%s", pid, NsName(n.Type))
 }
 
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall.go
index fb4b852..4ce6813 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall.go
@@ -2,19 +2,19 @@
 
 package configs
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
 func (n *Namespace) Syscall() int {
 	return namespaceInfo[n.Type]
 }
 
 var namespaceInfo = map[NamespaceType]int{
-	NEWNET:  syscall.CLONE_NEWNET,
-	NEWNS:   syscall.CLONE_NEWNS,
-	NEWUSER: syscall.CLONE_NEWUSER,
-	NEWIPC:  syscall.CLONE_NEWIPC,
-	NEWUTS:  syscall.CLONE_NEWUTS,
-	NEWPID:  syscall.CLONE_NEWPID,
+	NEWNET:  unix.CLONE_NEWNET,
+	NEWNS:   unix.CLONE_NEWNS,
+	NEWUSER: unix.CLONE_NEWUSER,
+	NEWIPC:  unix.CLONE_NEWIPC,
+	NEWUTS:  unix.CLONE_NEWUTS,
+	NEWPID:  unix.CLONE_NEWPID,
 }
 
 // CloneFlags parses the container's Namespaces options to set the correct
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unsupported.go
index 9a74033..19bf713 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unsupported.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unsupported.go
@@ -1,4 +1,4 @@
-// +build !linux,!freebsd
+// +build !linux
 
 package configs
 
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
similarity index 71%
rename from vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unix.go
rename to vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
index f44e62c..326ad3b 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
@@ -1,16 +1,14 @@
-// +build linux freebsd
-
 package devices
 
 import (
 	"errors"
-	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
-	"syscall"
 
 	"github.com/opencontainers/runc/libcontainer/configs"
+
+	"golang.org/x/sys/unix"
 )
 
 var (
@@ -19,45 +17,45 @@
 
 // Testing dependencies
 var (
-	osLstat       = os.Lstat
+	unixLstat     = unix.Lstat
 	ioutilReadDir = ioutil.ReadDir
 )
 
 // Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
 func DeviceFromPath(path, permissions string) (*configs.Device, error) {
-	fileInfo, err := osLstat(path)
+	var stat unix.Stat_t
+	err := unixLstat(path, &stat)
 	if err != nil {
 		return nil, err
 	}
+
 	var (
-		devType                rune
-		mode                   = fileInfo.Mode()
-		fileModePermissionBits = os.FileMode.Perm(mode)
+		devNumber = int(stat.Rdev)
+		major     = Major(devNumber)
+	)
+	if major == 0 {
+		return nil, ErrNotADevice
+	}
+
+	var (
+		devType rune
+		mode    = stat.Mode
 	)
 	switch {
-	case mode&os.ModeDevice == 0:
-		return nil, ErrNotADevice
-	case mode&os.ModeCharDevice != 0:
-		fileModePermissionBits |= syscall.S_IFCHR
-		devType = 'c'
-	default:
-		fileModePermissionBits |= syscall.S_IFBLK
+	case mode&unix.S_IFBLK == unix.S_IFBLK:
 		devType = 'b'
+	case mode&unix.S_IFCHR == unix.S_IFCHR:
+		devType = 'c'
 	}
-	stat_t, ok := fileInfo.Sys().(*syscall.Stat_t)
-	if !ok {
-		return nil, fmt.Errorf("cannot determine the device number for device %s", path)
-	}
-	devNumber := int(stat_t.Rdev)
 	return &configs.Device{
 		Type:        devType,
 		Path:        path,
-		Major:       Major(devNumber),
+		Major:       major,
 		Minor:       Minor(devNumber),
 		Permissions: permissions,
-		FileMode:    fileModePermissionBits,
-		Uid:         stat_t.Uid,
-		Gid:         stat_t.Gid,
+		FileMode:    os.FileMode(mode),
+		Uid:         stat.Uid,
+		Gid:         stat.Gid,
 	}, nil
 }
 
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go
index 1e84033..6649b9f 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go
@@ -1,3 +1,3 @@
-// +build windows
+// +build !linux
 
 package devices
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
index 0ad6883..a6a107e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
+++ b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
@@ -1,3 +1,4 @@
+
 #define _GNU_SOURCE
 #include <endian.h>
 #include <errno.h>
@@ -19,6 +20,8 @@
 #include <sys/prctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/wait.h>
+
 
 #include <linux/limits.h>
 #include <linux/netlink.h>
@@ -64,7 +67,13 @@
 
 struct nlconfig_t {
 	char *data;
+
+	/* Process settings. */
 	uint32_t cloneflags;
+	char *oom_score_adj;
+	size_t oom_score_adj_len;
+
+	/* User namespace settings.*/
 	char *uidmap;
 	size_t uidmap_len;
 	char *gidmap;
@@ -72,9 +81,13 @@
 	char *namespaces;
 	size_t namespaces_len;
 	uint8_t is_setgroup;
+
+	/* Rootless container settings.*/
 	uint8_t is_rootless;
-	char *oom_score_adj;
-	size_t oom_score_adj_len;
+	char *uidmappath;
+	size_t uidmappath_len;
+	char *gidmappath;
+	size_t gidmappath_len;
 };
 
 /*
@@ -89,6 +102,8 @@
 #define SETGROUP_ATTR		27285
 #define OOM_SCORE_ADJ_ATTR	27286
 #define ROOTLESS_ATTR	    27287
+#define UIDMAPPATH_ATTR	    27288
+#define GIDMAPPATH_ATTR	    27289
 
 /*
  * Use the raw syscall for versions of glibc which don't include a function for
@@ -143,8 +158,7 @@
 
 	fd = open(path, O_RDWR);
 	if (fd < 0) {
-		ret = -1;
-		goto out;
+		return -1;
 	}
 
 	len = write(fd, data, data_len);
@@ -192,22 +206,96 @@
 	}
 }
 
-static void update_uidmap(int pid, char *map, size_t map_len)
+static int try_mapping_tool(const char *app, int pid, char *map, size_t map_len)
 {
-	if (map == NULL || map_len <= 0)
-		return;
+	int child;
 
-	if (write_file(map, map_len, "/proc/%d/uid_map", pid) < 0)
-		bail("failed to update /proc/%d/uid_map", pid);
+	/*
+	 * If @app is NULL, execve will segfault. Just check it here and bail (if
+	 * we're in this path, the caller is already getting desparate and there
+	 * isn't a backup to this failing). This usually would be a configuration
+	 * or programming issue.
+	 */
+	if (!app)
+		bail("mapping tool not present");
+
+	child = fork();
+	if (child < 0)
+		bail("failed to fork");
+
+	if (!child) {
+#define MAX_ARGV 20
+		char *argv[MAX_ARGV];
+		char *envp[] = {NULL};
+		char pid_fmt[16];
+		int argc = 0;
+		char *next;
+
+		snprintf(pid_fmt, 16, "%d", pid);
+
+		argv[argc++] = (char *) app;
+		argv[argc++] = pid_fmt;
+		/*
+		 * Convert the map string into a list of argument that
+		 * newuidmap/newgidmap can understand.
+		 */
+
+		while (argc < MAX_ARGV) {
+			if (*map == '\0') {
+				argv[argc++] = NULL;
+				break;
+			}
+			argv[argc++] = map;
+			next = strpbrk(map, "\n ");
+			if (next == NULL)
+				break;
+			*next++ = '\0';
+			map = next + strspn(next, "\n ");
+		}
+
+		execve(app, argv, envp);
+		bail("failed to execv");
+	} else {
+		int status;
+
+		while (true) {
+			if (waitpid(child, &status, 0) < 0) {
+				if (errno == EINTR)
+					continue;
+				bail("failed to waitpid");
+			}
+			if (WIFEXITED(status) || WIFSIGNALED(status))
+				return WEXITSTATUS(status);
+		}
+	}
+
+	return -1;
 }
 
-static void update_gidmap(int pid, char *map, size_t map_len)
+static void update_uidmap(const char *path, int pid, char *map, size_t map_len)
 {
 	if (map == NULL || map_len <= 0)
 		return;
 
-	if (write_file(map, map_len, "/proc/%d/gid_map", pid) < 0)
-		bail("failed to update /proc/%d/gid_map", pid);
+	if (write_file(map, map_len, "/proc/%d/uid_map", pid) < 0) {
+		if (errno != EPERM)
+			bail("failed to update /proc/%d/uid_map", pid);
+		if (try_mapping_tool(path, pid, map, map_len))
+			bail("failed to use newuid map on %d", pid);
+	}
+}
+
+static void update_gidmap(const char *path, int pid, char *map, size_t map_len)
+{
+	if (map == NULL || map_len <= 0)
+		return;
+
+	if (write_file(map, map_len, "/proc/%d/gid_map", pid) < 0) {
+		if (errno != EPERM)
+			bail("failed to update /proc/%d/gid_map", pid);
+		if (try_mapping_tool(path, pid, map, map_len))
+			bail("failed to use newgid map on %d", pid);
+	}
 }
 
 static void update_oom_score_adj(char *data, size_t len)
@@ -351,6 +439,14 @@
 			config->gidmap = current;
 			config->gidmap_len = payload_len;
 			break;
+		case UIDMAPPATH_ATTR:
+			config->uidmappath = current;
+			config->uidmappath_len = payload_len;
+			break;
+		case GIDMAPPATH_ATTR:
+			config->gidmappath = current;
+			config->gidmappath_len = payload_len;
+			break;
 		case SETGROUP_ATTR:
 			config->is_setgroup = readint8(current);
 			break;
@@ -543,7 +639,7 @@
 	 */
 	case JUMP_PARENT: {
 			int len;
-			pid_t child;
+			pid_t child, first_child = -1;
 			char buf[JSON_MAX];
 			bool ready = false;
 
@@ -597,8 +693,8 @@
 						update_setgroups(child, SETGROUPS_DENY);
 
 					/* Set up mappings. */
-					update_uidmap(child, config.uidmap, config.uidmap_len);
-					update_gidmap(child, config.gidmap, config.gidmap_len);
+					update_uidmap(config.uidmappath, child, config.uidmap, config.uidmap_len);
+					update_gidmap(config.gidmappath, child, config.gidmap, config.gidmap_len);
 
 					s = SYNC_USERMAP_ACK;
 					if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
@@ -607,18 +703,18 @@
 					}
 					break;
 				case SYNC_RECVPID_PLS: {
-						pid_t old = child;
+						first_child = child;
 
 						/* Get the init_func pid. */
 						if (read(syncfd, &child, sizeof(child)) != sizeof(child)) {
-							kill(old, SIGKILL);
+							kill(first_child, SIGKILL);
 							bail("failed to sync with child: read(childpid)");
 						}
 
 						/* Send ACK. */
 						s = SYNC_RECVPID_ACK;
 						if (write(syncfd, &s, sizeof(s)) != sizeof(s)) {
-							kill(old, SIGKILL);
+							kill(first_child, SIGKILL);
 							kill(child, SIGKILL);
 							bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
 						}
@@ -666,8 +762,13 @@
 				}
 			}
 
-			/* Send the init_func pid back to our parent. */
-			len = snprintf(buf, JSON_MAX, "{\"pid\": %d}\n", child);
+			/*
+			 * Send the init_func pid and the pid of the first child back to our parent.
+			 *
+			 * We need to send both back because we can't reap the first child we created (CLONE_PARENT).
+			 * It becomes the responsibility of our parent to reap the first child.
+			 */
+			len = snprintf(buf, JSON_MAX, "{\"pid\": %d, \"pid_first\": %d}\n", child, first_child);
 			if (len < 0) {
 				kill(child, SIGKILL);
 				bail("unable to generate JSON for child pid");
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go
index 1afc52b..4837085 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go
@@ -7,8 +7,10 @@
 	"fmt"
 	"os"
 	"os/exec"
-	"syscall"
+	"syscall" // only for exec
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 // If arg2 is nonzero, set the "child subreaper" attribute of the
@@ -53,8 +55,8 @@
 	return syscall.Exec(name, args, env)
 }
 
-func Prlimit(pid, resource int, limit syscall.Rlimit) error {
-	_, _, err := syscall.RawSyscall6(syscall.SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(&limit)), uintptr(unsafe.Pointer(&limit)), 0, 0)
+func Prlimit(pid, resource int, limit unix.Rlimit) error {
+	_, _, err := unix.RawSyscall6(unix.SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(&limit)), uintptr(unsafe.Pointer(&limit)), 0, 0)
 	if err != 0 {
 		return err
 	}
@@ -62,7 +64,7 @@
 }
 
 func SetParentDeathSignal(sig uintptr) error {
-	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, sig, 0); err != 0 {
+	if err := unix.Prctl(unix.PR_SET_PDEATHSIG, sig, 0, 0, 0); err != nil {
 		return err
 	}
 	return nil
@@ -70,15 +72,14 @@
 
 func GetParentDeathSignal() (ParentDeathSignal, error) {
 	var sig int
-	_, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0)
-	if err != 0 {
+	if err := unix.Prctl(unix.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0, 0, 0); err != nil {
 		return -1, err
 	}
 	return ParentDeathSignal(sig), nil
 }
 
 func SetKeepCaps() error {
-	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 1, 0); err != 0 {
+	if err := unix.Prctl(unix.PR_SET_KEEPCAPS, 1, 0, 0, 0); err != nil {
 		return err
 	}
 
@@ -86,7 +87,7 @@
 }
 
 func ClearKeepCaps() error {
-	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 0, 0); err != 0 {
+	if err := unix.Prctl(unix.PR_SET_KEEPCAPS, 0, 0, 0, 0); err != nil {
 		return err
 	}
 
@@ -94,7 +95,7 @@
 }
 
 func Setctty() error {
-	if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 {
+	if err := unix.IoctlSetInt(0, unix.TIOCSCTTY, 0); err != nil {
 		return err
 	}
 	return nil
@@ -131,13 +132,5 @@
 
 // SetSubreaper sets the value i as the subreaper setting for the calling process
 func SetSubreaper(i int) error {
-	return Prctl(PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0)
-}
-
-func Prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {
-	_, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
+	return unix.Prctl(PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0)
 }
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
index a0e9637..79232a4 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go
@@ -1,43 +1,113 @@
 package system
 
 import (
+	"fmt"
 	"io/ioutil"
 	"path/filepath"
 	"strconv"
 	"strings"
 )
 
-// look in /proc to find the process start time so that we can verify
-// that this pid has started after ourself
+// State is the status of a process.
+type State rune
+
+const ( // Only values for Linux 3.14 and later are listed here
+	Dead        State = 'X'
+	DiskSleep   State = 'D'
+	Running     State = 'R'
+	Sleeping    State = 'S'
+	Stopped     State = 'T'
+	TracingStop State = 't'
+	Zombie      State = 'Z'
+)
+
+// String forms of the state from proc(5)'s documentation for
+// /proc/[pid]/status' "State" field.
+func (s State) String() string {
+	switch s {
+	case Dead:
+		return "dead"
+	case DiskSleep:
+		return "disk sleep"
+	case Running:
+		return "running"
+	case Sleeping:
+		return "sleeping"
+	case Stopped:
+		return "stopped"
+	case TracingStop:
+		return "tracing stop"
+	case Zombie:
+		return "zombie"
+	default:
+		return fmt.Sprintf("unknown (%c)", s)
+	}
+}
+
+// Stat_t represents the information from /proc/[pid]/stat, as
+// described in proc(5) with names based on the /proc/[pid]/status
+// fields.
+type Stat_t struct {
+	// PID is the process ID.
+	PID uint
+
+	// Name is the command run by the process.
+	Name string
+
+	// State is the state of the process.
+	State State
+
+	// StartTime is the number of clock ticks after system boot (since
+	// Linux 2.6).
+	StartTime uint64
+}
+
+// Stat returns a Stat_t instance for the specified process.
+func Stat(pid int) (stat Stat_t, err error) {
+	bytes, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat"))
+	if err != nil {
+		return stat, err
+	}
+	return parseStat(string(bytes))
+}
+
+// GetProcessStartTime is deprecated.  Use Stat(pid) and
+// Stat_t.StartTime instead.
 func GetProcessStartTime(pid int) (string, error) {
-	data, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat"))
+	stat, err := Stat(pid)
 	if err != nil {
 		return "", err
 	}
-	return parseStartTime(string(data))
+	return fmt.Sprintf("%d", stat.StartTime), nil
 }
 
-func parseStartTime(stat string) (string, error) {
-	// the starttime is located at pos 22
-	// from the man page
-	//
-	// starttime %llu (was %lu before Linux 2.6)
-	// (22)  The  time the process started after system boot.  In kernels before Linux 2.6, this
-	// value was expressed in jiffies.  Since Linux 2.6, the value is expressed in  clock  ticks
-	// (divide by sysconf(_SC_CLK_TCK)).
-	//
-	// NOTE:
-	// pos 2 could contain space and is inside `(` and `)`:
-	// (2) comm  %s
-	// The filename of the executable, in parentheses.
-	// This is visible whether or not the executable is
-	// swapped out.
-	//
-	// the following is an example:
+func parseStat(data string) (stat Stat_t, err error) {
+	// From proc(5), field 2 could contain space and is inside `(` and `)`.
+	// The following is an example:
 	// 89653 (gunicorn: maste) S 89630 89653 89653 0 -1 4194560 29689 28896 0 3 146 32 76 19 20 0 1 0 2971844 52965376 3920 18446744073709551615 1 1 0 0 0 0 0 16781312 137447943 0 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+	i := strings.LastIndex(data, ")")
+	if i <= 2 || i >= len(data)-1 {
+		return stat, fmt.Errorf("invalid stat data: %q", data)
+	}
 
-	// get parts after last `)`:
-	s := strings.Split(stat, ")")
-	parts := strings.Split(strings.TrimSpace(s[len(s)-1]), " ")
-	return parts[22-3], nil // starts at 3 (after the filename pos `2`)
+	parts := strings.SplitN(data[:i], "(", 2)
+	if len(parts) != 2 {
+		return stat, fmt.Errorf("invalid stat data: %q", data)
+	}
+
+	stat.Name = parts[1]
+	_, err = fmt.Sscanf(parts[0], "%d", &stat.PID)
+	if err != nil {
+		return stat, err
+	}
+
+	// parts indexes should be offset by 3 from the field number given
+	// proc(5), because parts is zero-indexed and we've removed fields
+	// one (PID) and two (Name) in the paren-split.
+	parts = strings.Split(data[i+2:], " ")
+	var state int
+	fmt.Sscanf(parts[3-3], "%c", &state)
+	stat.State = State(state)
+	fmt.Sscanf(parts[22-3], "%d", &stat.StartTime)
+	return stat, nil
 }
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/setns_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/setns_linux.go
deleted file mode 100644
index 615ff4c..0000000
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/setns_linux.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package system
-
-import (
-	"fmt"
-	"runtime"
-	"syscall"
-)
-
-// Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092
-//
-// We need different setns values for the different platforms and arch
-// We are declaring the macro here because the SETNS syscall does not exist in th stdlib
-var setNsMap = map[string]uintptr{
-	"linux/386":     346,
-	"linux/arm64":   268,
-	"linux/amd64":   308,
-	"linux/arm":     375,
-	"linux/ppc":     350,
-	"linux/ppc64":   350,
-	"linux/ppc64le": 350,
-	"linux/s390x":   339,
-}
-
-var sysSetns = setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)]
-
-func SysSetns() uint32 {
-	return uint32(sysSetns)
-}
-
-func Setns(fd uintptr, flags uintptr) error {
-	ns, exists := setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)]
-	if !exists {
-		return fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH)
-	}
-	_, _, err := syscall.RawSyscall(ns, fd, flags, 0)
-	if err != 0 {
-		return err
-	}
-	return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go
index bb44d89..3f7235e 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go
@@ -3,12 +3,12 @@
 package system
 
 import (
-	"syscall"
+	"golang.org/x/sys/unix"
 )
 
 // Setuid sets the uid of the calling thread to the specified uid.
 func Setuid(uid int) (err error) {
-	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0)
+	_, _, e1 := unix.RawSyscall(unix.SYS_SETUID32, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = e1
 	}
@@ -17,7 +17,7 @@
 
 // Setgid sets the gid of the calling thread to the specified gid.
 func Setgid(gid int) (err error) {
-	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0)
+	_, _, e1 := unix.RawSyscall(unix.SYS_SETGID32, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = e1
 	}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go
index 0816bf8..d7891a2 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go
@@ -3,12 +3,12 @@
 package system
 
 import (
-	"syscall"
+	"golang.org/x/sys/unix"
 )
 
 // Setuid sets the uid of the calling thread to the specified uid.
 func Setuid(uid int) (err error) {
-	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := unix.RawSyscall(unix.SYS_SETUID, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = e1
 	}
@@ -17,7 +17,7 @@
 
 // Setgid sets the gid of the calling thread to the specified gid.
 func Setgid(gid int) (err error) {
-	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := unix.RawSyscall(unix.SYS_SETGID, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = e1
 	}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_arm.go b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_arm.go
index 3f780f3..31ff3de 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_arm.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_arm.go
@@ -3,12 +3,12 @@
 package system
 
 import (
-	"syscall"
+	"golang.org/x/sys/unix"
 )
 
 // Setuid sets the uid of the calling thread to the specified uid.
 func Setuid(uid int) (err error) {
-	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0)
+	_, _, e1 := unix.RawSyscall(unix.SYS_SETUID32, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = e1
 	}
@@ -17,7 +17,7 @@
 
 // Setgid sets the gid of the calling thread to the specified gid.
 func Setgid(gid int) (err error) {
-	_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0)
+	_, _, e1 := unix.RawSyscall(unix.SYS_SETGID32, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = e1
 	}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go
index 30f74df..a6823fc 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go
@@ -1,99 +1,35 @@
 package system
 
-import (
-	"syscall"
-	"unsafe"
-)
-
-var _zero uintptr
-
-// Returns the size of xattrs and nil error
-// Requires path, takes allocated []byte or nil as last argument
-func Llistxattr(path string, dest []byte) (size int, err error) {
-	pathBytes, err := syscall.BytePtrFromString(path)
-	if err != nil {
-		return -1, err
-	}
-	var newpathBytes unsafe.Pointer
-	if len(dest) > 0 {
-		newpathBytes = unsafe.Pointer(&dest[0])
-	} else {
-		newpathBytes = unsafe.Pointer(&_zero)
-	}
-
-	_size, _, errno := syscall.Syscall6(syscall.SYS_LLISTXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(newpathBytes), uintptr(len(dest)), 0, 0, 0)
-	size = int(_size)
-	if errno != 0 {
-		return -1, errno
-	}
-
-	return size, nil
-}
+import "golang.org/x/sys/unix"
 
 // Returns a []byte slice if the xattr is set and nil otherwise
 // Requires path and its attribute as arguments
 func Lgetxattr(path string, attr string) ([]byte, error) {
 	var sz int
-	pathBytes, err := syscall.BytePtrFromString(path)
-	if err != nil {
-		return nil, err
-	}
-	attrBytes, err := syscall.BytePtrFromString(attr)
-	if err != nil {
-		return nil, err
-	}
-
 	// Start with a 128 length byte array
-	sz = 128
-	dest := make([]byte, sz)
-	destBytes := unsafe.Pointer(&dest[0])
-	_sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
+	dest := make([]byte, 128)
+	sz, errno := unix.Lgetxattr(path, attr, dest)
 
 	switch {
-	case errno == syscall.ENODATA:
+	case errno == unix.ENODATA:
 		return nil, errno
-	case errno == syscall.ENOTSUP:
+	case errno == unix.ENOTSUP:
 		return nil, errno
-	case errno == syscall.ERANGE:
+	case errno == unix.ERANGE:
 		// 128 byte array might just not be good enough,
-		// A dummy buffer is used ``uintptr(0)`` to get real size
+		// A dummy buffer is used to get the real size
 		// of the xattrs on disk
-		_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0)
-		sz = int(_sz)
-		if sz < 0 {
+		sz, errno = unix.Lgetxattr(path, attr, []byte{})
+		if errno != nil {
 			return nil, errno
 		}
 		dest = make([]byte, sz)
-		destBytes := unsafe.Pointer(&dest[0])
-		_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0)
-		if errno != 0 {
+		sz, errno = unix.Lgetxattr(path, attr, dest)
+		if errno != nil {
 			return nil, errno
 		}
-	case errno != 0:
+	case errno != nil:
 		return nil, errno
 	}
-	sz = int(_sz)
 	return dest[:sz], nil
 }
-
-func Lsetxattr(path string, attr string, data []byte, flags int) error {
-	pathBytes, err := syscall.BytePtrFromString(path)
-	if err != nil {
-		return err
-	}
-	attrBytes, err := syscall.BytePtrFromString(attr)
-	if err != nil {
-		return err
-	}
-	var dataBytes unsafe.Pointer
-	if len(data) > 0 {
-		dataBytes = unsafe.Pointer(&data[0])
-	} else {
-		dataBytes = unsafe.Pointer(&_zero)
-	}
-	_, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
-	if errno != 0 {
-		return errno
-	}
-	return nil
-}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
index ab1439f..95e9eeb 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go
@@ -2,7 +2,6 @@
 
 import (
 	"errors"
-	"syscall"
 )
 
 var (
@@ -36,13 +35,6 @@
 	return users[0], nil
 }
 
-// CurrentUser looks up the current user by their user id in /etc/passwd. If the
-// user cannot be found (or there is no /etc/passwd file on the filesystem),
-// then CurrentUser returns an error.
-func CurrentUser() (User, error) {
-	return LookupUid(syscall.Getuid())
-}
-
 // LookupUser looks up a user by their username in /etc/passwd. If the user
 // cannot be found (or there is no /etc/passwd file on the filesystem), then
 // LookupUser returns an error.
@@ -84,13 +76,6 @@
 	return groups[0], nil
 }
 
-// CurrentGroup looks up the current user's group by their primary group id's
-// entry in /etc/passwd. If the group cannot be found (or there is no
-// /etc/group file on the filesystem), then CurrentGroup returns an error.
-func CurrentGroup() (Group, error) {
-	return LookupGid(syscall.Getgid())
-}
-
 // LookupGroup looks up a group by its name in /etc/group. If the group cannot
 // be found (or there is no /etc/group file on the filesystem), then LookupGroup
 // returns an error.
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
index 758b734..c2bb9ec 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go
@@ -5,6 +5,8 @@
 import (
 	"io"
 	"os"
+
+	"golang.org/x/sys/unix"
 )
 
 // Unix-specific path to the passwd and group formatted files.
@@ -28,3 +30,17 @@
 func GetGroup() (io.ReadCloser, error) {
 	return os.Open(unixGroupPath)
 }
+
+// CurrentUser looks up the current user by their user id in /etc/passwd. If the
+// user cannot be found (or there is no /etc/passwd file on the filesystem),
+// then CurrentUser returns an error.
+func CurrentUser() (User, error) {
+	return LookupUid(unix.Getuid())
+}
+
+// CurrentGroup looks up the current user's group by their primary group id's
+// entry in /etc/passwd. If the group cannot be found (or there is no
+// /etc/group file on the filesystem), then CurrentGroup returns an error.
+func CurrentGroup() (Group, error) {
+	return LookupGid(unix.Getgid())
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go
index 7217948..4a8d00a 100644
--- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go
+++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go
@@ -2,7 +2,10 @@
 
 package user
 
-import "io"
+import (
+	"io"
+	"syscall"
+)
 
 func GetPasswdPath() (string, error) {
 	return "", ErrUnsupported
@@ -19,3 +22,17 @@
 func GetGroup() (io.ReadCloser, error) {
 	return nil, ErrUnsupported
 }
+
+// CurrentUser looks up the current user by their user id in /etc/passwd. If the
+// user cannot be found (or there is no /etc/passwd file on the filesystem),
+// then CurrentUser returns an error.
+func CurrentUser() (User, error) {
+	return LookupUid(syscall.Getuid())
+}
+
+// CurrentGroup looks up the current user's group by their primary group id's
+// entry in /etc/passwd. If the group cannot be found (or there is no
+// /etc/group file on the filesystem), then CurrentGroup returns an error.
+func CurrentGroup() (Group, error) {
+	return LookupGid(syscall.Getgid())
+}
diff --git a/vendor/github.com/opencontainers/runc/vendor.conf b/vendor/github.com/opencontainers/runc/vendor.conf
index 6ab9bf8..1266ee4 100644
--- a/vendor/github.com/opencontainers/runc/vendor.conf
+++ b/vendor/github.com/opencontainers/runc/vendor.conf
@@ -1,21 +1,25 @@
 # OCI runtime-spec. When updating this, make sure you use a version tag rather
 # than a commit ID so it's much more obvious what version of the spec we are
 # using.
-github.com/opencontainers/runtime-spec v1.0.0-rc5
+github.com/opencontainers/runtime-spec v1.0.0
 # Core libcontainer functionality.
 github.com/mrunalp/fileutils ed869b029674c0e9ce4c0dfa781405c2d9946d08
 github.com/opencontainers/selinux v1.0.0-rc1
 github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
-github.com/Sirupsen/logrus 26709e2714106fb8ad40b773b711ebce25b78914
-github.com/syndtr/gocapability e7cb7fa329f456b3855136a2642b197bad7366ba
+github.com/sirupsen/logrus a3f95b5c423586578a4e099b11a46c2479628cac
+github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
 github.com/vishvananda/netlink 1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270
 # systemd integration.
 github.com/coreos/go-systemd v14
 github.com/coreos/pkg v3
 github.com/godbus/dbus v3
-github.com/golang/protobuf f7137ae6b19afbfd61a94b746fda3b3fe0491874
+github.com/golang/protobuf 18c9bb3261723cd5401db4d0c9fbc5c3b6c70fe8
 # Command-line interface.
 github.com/docker/docker 0f5c9d301b9b1cca66b3ea0f9dec3b5317d3686d
 github.com/docker/go-units v0.2.0
 github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
-golang.org/x/sys 9a7256cb28ed514b4e1e5f68959914c4c28a92e0 https://github.com/golang/sys
+golang.org/x/sys 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce https://github.com/golang/sys
+
+# console dependencies
+github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
+github.com/pkg/errors v0.8.0
diff --git a/vendor/github.com/opencontainers/runtime-spec/README.md b/vendor/github.com/opencontainers/runtime-spec/README.md
index 1364f6f..2f7eb60 100644
--- a/vendor/github.com/opencontainers/runtime-spec/README.md
+++ b/vendor/github.com/opencontainers/runtime-spec/README.md
@@ -10,7 +10,6 @@
 
 - [Code of Conduct][code-of-conduct]
 - [Style and Conventions](style.md)
-- [Roadmap](ROADMAP.md)
 - [Implementations](implementations.md)
 - [Releases](RELEASES.md)
 - [project](project.md)
@@ -33,12 +32,7 @@
 
 ### Runtime Developers
 
-Runtime developers can build runtime implementations that run OCI-compliant bundles and container configuration, containing low-level OS and host specific details, on a particular platform.
-
-## Releases
-
-There is a loose [Road Map](./ROADMAP.md).
-During the `0.x` series of OCI releases we make no backwards compatibility guarantees and intend to break the schema during this series.
+Runtime developers can build runtime implementations that run OCI-compliant bundles and container configuration, containing low-level OS and host-specific details, on a particular platform.
 
 ## Contributing
 
@@ -63,7 +57,7 @@
 The contributors and maintainers of all OCI projects have a weekly meeting on Wednesdays at:
 
 * 8:00 AM (USA Pacific), during [odd weeks][iso-week].
-* 5:00 PM (USA Pacific), during [even weeks][iso-week].
+* 2:00 PM (USA Pacific), during [even weeks][iso-week].
 
 There is an [iCalendar][rfc5545] format for the meetings [here](meeting.ics).
 
@@ -145,7 +139,7 @@
 5. Use the imperative mood in the subject line
 6. Wrap the body at 72 characters
 7. Use the body to explain what and why vs. how
-  * If there was important/useful/essential conversation or information, copy or include a reference
+    * If there was important/useful/essential conversation or information, copy or include a reference
 8. When possible, one keyword to scope the change in the subject (i.e. "README: ...", "runtime: ...")
 
 
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
index da90405..f3f37d4 100644
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
@@ -6,26 +6,24 @@
 type Spec struct {
 	// Version of the Open Container Runtime Specification with which the bundle complies.
 	Version string `json:"ociVersion"`
-	// Platform specifies the configuration's target platform.
-	Platform Platform `json:"platform"`
 	// Process configures the container process.
-	Process Process `json:"process"`
+	Process *Process `json:"process,omitempty"`
 	// Root configures the container's root filesystem.
-	Root Root `json:"root"`
+	Root *Root `json:"root,omitempty"`
 	// Hostname configures the container's hostname.
 	Hostname string `json:"hostname,omitempty"`
 	// Mounts configures additional mounts (on top of Root).
 	Mounts []Mount `json:"mounts,omitempty"`
 	// Hooks configures callbacks for container lifecycle events.
-	Hooks *Hooks `json:"hooks,omitempty"`
+	Hooks *Hooks `json:"hooks,omitempty" platform:"linux,solaris"`
 	// Annotations contains arbitrary metadata for the container.
 	Annotations map[string]string `json:"annotations,omitempty"`
 
-	// Linux is platform specific configuration for Linux based containers.
+	// Linux is platform-specific configuration for Linux based containers.
 	Linux *Linux `json:"linux,omitempty" platform:"linux"`
-	// Solaris is platform specific configuration for Solaris containers.
+	// Solaris is platform-specific configuration for Solaris based containers.
 	Solaris *Solaris `json:"solaris,omitempty" platform:"solaris"`
-	// Windows is platform specific configuration for Windows based containers, including Hyper-V containers.
+	// Windows is platform-specific configuration for Windows based containers.
 	Windows *Windows `json:"windows,omitempty" platform:"windows"`
 }
 
@@ -34,7 +32,7 @@
 	// Terminal creates an interactive terminal for the container.
 	Terminal bool `json:"terminal,omitempty"`
 	// ConsoleSize specifies the size of the console.
-	ConsoleSize Box `json:"consoleSize,omitempty"`
+	ConsoleSize *Box `json:"consoleSize,omitempty"`
 	// User specifies user information for the process.
 	User User `json:"user"`
 	// Args specifies the binary and arguments for the application to execute.
@@ -47,11 +45,13 @@
 	// Capabilities are Linux capabilities that are kept for the process.
 	Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"`
 	// Rlimits specifies rlimit options to apply to the process.
-	Rlimits []LinuxRlimit `json:"rlimits,omitempty" platform:"linux"`
+	Rlimits []POSIXRlimit `json:"rlimits,omitempty" platform:"linux,solaris"`
 	// NoNewPrivileges controls whether additional privileges could be gained by processes in the container.
 	NoNewPrivileges bool `json:"noNewPrivileges,omitempty" platform:"linux"`
 	// ApparmorProfile specifies the apparmor profile for the container.
 	ApparmorProfile string `json:"apparmorProfile,omitempty" platform:"linux"`
+	// Specify an oom_score_adj for the container.
+	OOMScoreAdj *int `json:"oomScoreAdj,omitempty" platform:"linux"`
 	// SelinuxLabel specifies the selinux context that the container process is run as.
 	SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
 }
@@ -99,23 +99,13 @@
 	Readonly bool `json:"readonly,omitempty"`
 }
 
-// Platform specifies OS and arch information for the host system that the container
-// is created for.
-type Platform struct {
-	// OS is the operating system.
-	OS string `json:"os"`
-	// Arch is the architecture
-	Arch string `json:"arch"`
-}
-
 // Mount specifies a mount for a container.
 type Mount struct {
-	// Destination is the path where the mount will be placed relative to the container's root.  The path and child directories MUST exist, a runtime MUST NOT create directories automatically to a mount point.
+	// Destination is the absolute path where the mount will be placed in the container.
 	Destination string `json:"destination"`
 	// Type specifies the mount kind.
-	Type string `json:"type,omitempty"`
-	// Source specifies the source path of the mount.  In the case of bind mounts on
-	// Linux based systems this would be the file on the host.
+	Type string `json:"type,omitempty" platform:"linux,solaris"`
+	// Source specifies the source path of the mount.
 	Source string `json:"source,omitempty"`
 	// Options are fstab style mount options.
 	Options []string `json:"options,omitempty"`
@@ -132,7 +122,6 @@
 // Hooks for container setup and teardown
 type Hooks struct {
 	// Prestart is a list of hooks to be run before the container process is executed.
-	// On Linux, they are run after the container namespaces are created.
 	Prestart []Hook `json:"prestart,omitempty"`
 	// Poststart is a list of hooks to be run after the container process is started.
 	Poststart []Hook `json:"poststart,omitempty"`
@@ -140,11 +129,11 @@
 	Poststop []Hook `json:"poststop,omitempty"`
 }
 
-// Linux contains platform specific configuration for Linux based containers.
+// Linux contains platform-specific configuration for Linux based containers.
 type Linux struct {
-	// UIDMapping specifies user mappings for supporting user namespaces on Linux.
+	// UIDMapping specifies user mappings for supporting user namespaces.
 	UIDMappings []LinuxIDMapping `json:"uidMappings,omitempty"`
-	// GIDMapping specifies group mappings for supporting user namespaces on Linux.
+	// GIDMapping specifies group mappings for supporting user namespaces.
 	GIDMappings []LinuxIDMapping `json:"gidMappings,omitempty"`
 	// Sysctl are a set of key value pairs that are set for the container on start
 	Sysctl map[string]string `json:"sysctl,omitempty"`
@@ -176,7 +165,7 @@
 
 // LinuxNamespace is the configuration for a Linux namespace
 type LinuxNamespace struct {
-	// Type is the type of Linux namespace
+	// Type is the type of namespace
 	Type LinuxNamespaceType `json:"type"`
 	// Path is a path to an existing namespace persisted on disk that can be joined
 	// and is of the same type
@@ -213,8 +202,8 @@
 	Size uint32 `json:"size"`
 }
 
-// LinuxRlimit type and restrictions
-type LinuxRlimit struct {
+// POSIXRlimit type and restrictions
+type POSIXRlimit struct {
 	// Type of the rlimit to set
 	Type string `json:"type"`
 	// Hard is the hard limit for the specified type
@@ -247,7 +236,7 @@
 	Minor int64 `json:"minor"`
 }
 
-// LinuxWeightDevice struct holds a `major:minor weight` pair for blkioWeightDevice
+// LinuxWeightDevice struct holds a `major:minor weight` pair for weightDevice
 type LinuxWeightDevice struct {
 	linuxBlockIODevice
 	// Weight is the bandwidth rate for the device.
@@ -266,35 +255,37 @@
 // LinuxBlockIO for Linux cgroup 'blkio' resource management
 type LinuxBlockIO struct {
 	// Specifies per cgroup weight
-	Weight *uint16 `json:"blkioWeight,omitempty"`
+	Weight *uint16 `json:"weight,omitempty"`
 	// Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, CFQ scheduler only
-	LeafWeight *uint16 `json:"blkioLeafWeight,omitempty"`
+	LeafWeight *uint16 `json:"leafWeight,omitempty"`
 	// Weight per cgroup per device, can override BlkioWeight
-	WeightDevice []LinuxWeightDevice `json:"blkioWeightDevice,omitempty"`
+	WeightDevice []LinuxWeightDevice `json:"weightDevice,omitempty"`
 	// IO read rate limit per cgroup per device, bytes per second
-	ThrottleReadBpsDevice []LinuxThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"`
+	ThrottleReadBpsDevice []LinuxThrottleDevice `json:"throttleReadBpsDevice,omitempty"`
 	// IO write rate limit per cgroup per device, bytes per second
-	ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"`
+	ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"throttleWriteBpsDevice,omitempty"`
 	// IO read rate limit per cgroup per device, IO per second
-	ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"`
+	ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"throttleReadIOPSDevice,omitempty"`
 	// IO write rate limit per cgroup per device, IO per second
-	ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"`
+	ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"throttleWriteIOPSDevice,omitempty"`
 }
 
 // LinuxMemory for Linux cgroup 'memory' resource management
 type LinuxMemory struct {
 	// Memory limit (in bytes).
-	Limit *uint64 `json:"limit,omitempty"`
+	Limit *int64 `json:"limit,omitempty"`
 	// Memory reservation or soft_limit (in bytes).
-	Reservation *uint64 `json:"reservation,omitempty"`
+	Reservation *int64 `json:"reservation,omitempty"`
 	// Total memory limit (memory + swap).
-	Swap *uint64 `json:"swap,omitempty"`
+	Swap *int64 `json:"swap,omitempty"`
 	// Kernel memory limit (in bytes).
-	Kernel *uint64 `json:"kernel,omitempty"`
+	Kernel *int64 `json:"kernel,omitempty"`
 	// Kernel memory limit for tcp (in bytes)
-	KernelTCP *uint64 `json:"kernelTCP,omitempty"`
-	// How aggressive the kernel will swap memory pages. Range from 0 to 100.
+	KernelTCP *int64 `json:"kernelTCP,omitempty"`
+	// How aggressive the kernel will swap memory pages.
 	Swappiness *uint64 `json:"swappiness,omitempty"`
+	// DisableOOMKiller disables the OOM killer for out of memory conditions
+	DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
 }
 
 // LinuxCPU for Linux cgroup 'cpu' resource management
@@ -333,10 +324,6 @@
 type LinuxResources struct {
 	// Devices configures the device whitelist.
 	Devices []LinuxDeviceCgroup `json:"devices,omitempty"`
-	// DisableOOMKiller disables the OOM killer for out of memory conditions
-	DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
-	// Specify an oom_score_adj for the container.
-	OOMScoreAdj *int `json:"oomScoreAdj,omitempty"`
 	// Memory restriction configuration
 	Memory *LinuxMemory `json:"memory,omitempty"`
 	// CPU resource restriction configuration
@@ -383,7 +370,7 @@
 	Access string `json:"access,omitempty"`
 }
 
-// Solaris contains platform specific configuration for Solaris application containers.
+// Solaris contains platform-specific configuration for Solaris application containers.
 type Solaris struct {
 	// SMF FMRI which should go "online" before we start the container process.
 	Milestone string `json:"milestone,omitempty"`
@@ -430,8 +417,20 @@
 
 // Windows defines the runtime configuration for Windows based containers, including Hyper-V containers.
 type Windows struct {
+	// LayerFolders contains a list of absolute paths to directories containing image layers.
+	LayerFolders []string `json:"layerFolders"`
 	// Resources contains information for handling resource constraints for the container.
 	Resources *WindowsResources `json:"resources,omitempty"`
+	// CredentialSpec contains a JSON object describing a group Managed Service Account (gMSA) specification.
+	CredentialSpec interface{} `json:"credentialSpec,omitempty"`
+	// Servicing indicates if the container is being started in a mode to apply a Windows Update servicing operation.
+	Servicing bool `json:"servicing,omitempty"`
+	// IgnoreFlushesDuringBoot indicates if the container is being started in a mode where disk writes are not flushed during its boot process.
+	IgnoreFlushesDuringBoot bool `json:"ignoreFlushesDuringBoot,omitempty"`
+	// HyperV contains information for running a container with Hyper-V isolation.
+	HyperV *WindowsHyperV `json:"hyperv,omitempty"`
+	// Network restriction configuration.
+	Network *WindowsNetwork `json:"network,omitempty"`
 }
 
 // WindowsResources has container runtime resource constraints for containers running on Windows.
@@ -442,23 +441,19 @@
 	CPU *WindowsCPUResources `json:"cpu,omitempty"`
 	// Storage restriction configuration.
 	Storage *WindowsStorageResources `json:"storage,omitempty"`
-	// Network restriction configuration.
-	Network *WindowsNetworkResources `json:"network,omitempty"`
 }
 
 // WindowsMemoryResources contains memory resource management settings.
 type WindowsMemoryResources struct {
 	// Memory limit in bytes.
 	Limit *uint64 `json:"limit,omitempty"`
-	// Memory reservation in bytes.
-	Reservation *uint64 `json:"reservation,omitempty"`
 }
 
 // WindowsCPUResources contains CPU resource management settings.
 type WindowsCPUResources struct {
 	// Number of CPUs available to the container.
 	Count *uint64 `json:"count,omitempty"`
-	// CPU shares (relative weight to other containers with cpu shares). Range is from 1 to 10000.
+	// CPU shares (relative weight to other containers with cpu shares).
 	Shares *uint16 `json:"shares,omitempty"`
 	// Specifies the portion of processor cycles that this container can use as a percentage times 100.
 	Maximum *uint16 `json:"maximum,omitempty"`
@@ -474,10 +469,22 @@
 	SandboxSize *uint64 `json:"sandboxSize,omitempty"`
 }
 
-// WindowsNetworkResources contains network resource management settings.
-type WindowsNetworkResources struct {
-	// EgressBandwidth is the maximum egress bandwidth in bytes per second.
-	EgressBandwidth *uint64 `json:"egressBandwidth,omitempty"`
+// WindowsNetwork contains network settings for Windows containers.
+type WindowsNetwork struct {
+	// List of HNS endpoints that the container should connect to.
+	EndpointList []string `json:"endpointList,omitempty"`
+	// Specifies if unqualified DNS name resolution is allowed.
+	AllowUnqualifiedDNSQuery bool `json:"allowUnqualifiedDNSQuery,omitempty"`
+	// Comma separated list of DNS suffixes to use for name resolution.
+	DNSSearchList []string `json:"DNSSearchList,omitempty"`
+	// Name (ID) of the container that we will share with the network stack.
+	NetworkSharedContainerName string `json:"networkSharedContainerName,omitempty"`
+}
+
+// WindowsHyperV contains information for configuring a container to run with Hyper-V isolation.
+type WindowsHyperV struct {
+	// UtilityVMPath is an optional path to the image used for the Utility VM.
+	UtilityVMPath string `json:"utilityVMPath,omitempty"`
 }
 
 // LinuxSeccomp represents syscall restrictions
@@ -543,7 +550,7 @@
 type LinuxSeccompArg struct {
 	Index    uint                 `json:"index"`
 	Value    uint64               `json:"value"`
-	ValueTwo uint64               `json:"valueTwo"`
+	ValueTwo uint64               `json:"valueTwo,omitempty"`
 	Op       LinuxSeccompOperator `json:"op"`
 }
 
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
index b5dd3be..89dce34 100644
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
@@ -9,7 +9,7 @@
 	// Status is the runtime status of the container.
 	Status string `json:"status"`
 	// Pid is the process ID for the container process.
-	Pid int `json:"pid"`
+	Pid int `json:"pid,omitempty"`
 	// Bundle is the path to the container's bundle directory.
 	Bundle string `json:"bundle"`
 	// Annotations are key values associated with the container.
diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go
index dfcf009..926ce66 100644
--- a/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go
+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go
@@ -11,7 +11,7 @@
 	VersionPatch = 0
 
 	// VersionDev indicates development branch. Releases will be empty string.
-	VersionDev = "-rc5-dev"
+	VersionDev = ""
 )
 
 // Version is the specification version that the package types support.
diff --git a/vendor/github.com/Sirupsen/logrus/LICENSE b/vendor/github.com/sirupsen/logrus/LICENSE
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/LICENSE
rename to vendor/github.com/sirupsen/logrus/LICENSE
diff --git a/vendor/github.com/Sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md
similarity index 71%
rename from vendor/github.com/Sirupsen/logrus/README.md
rename to vendor/github.com/sirupsen/logrus/README.md
index 126cd1f..4f5ce57 100644
--- a/vendor/github.com/Sirupsen/logrus/README.md
+++ b/vendor/github.com/sirupsen/logrus/README.md
@@ -1,11 +1,24 @@
-# 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 <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. [Godoc][godoc]. **Please note the Logrus API is not
-yet stable (pre 1.0). Logrus itself is completely stable and has been used in
-many large deployments. The core API is unlikely to change much but please
-version control your Logrus to make sure you aren't fetching latest `master` on
-every build.**
+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):
@@ -46,6 +59,12 @@
 exit status 1
 ```
 
+#### 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:
@@ -54,7 +73,7 @@
 package main
 
 import (
-  log "github.com/Sirupsen/logrus"
+  log "github.com/sirupsen/logrus"
 )
 
 func main() {
@@ -65,7 +84,7 @@
 ```
 
 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"`
+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:
 
@@ -74,15 +93,16 @@
 
 import (
   "os"
-  log "github.com/Sirupsen/logrus"
+  log "github.com/sirupsen/logrus"
 )
 
 func init() {
   // Log as JSON instead of the default ASCII formatter.
   log.SetFormatter(&log.JSONFormatter{})
 
-  // Output to stderr instead of stdout, could also be a file.
-  log.SetOutput(os.Stderr)
+  // 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)
@@ -123,7 +143,8 @@
 package main
 
 import (
-  "github.com/Sirupsen/logrus"
+  "os"
+  "github.com/sirupsen/logrus"
 )
 
 // Create a new instance of the logger. You can have any number of instances.
@@ -132,7 +153,15 @@
 func main() {
   // The API for setting attributes is a little different than the package level
   // exported logger. See Godoc.
-  log.Out = os.Stderr
+  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",
@@ -143,7 +172,7 @@
 
 #### Fields
 
-Logrus encourages careful, structured logging though logging fields instead of
+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:
@@ -165,6 +194,20 @@
 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
@@ -176,9 +219,9 @@
 
 ```go
 import (
-  log "github.com/Sirupsen/logrus"
+  log "github.com/sirupsen/logrus"
   "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake"
-  logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
+  logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
   "log/syslog"
 )
 
@@ -200,40 +243,52 @@
 
 | Hook  | Description |
 | ----- | ----------- |
-| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. |
 | [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
-| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
-| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
-| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
-| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
-| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
-| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
-| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
-| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
-| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) |
-| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) |
-| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
-| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
-| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
-| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
-| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
-| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
-| [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) |
-| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
-| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
-| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
-| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) |
+| [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. |
+| [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) |
 | [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) |
-| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
-| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
+| [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
+| [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic |
+| [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) |
 | [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch|
-| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
-| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)|
-| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
-| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
+| [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/)
+| [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd |
+| [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) |
+| [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) |
+| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
+| [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger |
+| [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb |
+| [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) |
+| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
+| [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka |
+| [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem |
+| [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) |
+| [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) |
 | [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) |
+| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
+| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
+| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
+| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) |
+| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
+| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
+| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
+| [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. |
+| [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) |
 | [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) |
-
+| [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) |
+| [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) |
+| [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar |
+| [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)|
+| [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. |
+| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
+| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
+| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
+| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
+| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
+| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
+| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
+| [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash |
+| [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) |
 
 #### Level logging
 
@@ -282,7 +337,7 @@
 
 ```go
 import (
-  log "github.com/Sirupsen/logrus"
+  log "github.com/sirupsen/logrus"
 )
 
 init() {
@@ -309,11 +364,15 @@
   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`
+    `DisableColors` field to `true`. For Windows, see
+    [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
+  * 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 by parsed by Kubernetes and Google Container Engine.
 * [`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̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
@@ -359,6 +418,18 @@
 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
@@ -370,7 +441,7 @@
 | 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 arround 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) |
+|[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
 
@@ -380,15 +451,24 @@
 * a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
 
 ```go
-logger, hook := NewNullLogger()
-logger.Error("Hello error")
+import(
+  "github.com/sirupsen/logrus"
+  "github.com/sirupsen/logrus/hooks/test"
+  "github.com/stretchr/testify/assert"
+  "testing"
+)
 
-assert.Equal(1, len(hook.Entries))
-assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level)
-assert.Equal("Hello error", hook.LastEntry().Message)
+func TestSomething(t*testing.T){
+  logger, hook := test.NewNullLogger()
+  logger.Error("Helloerror")
 
-hook.Reset()
-assert.Nil(hook.LastEntry())
+  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
@@ -407,7 +487,7 @@
 ...
 ```
 
-#### Thread safty
+#### Thread safety
 
 By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs.
 If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
diff --git a/vendor/github.com/Sirupsen/logrus/alt_exit.go b/vendor/github.com/sirupsen/logrus/alt_exit.go
similarity index 96%
rename from vendor/github.com/Sirupsen/logrus/alt_exit.go
rename to vendor/github.com/sirupsen/logrus/alt_exit.go
index b4c9e84..8af9063 100644
--- a/vendor/github.com/Sirupsen/logrus/alt_exit.go
+++ b/vendor/github.com/sirupsen/logrus/alt_exit.go
@@ -1,7 +1,7 @@
 package logrus
 
 // The following code was sourced and modified from the
-// https://bitbucket.org/tebeka/atexit package governed by the following license:
+// https://github.com/tebeka/atexit package governed by the following license:
 //
 // Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
 //
diff --git a/vendor/github.com/Sirupsen/logrus/doc.go b/vendor/github.com/sirupsen/logrus/doc.go
similarity index 83%
rename from vendor/github.com/Sirupsen/logrus/doc.go
rename to vendor/github.com/sirupsen/logrus/doc.go
index dddd5f8..da67aba 100644
--- a/vendor/github.com/Sirupsen/logrus/doc.go
+++ b/vendor/github.com/sirupsen/logrus/doc.go
@@ -7,7 +7,7 @@
   package main
 
   import (
-    log "github.com/Sirupsen/logrus"
+    log "github.com/sirupsen/logrus"
   )
 
   func main() {
@@ -21,6 +21,6 @@
 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
+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
similarity index 87%
rename from vendor/github.com/Sirupsen/logrus/entry.go
rename to vendor/github.com/sirupsen/logrus/entry.go
index 4edbe7a..5bf582e 100644
--- a/vendor/github.com/Sirupsen/logrus/entry.go
+++ b/vendor/github.com/sirupsen/logrus/entry.go
@@ -35,6 +35,7 @@
 	Time time.Time
 
 	// Level the log entry was logged at: 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
 
 	// Message passed to Debug, Info, Warn, Error, Fatal or Panic
@@ -126,7 +127,7 @@
 }
 
 func (entry *Entry) Debug(args ...interface{}) {
-	if entry.Logger.Level >= DebugLevel {
+	if entry.Logger.level() >= DebugLevel {
 		entry.log(DebugLevel, fmt.Sprint(args...))
 	}
 }
@@ -136,13 +137,13 @@
 }
 
 func (entry *Entry) Info(args ...interface{}) {
-	if entry.Logger.Level >= InfoLevel {
+	if entry.Logger.level() >= InfoLevel {
 		entry.log(InfoLevel, fmt.Sprint(args...))
 	}
 }
 
 func (entry *Entry) Warn(args ...interface{}) {
-	if entry.Logger.Level >= WarnLevel {
+	if entry.Logger.level() >= WarnLevel {
 		entry.log(WarnLevel, fmt.Sprint(args...))
 	}
 }
@@ -152,20 +153,20 @@
 }
 
 func (entry *Entry) Error(args ...interface{}) {
-	if entry.Logger.Level >= ErrorLevel {
+	if entry.Logger.level() >= ErrorLevel {
 		entry.log(ErrorLevel, fmt.Sprint(args...))
 	}
 }
 
 func (entry *Entry) Fatal(args ...interface{}) {
-	if entry.Logger.Level >= FatalLevel {
+	if entry.Logger.level() >= FatalLevel {
 		entry.log(FatalLevel, fmt.Sprint(args...))
 	}
 	Exit(1)
 }
 
 func (entry *Entry) Panic(args ...interface{}) {
-	if entry.Logger.Level >= PanicLevel {
+	if entry.Logger.level() >= PanicLevel {
 		entry.log(PanicLevel, fmt.Sprint(args...))
 	}
 	panic(fmt.Sprint(args...))
@@ -174,13 +175,13 @@
 // Entry Printf family functions
 
 func (entry *Entry) Debugf(format string, args ...interface{}) {
-	if entry.Logger.Level >= DebugLevel {
+	if entry.Logger.level() >= DebugLevel {
 		entry.Debug(fmt.Sprintf(format, args...))
 	}
 }
 
 func (entry *Entry) Infof(format string, args ...interface{}) {
-	if entry.Logger.Level >= InfoLevel {
+	if entry.Logger.level() >= InfoLevel {
 		entry.Info(fmt.Sprintf(format, args...))
 	}
 }
@@ -190,7 +191,7 @@
 }
 
 func (entry *Entry) Warnf(format string, args ...interface{}) {
-	if entry.Logger.Level >= WarnLevel {
+	if entry.Logger.level() >= WarnLevel {
 		entry.Warn(fmt.Sprintf(format, args...))
 	}
 }
@@ -200,20 +201,20 @@
 }
 
 func (entry *Entry) Errorf(format string, args ...interface{}) {
-	if entry.Logger.Level >= ErrorLevel {
+	if entry.Logger.level() >= ErrorLevel {
 		entry.Error(fmt.Sprintf(format, args...))
 	}
 }
 
 func (entry *Entry) Fatalf(format string, args ...interface{}) {
-	if entry.Logger.Level >= FatalLevel {
+	if entry.Logger.level() >= FatalLevel {
 		entry.Fatal(fmt.Sprintf(format, args...))
 	}
 	Exit(1)
 }
 
 func (entry *Entry) Panicf(format string, args ...interface{}) {
-	if entry.Logger.Level >= PanicLevel {
+	if entry.Logger.level() >= PanicLevel {
 		entry.Panic(fmt.Sprintf(format, args...))
 	}
 }
@@ -221,13 +222,13 @@
 // Entry Println family functions
 
 func (entry *Entry) Debugln(args ...interface{}) {
-	if entry.Logger.Level >= DebugLevel {
+	if entry.Logger.level() >= DebugLevel {
 		entry.Debug(entry.sprintlnn(args...))
 	}
 }
 
 func (entry *Entry) Infoln(args ...interface{}) {
-	if entry.Logger.Level >= InfoLevel {
+	if entry.Logger.level() >= InfoLevel {
 		entry.Info(entry.sprintlnn(args...))
 	}
 }
@@ -237,7 +238,7 @@
 }
 
 func (entry *Entry) Warnln(args ...interface{}) {
-	if entry.Logger.Level >= WarnLevel {
+	if entry.Logger.level() >= WarnLevel {
 		entry.Warn(entry.sprintlnn(args...))
 	}
 }
@@ -247,20 +248,20 @@
 }
 
 func (entry *Entry) Errorln(args ...interface{}) {
-	if entry.Logger.Level >= ErrorLevel {
+	if entry.Logger.level() >= ErrorLevel {
 		entry.Error(entry.sprintlnn(args...))
 	}
 }
 
 func (entry *Entry) Fatalln(args ...interface{}) {
-	if entry.Logger.Level >= FatalLevel {
+	if entry.Logger.level() >= FatalLevel {
 		entry.Fatal(entry.sprintlnn(args...))
 	}
 	Exit(1)
 }
 
 func (entry *Entry) Panicln(args ...interface{}) {
-	if entry.Logger.Level >= PanicLevel {
+	if entry.Logger.level() >= PanicLevel {
 		entry.Panic(entry.sprintlnn(args...))
 	}
 }
diff --git a/vendor/github.com/Sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go
similarity index 98%
rename from vendor/github.com/Sirupsen/logrus/exported.go
rename to vendor/github.com/sirupsen/logrus/exported.go
index 9a0120a..013183e 100644
--- a/vendor/github.com/Sirupsen/logrus/exported.go
+++ b/vendor/github.com/sirupsen/logrus/exported.go
@@ -31,14 +31,14 @@
 func SetLevel(level Level) {
 	std.mu.Lock()
 	defer std.mu.Unlock()
-	std.Level = level
+	std.SetLevel(level)
 }
 
 // GetLevel returns the standard logger level.
 func GetLevel() Level {
 	std.mu.Lock()
 	defer std.mu.Unlock()
-	return std.Level
+	return std.level()
 }
 
 // AddHook adds a hook to the standard logger hooks.
diff --git a/vendor/github.com/Sirupsen/logrus/formatter.go b/vendor/github.com/sirupsen/logrus/formatter.go
similarity index 96%
rename from vendor/github.com/Sirupsen/logrus/formatter.go
rename to vendor/github.com/sirupsen/logrus/formatter.go
index b5fbe93..b183ff5 100644
--- a/vendor/github.com/Sirupsen/logrus/formatter.go
+++ b/vendor/github.com/sirupsen/logrus/formatter.go
@@ -2,7 +2,7 @@
 
 import "time"
 
-const DefaultTimestampFormat = time.RFC3339
+const defaultTimestampFormat = time.RFC3339
 
 // The Formatter interface is used to implement a custom Formatter. It takes an
 // `Entry`. It exposes all the fields, including the default ones:
diff --git a/vendor/github.com/Sirupsen/logrus/hooks.go b/vendor/github.com/sirupsen/logrus/hooks.go
similarity index 100%
rename from vendor/github.com/Sirupsen/logrus/hooks.go
rename to vendor/github.com/sirupsen/logrus/hooks.go
diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go
new file mode 100644
index 0000000..fb01c1b
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/json_formatter.go
@@ -0,0 +1,79 @@
+package logrus
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type fieldKey string
+
+// FieldMap allows customization of the key names for default fields.
+type FieldMap map[fieldKey]string
+
+// Default key names for the default fields
+const (
+	FieldKeyMsg   = "msg"
+	FieldKeyLevel = "level"
+	FieldKeyTime  = "time"
+)
+
+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
+
+	// 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",
+	//    },
+	// }
+	FieldMap FieldMap
+}
+
+// Format renders a single log entry
+func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
+	data := make(Fields, len(entry.Data)+3)
+	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
+		}
+	}
+	prefixFieldClashes(data)
+
+	timestampFormat := f.TimestampFormat
+	if timestampFormat == "" {
+		timestampFormat = defaultTimestampFormat
+	}
+
+	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()
+
+	serialized, err := json.Marshal(data)
+	if err != nil {
+		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
+	}
+	return append(serialized, '\n'), nil
+}
diff --git a/vendor/github.com/Sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go
similarity index 87%
rename from vendor/github.com/Sirupsen/logrus/logger.go
rename to vendor/github.com/sirupsen/logrus/logger.go
index b769f3d..2acab05 100644
--- a/vendor/github.com/Sirupsen/logrus/logger.go
+++ b/vendor/github.com/sirupsen/logrus/logger.go
@@ -4,6 +4,7 @@
 	"io"
 	"os"
 	"sync"
+	"sync/atomic"
 )
 
 type Logger struct {
@@ -24,7 +25,7 @@
 	Formatter Formatter
 	// 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. `logrus.Debug` is useful in
+	// logged.
 	Level Level
 	// Used to sync writing to the log. Locking is enabled by Default
 	mu MutexWrap
@@ -112,7 +113,7 @@
 }
 
 func (logger *Logger) Debugf(format string, args ...interface{}) {
-	if logger.Level >= DebugLevel {
+	if logger.level() >= DebugLevel {
 		entry := logger.newEntry()
 		entry.Debugf(format, args...)
 		logger.releaseEntry(entry)
@@ -120,7 +121,7 @@
 }
 
 func (logger *Logger) Infof(format string, args ...interface{}) {
-	if logger.Level >= InfoLevel {
+	if logger.level() >= InfoLevel {
 		entry := logger.newEntry()
 		entry.Infof(format, args...)
 		logger.releaseEntry(entry)
@@ -134,7 +135,7 @@
 }
 
 func (logger *Logger) Warnf(format string, args ...interface{}) {
-	if logger.Level >= WarnLevel {
+	if logger.level() >= WarnLevel {
 		entry := logger.newEntry()
 		entry.Warnf(format, args...)
 		logger.releaseEntry(entry)
@@ -142,7 +143,7 @@
 }
 
 func (logger *Logger) Warningf(format string, args ...interface{}) {
-	if logger.Level >= WarnLevel {
+	if logger.level() >= WarnLevel {
 		entry := logger.newEntry()
 		entry.Warnf(format, args...)
 		logger.releaseEntry(entry)
@@ -150,7 +151,7 @@
 }
 
 func (logger *Logger) Errorf(format string, args ...interface{}) {
-	if logger.Level >= ErrorLevel {
+	if logger.level() >= ErrorLevel {
 		entry := logger.newEntry()
 		entry.Errorf(format, args...)
 		logger.releaseEntry(entry)
@@ -158,7 +159,7 @@
 }
 
 func (logger *Logger) Fatalf(format string, args ...interface{}) {
-	if logger.Level >= FatalLevel {
+	if logger.level() >= FatalLevel {
 		entry := logger.newEntry()
 		entry.Fatalf(format, args...)
 		logger.releaseEntry(entry)
@@ -167,7 +168,7 @@
 }
 
 func (logger *Logger) Panicf(format string, args ...interface{}) {
-	if logger.Level >= PanicLevel {
+	if logger.level() >= PanicLevel {
 		entry := logger.newEntry()
 		entry.Panicf(format, args...)
 		logger.releaseEntry(entry)
@@ -175,7 +176,7 @@
 }
 
 func (logger *Logger) Debug(args ...interface{}) {
-	if logger.Level >= DebugLevel {
+	if logger.level() >= DebugLevel {
 		entry := logger.newEntry()
 		entry.Debug(args...)
 		logger.releaseEntry(entry)
@@ -183,7 +184,7 @@
 }
 
 func (logger *Logger) Info(args ...interface{}) {
-	if logger.Level >= InfoLevel {
+	if logger.level() >= InfoLevel {
 		entry := logger.newEntry()
 		entry.Info(args...)
 		logger.releaseEntry(entry)
@@ -197,7 +198,7 @@
 }
 
 func (logger *Logger) Warn(args ...interface{}) {
-	if logger.Level >= WarnLevel {
+	if logger.level() >= WarnLevel {
 		entry := logger.newEntry()
 		entry.Warn(args...)
 		logger.releaseEntry(entry)
@@ -205,7 +206,7 @@
 }
 
 func (logger *Logger) Warning(args ...interface{}) {
-	if logger.Level >= WarnLevel {
+	if logger.level() >= WarnLevel {
 		entry := logger.newEntry()
 		entry.Warn(args...)
 		logger.releaseEntry(entry)
@@ -213,7 +214,7 @@
 }
 
 func (logger *Logger) Error(args ...interface{}) {
-	if logger.Level >= ErrorLevel {
+	if logger.level() >= ErrorLevel {
 		entry := logger.newEntry()
 		entry.Error(args...)
 		logger.releaseEntry(entry)
@@ -221,7 +222,7 @@
 }
 
 func (logger *Logger) Fatal(args ...interface{}) {
-	if logger.Level >= FatalLevel {
+	if logger.level() >= FatalLevel {
 		entry := logger.newEntry()
 		entry.Fatal(args...)
 		logger.releaseEntry(entry)
@@ -230,7 +231,7 @@
 }
 
 func (logger *Logger) Panic(args ...interface{}) {
-	if logger.Level >= PanicLevel {
+	if logger.level() >= PanicLevel {
 		entry := logger.newEntry()
 		entry.Panic(args...)
 		logger.releaseEntry(entry)
@@ -238,7 +239,7 @@
 }
 
 func (logger *Logger) Debugln(args ...interface{}) {
-	if logger.Level >= DebugLevel {
+	if logger.level() >= DebugLevel {
 		entry := logger.newEntry()
 		entry.Debugln(args...)
 		logger.releaseEntry(entry)
@@ -246,7 +247,7 @@
 }
 
 func (logger *Logger) Infoln(args ...interface{}) {
-	if logger.Level >= InfoLevel {
+	if logger.level() >= InfoLevel {
 		entry := logger.newEntry()
 		entry.Infoln(args...)
 		logger.releaseEntry(entry)
@@ -260,7 +261,7 @@
 }
 
 func (logger *Logger) Warnln(args ...interface{}) {
-	if logger.Level >= WarnLevel {
+	if logger.level() >= WarnLevel {
 		entry := logger.newEntry()
 		entry.Warnln(args...)
 		logger.releaseEntry(entry)
@@ -268,7 +269,7 @@
 }
 
 func (logger *Logger) Warningln(args ...interface{}) {
-	if logger.Level >= WarnLevel {
+	if logger.level() >= WarnLevel {
 		entry := logger.newEntry()
 		entry.Warnln(args...)
 		logger.releaseEntry(entry)
@@ -276,7 +277,7 @@
 }
 
 func (logger *Logger) Errorln(args ...interface{}) {
-	if logger.Level >= ErrorLevel {
+	if logger.level() >= ErrorLevel {
 		entry := logger.newEntry()
 		entry.Errorln(args...)
 		logger.releaseEntry(entry)
@@ -284,7 +285,7 @@
 }
 
 func (logger *Logger) Fatalln(args ...interface{}) {
-	if logger.Level >= FatalLevel {
+	if logger.level() >= FatalLevel {
 		entry := logger.newEntry()
 		entry.Fatalln(args...)
 		logger.releaseEntry(entry)
@@ -293,7 +294,7 @@
 }
 
 func (logger *Logger) Panicln(args ...interface{}) {
-	if logger.Level >= PanicLevel {
+	if logger.level() >= PanicLevel {
 		entry := logger.newEntry()
 		entry.Panicln(args...)
 		logger.releaseEntry(entry)
@@ -306,3 +307,11 @@
 func (logger *Logger) SetNoLock() {
 	logger.mu.Disable()
 }
+
+func (logger *Logger) level() Level {
+	return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
+}
+
+func (logger *Logger) SetLevel(level Level) {
+	atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
+}
diff --git a/vendor/github.com/Sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go
similarity index 99%
rename from vendor/github.com/Sirupsen/logrus/logrus.go
rename to vendor/github.com/sirupsen/logrus/logrus.go
index e596691..dd38999 100644
--- a/vendor/github.com/Sirupsen/logrus/logrus.go
+++ b/vendor/github.com/sirupsen/logrus/logrus.go
@@ -10,7 +10,7 @@
 type Fields map[string]interface{}
 
 // Level type
-type Level uint8
+type Level uint32
 
 // Convert the Level to a string. E.g. PanicLevel becomes "panic".
 func (level Level) String() string {
diff --git a/vendor/github.com/sirupsen/logrus/terminal_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_bsd.go
new file mode 100644
index 0000000..d7b3893
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/terminal_bsd.go
@@ -0,0 +1,10 @@
+// +build darwin freebsd openbsd netbsd dragonfly
+// +build !appengine
+
+package logrus
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TIOCGETA
+
+type Termios unix.Termios
diff --git a/vendor/github.com/Sirupsen/logrus/terminal_linux.go b/vendor/github.com/sirupsen/logrus/terminal_linux.go
similarity index 70%
rename from vendor/github.com/Sirupsen/logrus/terminal_linux.go
rename to vendor/github.com/sirupsen/logrus/terminal_linux.go
index 308160c..88d7298 100644
--- a/vendor/github.com/Sirupsen/logrus/terminal_linux.go
+++ b/vendor/github.com/sirupsen/logrus/terminal_linux.go
@@ -7,8 +7,8 @@
 
 package logrus
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
-const ioctlReadTermios = syscall.TCGETS
+const ioctlReadTermios = unix.TCGETS
 
-type Termios syscall.Termios
+type Termios unix.Termios
diff --git a/vendor/github.com/Sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go
similarity index 66%
rename from vendor/github.com/Sirupsen/logrus/text_formatter.go
rename to vendor/github.com/sirupsen/logrus/text_formatter.go
index 9114b3c..be412aa 100644
--- a/vendor/github.com/Sirupsen/logrus/text_formatter.go
+++ b/vendor/github.com/sirupsen/logrus/text_formatter.go
@@ -3,10 +3,14 @@
 import (
 	"bytes"
 	"fmt"
-	"runtime"
+	"io"
+	"os"
 	"sort"
 	"strings"
+	"sync"
 	"time"
+
+	"golang.org/x/crypto/ssh/terminal"
 )
 
 const (
@@ -14,24 +18,19 @@
 	red     = 31
 	green   = 32
 	yellow  = 33
-	blue    = 34
+	blue    = 36
 	gray    = 37
 )
 
 var (
 	baseTimestamp time.Time
-	isTerminal    bool
 )
 
 func init() {
 	baseTimestamp = time.Now()
-	isTerminal = IsTerminal()
 }
 
-func miniTS() int {
-	return int(time.Since(baseTimestamp) / time.Second)
-}
-
+// TextFormatter formats logs into text
 type TextFormatter struct {
 	// Set to true to bypass checking for a TTY before outputting colors.
 	ForceColors bool
@@ -54,11 +53,35 @@
 	// that log extremely frequently and don't use the JSON formatter this may not
 	// be desired.
 	DisableSorting bool
+
+	// QuoteEmptyFields will wrap empty fields in quotes if true
+	QuoteEmptyFields bool
+
+	// Whether the logger's out is to a terminal
+	isTerminal bool
+
+	sync.Once
 }
 
+func (f *TextFormatter) init(entry *Entry) {
+	if entry.Logger != nil {
+		f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
+	}
+}
+
+func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
+	switch v := w.(type) {
+	case *os.File:
+		return terminal.IsTerminal(int(v.Fd()))
+	default:
+		return false
+	}
+}
+
+// Format renders a single log entry
 func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
 	var b *bytes.Buffer
-	var keys []string = make([]string, 0, len(entry.Data))
+	keys := make([]string, 0, len(entry.Data))
 	for k := range entry.Data {
 		keys = append(keys, k)
 	}
@@ -74,12 +97,13 @@
 
 	prefixFieldClashes(entry.Data)
 
-	isColorTerminal := isTerminal && (runtime.GOOS != "windows")
-	isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors
+	f.Do(func() { f.init(entry) })
+
+	isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors
 
 	timestampFormat := f.TimestampFormat
 	if timestampFormat == "" {
-		timestampFormat = DefaultTimestampFormat
+		timestampFormat = defaultTimestampFormat
 	}
 	if isColored {
 		f.printColored(b, entry, keys, timestampFormat)
@@ -115,8 +139,10 @@
 
 	levelText := strings.ToUpper(entry.Level.String())[0:4]
 
-	if !f.FullTimestamp {
-		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
+	if f.DisableTimestamp {
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message)
+	} else if !f.FullTimestamp {
+		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message)
 	} else {
 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message)
 	}
@@ -127,12 +153,15 @@
 	}
 }
 
-func needsQuoting(text string) bool {
+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 == '@' || ch == '^' || ch == '+') {
 			return true
 		}
 	}
@@ -140,29 +169,23 @@
 }
 
 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)
-	b.WriteByte(' ')
 }
 
 func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
-	switch value := value.(type) {
-	case string:
-		if !needsQuoting(value) {
-			b.WriteString(value)
-		} else {
-			fmt.Fprintf(b, "%q", value)
-		}
-	case error:
-		errmsg := value.Error()
-		if !needsQuoting(errmsg) {
-			b.WriteString(errmsg)
-		} else {
-			fmt.Fprintf(b, "%q", errmsg)
-		}
-	default:
-		fmt.Fprint(b, value)
+	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
new file mode 100644
index 0000000..7bdebed
--- /dev/null
+++ b/vendor/github.com/sirupsen/logrus/writer.go
@@ -0,0 +1,62 @@
+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 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/stevvooe/continuity/README.md b/vendor/github.com/stevvooe/continuity/README.md
deleted file mode 100644
index 50b64c2..0000000
--- a/vendor/github.com/stevvooe/continuity/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# continuity
-
-[![GoDoc](https://godoc.org/github.com/containerd/continuity?status.svg)](https://godoc.org/github.com/containerd/continuity)
-[![Build Status](https://travis-ci.org/containerd/continuity.svg?branch=master)](https://travis-ci.org/containerd/continuity)
-
-A transport-agnostic, filesystem metadata manifest system
-
-This project is a staging area for experiments in providing transport agnostic
-metadata storage.
-
-Please see https://github.com/opencontainers/specs/issues/11 for more details.
-
-## Building Proto Package
-
-If you change the proto file you will need to rebuild the generated Go with `go generate`.
-
-```
-go generate ./proto
-```
diff --git a/vendor/github.com/tonistiigi/fsutil/diff.go b/vendor/github.com/tonistiigi/fsutil/diff.go
index 1530973..6125ef7 100644
--- a/vendor/github.com/tonistiigi/fsutil/diff.go
+++ b/vendor/github.com/tonistiigi/fsutil/diff.go
@@ -1,6 +1,7 @@
 package fsutil
 
 import (
+	"hash"
 	"os"
 
 	"golang.org/x/net/context"
@@ -14,6 +15,8 @@
 
 type HandleChangeFn func(ChangeKind, string, os.FileInfo, error) error
 
+type ContentHasher func(*Stat) (hash.Hash, error)
+
 func GetWalkerFn(root string) walkerFn {
 	return func(ctx context.Context, pathC chan<- *currentPath) error {
 		return Walk(ctx, root, nil, func(path string, f os.FileInfo, err error) error {
@@ -35,3 +38,7 @@
 		})
 	}
 }
+
+func emptyWalker(ctx context.Context, pathC chan<- *currentPath) error {
+	return nil
+}
diff --git a/vendor/github.com/tonistiigi/fsutil/diff_containerd_linux.go b/vendor/github.com/tonistiigi/fsutil/diff_containerd_linux.go
index 3c9f078..4ac7ec5 100644
--- a/vendor/github.com/tonistiigi/fsutil/diff_containerd_linux.go
+++ b/vendor/github.com/tonistiigi/fsutil/diff_containerd_linux.go
@@ -4,8 +4,8 @@
 	"bytes"
 	"syscall"
 
+	"github.com/containerd/continuity/sysx"
 	"github.com/pkg/errors"
-	"github.com/stevvooe/continuity/sysx"
 )
 
 // compareSysStat returns whether the stats are equivalent,
diff --git a/vendor/github.com/tonistiigi/fsutil/diskwriter.go b/vendor/github.com/tonistiigi/fsutil/diskwriter.go
index a54b4a7..a465615 100644
--- a/vendor/github.com/tonistiigi/fsutil/diskwriter.go
+++ b/vendor/github.com/tonistiigi/fsutil/diskwriter.go
@@ -1,11 +1,6 @@
-// +build linux windows
-
 package fsutil
 
 import (
-	"archive/tar"
-	"crypto/sha256"
-	"encoding/hex"
 	"hash"
 	"io"
 	"os"
@@ -14,8 +9,7 @@
 	"sync"
 	"time"
 
-	"github.com/docker/docker/pkg/archive"
-	"github.com/docker/docker/pkg/tarsum"
+	digest "github.com/opencontainers/go-digest"
 	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 	"golang.org/x/sync/errgroup"
@@ -24,11 +18,15 @@
 type WriteToFunc func(context.Context, string, io.WriteCloser) error
 
 type DiskWriterOpt struct {
-	AsyncDataCb WriteToFunc
-	SyncDataCb  WriteToFunc
-	NotifyCb    func(ChangeKind, string, os.FileInfo, error) error
+	AsyncDataCb   WriteToFunc
+	SyncDataCb    WriteToFunc
+	NotifyCb      func(ChangeKind, string, os.FileInfo, error) error
+	ContentHasher ContentHasher
+	Filter        FilterFunc
 }
 
+type FilterFunc func(*Stat) bool
+
 type DiskWriter struct {
 	opt  DiskWriterOpt
 	dest string
@@ -37,6 +35,7 @@
 	ctx    context.Context
 	cancel func()
 	eg     *errgroup.Group
+	filter FilterFunc
 }
 
 func NewDiskWriter(ctx context.Context, dest string, opt DiskWriterOpt) (*DiskWriter, error) {
@@ -102,6 +101,12 @@
 		return errors.Errorf("%s invalid change without stat information", p)
 	}
 
+	if dw.filter != nil {
+		if ok := dw.filter(stat); !ok {
+			return nil
+		}
+	}
+
 	rename := true
 	oldFi, err := os.Lstat(destPath)
 	if err != nil {
@@ -202,7 +207,7 @@
 	var hw *hashedWriter
 	if dw.opt.NotifyCb != nil {
 		var err error
-		if hw, err = newHashWriter(p, fi, w); err != nil {
+		if hw, err = newHashWriter(dw.opt.ContentHasher, fi, w); err != nil {
 			return err
 		}
 		w = hw
@@ -229,13 +234,18 @@
 type hashedWriter struct {
 	os.FileInfo
 	io.Writer
-	h   hash.Hash
-	w   io.WriteCloser
-	sum string
+	h    hash.Hash
+	w    io.WriteCloser
+	dgst digest.Digest
 }
 
-func newHashWriter(p string, fi os.FileInfo, w io.WriteCloser) (*hashedWriter, error) {
-	h, err := NewTarsumHash(p, fi)
+func newHashWriter(ch ContentHasher, fi os.FileInfo, w io.WriteCloser) (*hashedWriter, error) {
+	stat, ok := fi.Sys().(*Stat)
+	if !ok {
+		return nil, errors.Errorf("invalid change without stat information")
+	}
+
+	h, err := ch(stat)
 	if err != nil {
 		return nil, err
 	}
@@ -249,15 +259,15 @@
 }
 
 func (hw *hashedWriter) Close() error {
-	hw.sum = string(hex.EncodeToString(hw.h.Sum(nil)))
+	hw.dgst = digest.NewDigest(digest.SHA256, hw.h)
 	if hw.w != nil {
 		return hw.w.Close()
 	}
 	return nil
 }
 
-func (hw *hashedWriter) Hash() string {
-	return hw.sum
+func (hw *hashedWriter) Digest() digest.Digest {
+	return hw.dgst
 }
 
 type lazyFileWriter struct {
@@ -310,44 +320,3 @@
 	randmu.Unlock()
 	return strconv.Itoa(int(1e9 + r%1e9))[1:]
 }
-
-func NewTarsumHash(p string, fi os.FileInfo) (hash.Hash, error) {
-	stat, ok := fi.Sys().(*Stat)
-	link := ""
-	if ok {
-		link = stat.Linkname
-	}
-	if fi.IsDir() {
-		p += string(os.PathSeparator)
-	}
-	h, err := archive.FileInfoHeader(p, fi, link)
-	if err != nil {
-		return nil, err
-	}
-	h.Name = p
-	if ok {
-		h.Uid = int(stat.Uid)
-		h.Gid = int(stat.Gid)
-		h.Linkname = stat.Linkname
-		if stat.Xattrs != nil {
-			h.Xattrs = make(map[string]string)
-			for k, v := range stat.Xattrs {
-				h.Xattrs[k] = string(v)
-			}
-		}
-	}
-	tsh := &tarsumHash{h: h, Hash: sha256.New()}
-	tsh.Reset()
-	return tsh, nil
-}
-
-// Reset resets the Hash to its initial state.
-func (tsh *tarsumHash) Reset() {
-	tsh.Hash.Reset()
-	tarsum.WriteV1Header(tsh.h, tsh.Hash)
-}
-
-type tarsumHash struct {
-	hash.Hash
-	h *tar.Header
-}
diff --git a/vendor/github.com/tonistiigi/fsutil/diskwriter_darwin.go b/vendor/github.com/tonistiigi/fsutil/diskwriter_darwin.go
new file mode 100644
index 0000000..94d3324
--- /dev/null
+++ b/vendor/github.com/tonistiigi/fsutil/diskwriter_darwin.go
@@ -0,0 +1,7 @@
+// +build darwin
+
+package fsutil
+
+func chtimes(path string, un int64) error {
+	return nil
+}
diff --git a/vendor/github.com/tonistiigi/fsutil/diskwriter_linux.go b/vendor/github.com/tonistiigi/fsutil/diskwriter_linux.go
index c6d97eb..74f08a1 100644
--- a/vendor/github.com/tonistiigi/fsutil/diskwriter_linux.go
+++ b/vendor/github.com/tonistiigi/fsutil/diskwriter_linux.go
@@ -3,36 +3,10 @@
 package fsutil
 
 import (
-	"os"
-	"syscall"
-
 	"github.com/pkg/errors"
-	"github.com/stevvooe/continuity/sysx"
 	"golang.org/x/sys/unix"
 )
 
-func rewriteMetadata(p string, stat *Stat) error {
-	for key, value := range stat.Xattrs {
-		sysx.Setxattr(p, key, value, 0)
-	}
-
-	if err := os.Lchown(p, int(stat.Uid), int(stat.Gid)); err != nil {
-		return errors.Wrapf(err, "failed to lchown %s", p)
-	}
-
-	if os.FileMode(stat.Mode)&os.ModeSymlink == 0 {
-		if err := os.Chmod(p, os.FileMode(stat.Mode)); err != nil {
-			return errors.Wrapf(err, "failed to chown %s", p)
-		}
-	}
-
-	if err := chtimes(p, stat.ModTime); err != nil {
-		return errors.Wrapf(err, "failed to chtimes %s", p)
-	}
-
-	return nil
-}
-
 func chtimes(path string, un int64) error {
 	var utimes [2]unix.Timespec
 	utimes[0] = unix.NsecToTimespec(un)
@@ -44,21 +18,3 @@
 
 	return nil
 }
-
-// handleTarTypeBlockCharFifo is an OS-specific helper function used by
-// createTarFile to handle the following types of header: Block; Char; Fifo
-func handleTarTypeBlockCharFifo(path string, stat *Stat) error {
-	mode := uint32(stat.Mode & 07777)
-	if os.FileMode(stat.Mode)&os.ModeCharDevice != 0 {
-		mode |= syscall.S_IFCHR
-	} else if os.FileMode(stat.Mode)&os.ModeNamedPipe != 0 {
-		mode |= syscall.S_IFIFO
-	} else {
-		mode |= syscall.S_IFBLK
-	}
-
-	if err := syscall.Mknod(path, mode, int(mkdev(stat.Devmajor, stat.Devminor))); err != nil {
-		return err
-	}
-	return nil
-}
diff --git a/vendor/github.com/tonistiigi/fsutil/diskwriter_unix.go b/vendor/github.com/tonistiigi/fsutil/diskwriter_unix.go
new file mode 100644
index 0000000..19dffab
--- /dev/null
+++ b/vendor/github.com/tonistiigi/fsutil/diskwriter_unix.go
@@ -0,0 +1,51 @@
+// +build !windows
+
+package fsutil
+
+import (
+	"os"
+	"syscall"
+
+	"github.com/containerd/continuity/sysx"
+	"github.com/pkg/errors"
+)
+
+func rewriteMetadata(p string, stat *Stat) error {
+	for key, value := range stat.Xattrs {
+		sysx.Setxattr(p, key, value, 0)
+	}
+
+	if err := os.Lchown(p, int(stat.Uid), int(stat.Gid)); err != nil {
+		return errors.Wrapf(err, "failed to lchown %s", p)
+	}
+
+	if os.FileMode(stat.Mode)&os.ModeSymlink == 0 {
+		if err := os.Chmod(p, os.FileMode(stat.Mode)); err != nil {
+			return errors.Wrapf(err, "failed to chown %s", p)
+		}
+	}
+
+	if err := chtimes(p, stat.ModTime); err != nil {
+		return errors.Wrapf(err, "failed to chtimes %s", p)
+	}
+
+	return nil
+}
+
+// handleTarTypeBlockCharFifo is an OS-specific helper function used by
+// createTarFile to handle the following types of header: Block; Char; Fifo
+func handleTarTypeBlockCharFifo(path string, stat *Stat) error {
+	mode := uint32(stat.Mode & 07777)
+	if os.FileMode(stat.Mode)&os.ModeCharDevice != 0 {
+		mode |= syscall.S_IFCHR
+	} else if os.FileMode(stat.Mode)&os.ModeNamedPipe != 0 {
+		mode |= syscall.S_IFIFO
+	} else {
+		mode |= syscall.S_IFBLK
+	}
+
+	if err := syscall.Mknod(path, mode, int(mkdev(stat.Devmajor, stat.Devminor))); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/vendor/github.com/tonistiigi/fsutil/receive.go b/vendor/github.com/tonistiigi/fsutil/receive.go
index e7cee2b..233c28b 100644
--- a/vendor/github.com/tonistiigi/fsutil/receive.go
+++ b/vendor/github.com/tonistiigi/fsutil/receive.go
@@ -1,5 +1,3 @@
-// +build linux windows
-
 package fsutil
 
 import (
@@ -12,29 +10,45 @@
 	"golang.org/x/sync/errgroup"
 )
 
-func Receive(ctx context.Context, conn Stream, dest string, notifyHashed ChangeFunc) error {
+type ReceiveOpt struct {
+	NotifyHashed  ChangeFunc
+	ContentHasher ContentHasher
+	ProgressCb    func(int, bool)
+	Merge         bool
+	Filter        FilterFunc
+}
+
+func Receive(ctx context.Context, conn Stream, dest string, opt ReceiveOpt) error {
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
 
 	r := &receiver{
-		conn:         &syncStream{Stream: conn},
-		dest:         dest,
-		files:        make(map[string]uint32),
-		pipes:        make(map[uint32]io.WriteCloser),
-		notifyHashed: notifyHashed,
+		conn:          &syncStream{Stream: conn},
+		dest:          dest,
+		files:         make(map[string]uint32),
+		pipes:         make(map[uint32]io.WriteCloser),
+		notifyHashed:  opt.NotifyHashed,
+		contentHasher: opt.ContentHasher,
+		progressCb:    opt.ProgressCb,
+		merge:         opt.Merge,
+		filter:        opt.Filter,
 	}
 	return r.run(ctx)
 }
 
 type receiver struct {
-	dest    string
-	conn    Stream
-	files   map[string]uint32
-	pipes   map[uint32]io.WriteCloser
-	mu      sync.RWMutex
-	muPipes sync.RWMutex
+	dest       string
+	conn       Stream
+	files      map[string]uint32
+	pipes      map[uint32]io.WriteCloser
+	mu         sync.RWMutex
+	muPipes    sync.RWMutex
+	progressCb func(int, bool)
+	merge      bool
+	filter     FilterFunc
 
 	notifyHashed   ChangeFunc
+	contentHasher  ContentHasher
 	orderValidator Validator
 	hlValidator    Hardlinks
 }
@@ -81,8 +95,10 @@
 	g, ctx := errgroup.WithContext(ctx)
 
 	dw, err := NewDiskWriter(ctx, r.dest, DiskWriterOpt{
-		AsyncDataCb: r.asyncDataFunc,
-		NotifyCb:    r.notifyHashed,
+		AsyncDataCb:   r.asyncDataFunc,
+		NotifyCb:      r.notifyHashed,
+		ContentHasher: r.contentHasher,
+		Filter:        r.filter,
 	})
 	if err != nil {
 		return err
@@ -91,7 +107,11 @@
 	w := newDynamicWalker()
 
 	g.Go(func() error {
-		err := doubleWalkDiff(ctx, dw.HandleChange, GetWalkerFn(r.dest), w.fill)
+		destWalker := emptyWalker
+		if !r.merge {
+			destWalker = GetWalkerFn(r.dest)
+		}
+		err := doubleWalkDiff(ctx, dw.HandleChange, destWalker, w.fill)
 		if err != nil {
 			return err
 		}
@@ -105,12 +125,23 @@
 	g.Go(func() error {
 		var i uint32 = 0
 
+		size := 0
+		if r.progressCb != nil {
+			defer func() {
+				r.progressCb(size, true)
+			}()
+		}
 		var p Packet
 		for {
 			p = Packet{Data: p.Data[:0]}
 			if err := r.conn.RecvMsg(&p); err != nil {
 				return err
 			}
+			if r.progressCb != nil {
+				size += p.Size()
+				r.progressCb(size, false)
+			}
+
 			switch p.Type {
 			case PACKET_STAT:
 				if p.Stat == nil {
diff --git a/vendor/github.com/tonistiigi/fsutil/receive_unsupported.go b/vendor/github.com/tonistiigi/fsutil/receive_unsupported.go
deleted file mode 100644
index 8e83342..0000000
--- a/vendor/github.com/tonistiigi/fsutil/receive_unsupported.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// +build !linux,!windows
-
-package fsutil
-
-import (
-	"runtime"
-
-	"github.com/pkg/errors"
-	"golang.org/x/net/context"
-)
-
-func Receive(ctx context.Context, conn Stream, dest string, notifyHashed ChangeFunc) error {
-	return errors.Errorf("receive is unsupported in %s", runtime.GOOS)
-}
diff --git a/vendor/github.com/tonistiigi/fsutil/validator.go b/vendor/github.com/tonistiigi/fsutil/validator.go
index e4a5eba..2bd1287 100644
--- a/vendor/github.com/tonistiigi/fsutil/validator.go
+++ b/vendor/github.com/tonistiigi/fsutil/validator.go
@@ -2,7 +2,8 @@
 
 import (
 	"os"
-	"path/filepath"
+	"path"
+	"runtime"
 	"sort"
 	"strings"
 
@@ -26,14 +27,17 @@
 	if v.parentDirs == nil {
 		v.parentDirs = make([]parent, 1, 10)
 	}
-	if p != filepath.Clean(p) {
+	if runtime.GOOS == "windows" {
+		p = strings.Replace(p, "\\", "", -1)
+	}
+	if p != path.Clean(p) {
 		return errors.Errorf("invalid unclean path %s", p)
 	}
-	if filepath.IsAbs(p) {
+	if path.IsAbs(p) {
 		return errors.Errorf("abolute path %s not allowed", p)
 	}
-	dir := filepath.Dir(p)
-	base := filepath.Base(p)
+	dir := path.Dir(p)
+	base := path.Base(p)
 	if dir == "." {
 		dir = ""
 	}
@@ -51,12 +55,12 @@
 	}
 
 	if dir != v.parentDirs[len(v.parentDirs)-1].dir || v.parentDirs[i].last >= base {
-		return errors.Errorf("changes out of order: %q %q", p, filepath.Join(v.parentDirs[i].dir, v.parentDirs[i].last))
+		return errors.Errorf("changes out of order: %q %q", p, path.Join(v.parentDirs[i].dir, v.parentDirs[i].last))
 	}
 	v.parentDirs[i].last = base
 	if kind != ChangeKindDelete && fi.IsDir() {
 		v.parentDirs = append(v.parentDirs, parent{
-			dir:  filepath.Join(dir, base),
+			dir:  path.Join(dir, base),
 			last: "",
 		})
 	}
diff --git a/vendor/github.com/tonistiigi/fsutil/walker.go b/vendor/github.com/tonistiigi/fsutil/walker.go
index bfec609..db1af56 100644
--- a/vendor/github.com/tonistiigi/fsutil/walker.go
+++ b/vendor/github.com/tonistiigi/fsutil/walker.go
@@ -13,8 +13,9 @@
 )
 
 type WalkOpt struct {
-	IncludePaths    []string // todo: remove?
+	IncludePatterns []string
 	ExcludePatterns []string
+	Map             func(*Stat) bool
 }
 
 func Walk(ctx context.Context, p string, opt *WalkOpt, fn filepath.WalkFunc) error {
@@ -57,9 +58,9 @@
 		}
 
 		if opt != nil {
-			if opt.IncludePaths != nil {
+			if opt.IncludePatterns != nil {
 				matched := false
-				for _, p := range opt.IncludePaths {
+				for _, p := range opt.IncludePatterns {
 					if m, _ := filepath.Match(p, path); m {
 						matched = true
 						break
@@ -138,7 +139,12 @@
 		case <-ctx.Done():
 			return ctx.Err()
 		default:
-			if err := fn(path, &StatInfo{stat}, nil); err != nil {
+			if opt != nil && opt.Map != nil {
+				if allowed := opt.Map(stat); !allowed {
+					return nil
+				}
+			}
+			if err := fn(stat.Path, &StatInfo{stat}, nil); err != nil {
 				return err
 			}
 		}
diff --git a/vendor/github.com/tonistiigi/fsutil/walker_unix.go b/vendor/github.com/tonistiigi/fsutil/walker_unix.go
index 6f13c95..7e8ee80 100644
--- a/vendor/github.com/tonistiigi/fsutil/walker_unix.go
+++ b/vendor/github.com/tonistiigi/fsutil/walker_unix.go
@@ -6,8 +6,8 @@
 	"os"
 	"syscall"
 
+	"github.com/containerd/continuity/sysx"
 	"github.com/pkg/errors"
-	"github.com/stevvooe/continuity/sysx"
 )
 
 func loadXattr(origpath string, stat *Stat) error {
diff --git a/vendor/golang.org/x/crypto/README b/vendor/golang.org/x/crypto/README
deleted file mode 100644
index f1e0cbf..0000000
--- a/vendor/golang.org/x/crypto/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This repository holds supplementary Go cryptography libraries.
-
-To submit changes to this repository, see http://golang.org/doc/contribute.html.
diff --git a/vendor/golang.org/x/crypto/README.md b/vendor/golang.org/x/crypto/README.md
new file mode 100644
index 0000000..c9d6fec
--- /dev/null
+++ b/vendor/golang.org/x/crypto/README.md
@@ -0,0 +1,21 @@
+# Go Cryptography
+
+This repository holds supplementary Go cryptography libraries.
+
+## Download/Install
+
+The easiest way to install is to run `go get -u golang.org/x/crypto/...`. You
+can also manually git clone the repository to `$GOPATH/src/golang.org/x/crypto`.
+
+## Report Issues / Send Patches
+
+This repository uses Gerrit for code changes. To learn how to submit changes to
+this repository, see https://golang.org/doc/contribute.html.
+
+The main issue tracker for the crypto repository is located at
+https://github.com/golang/go/issues. Prefix your issue with "x/crypto:" in the
+subject line, so it is easy to find.
+
+Note that contributions to the cryptography package receive additional scrutiny
+due to their sensitive nature. Patches may take longer than normal to receive
+feedback.
diff --git a/vendor/golang.org/x/crypto/curve25519/const_amd64.h b/vendor/golang.org/x/crypto/curve25519/const_amd64.h
new file mode 100644
index 0000000..b3f7416
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/const_amd64.h
@@ -0,0 +1,8 @@
+// Copyright 2012 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.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
+
+#define REDMASK51     0x0007FFFFFFFFFFFF
diff --git a/vendor/golang.org/x/crypto/curve25519/const_amd64.s b/vendor/golang.org/x/crypto/curve25519/const_amd64.s
new file mode 100644
index 0000000..ee7b4bd
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/const_amd64.s
@@ -0,0 +1,20 @@
+// Copyright 2012 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.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+// These constants cannot be encoded in non-MOVQ immediates.
+// We access them directly from memory instead.
+
+DATA ·_121666_213(SB)/8, $996687872
+GLOBL ·_121666_213(SB), 8, $8
+
+DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
+GLOBL ·_2P0(SB), 8, $8
+
+DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
+GLOBL ·_2P1234(SB), 8, $8
diff --git a/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s b/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
new file mode 100644
index 0000000..cd793a5
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
@@ -0,0 +1,65 @@
+// Copyright 2012 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.
+
+// +build amd64,!gccgo,!appengine
+
+// func cswap(inout *[4][5]uint64, v uint64)
+TEXT ·cswap(SB),7,$0
+	MOVQ inout+0(FP),DI
+	MOVQ v+8(FP),SI
+
+	SUBQ $1, SI
+	NOTQ SI
+	MOVQ SI, X15
+	PSHUFD $0x44, X15, X15
+
+	MOVOU 0(DI), X0
+	MOVOU 16(DI), X2
+	MOVOU 32(DI), X4
+	MOVOU 48(DI), X6
+	MOVOU 64(DI), X8
+	MOVOU 80(DI), X1
+	MOVOU 96(DI), X3
+	MOVOU 112(DI), X5
+	MOVOU 128(DI), X7
+	MOVOU 144(DI), X9
+
+	MOVO X1, X10
+	MOVO X3, X11
+	MOVO X5, X12
+	MOVO X7, X13
+	MOVO X9, X14
+
+	PXOR X0, X10
+	PXOR X2, X11
+	PXOR X4, X12
+	PXOR X6, X13
+	PXOR X8, X14
+	PAND X15, X10
+	PAND X15, X11
+	PAND X15, X12
+	PAND X15, X13
+	PAND X15, X14
+	PXOR X10, X0
+	PXOR X10, X1
+	PXOR X11, X2
+	PXOR X11, X3
+	PXOR X12, X4
+	PXOR X12, X5
+	PXOR X13, X6
+	PXOR X13, X7
+	PXOR X14, X8
+	PXOR X14, X9
+
+	MOVOU X0, 0(DI)
+	MOVOU X2, 16(DI)
+	MOVOU X4, 32(DI)
+	MOVOU X6, 48(DI)
+	MOVOU X8, 64(DI)
+	MOVOU X1, 80(DI)
+	MOVOU X3, 96(DI)
+	MOVOU X5, 112(DI)
+	MOVOU X7, 128(DI)
+	MOVOU X9, 144(DI)
+	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go
new file mode 100644
index 0000000..2d14c2a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go
@@ -0,0 +1,834 @@
+// 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.
+
+// We have a implementation in amd64 assembly so this code is only run on
+// non-amd64 platforms. The amd64 assembly does not support gccgo.
+// +build !amd64 gccgo appengine
+
+package curve25519
+
+import (
+	"encoding/binary"
+)
+
+// This code is a port of the public domain, "ref10" implementation of
+// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
+
+// fieldElement represents an element of the field GF(2^255 - 19). An element
+// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
+// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
+// context.
+type fieldElement [10]int32
+
+func feZero(fe *fieldElement) {
+	for i := range fe {
+		fe[i] = 0
+	}
+}
+
+func feOne(fe *fieldElement) {
+	feZero(fe)
+	fe[0] = 1
+}
+
+func feAdd(dst, a, b *fieldElement) {
+	for i := range dst {
+		dst[i] = a[i] + b[i]
+	}
+}
+
+func feSub(dst, a, b *fieldElement) {
+	for i := range dst {
+		dst[i] = a[i] - b[i]
+	}
+}
+
+func feCopy(dst, src *fieldElement) {
+	for i := range dst {
+		dst[i] = src[i]
+	}
+}
+
+// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0.
+//
+// Preconditions: b in {0,1}.
+func feCSwap(f, g *fieldElement, b int32) {
+	b = -b
+	for i := range f {
+		t := b & (f[i] ^ g[i])
+		f[i] ^= t
+		g[i] ^= t
+	}
+}
+
+// load3 reads a 24-bit, little-endian value from in.
+func load3(in []byte) int64 {
+	var r int64
+	r = int64(in[0])
+	r |= int64(in[1]) << 8
+	r |= int64(in[2]) << 16
+	return r
+}
+
+// load4 reads a 32-bit, little-endian value from in.
+func load4(in []byte) int64 {
+	return int64(binary.LittleEndian.Uint32(in))
+}
+
+func feFromBytes(dst *fieldElement, src *[32]byte) {
+	h0 := load4(src[:])
+	h1 := load3(src[4:]) << 6
+	h2 := load3(src[7:]) << 5
+	h3 := load3(src[10:]) << 3
+	h4 := load3(src[13:]) << 2
+	h5 := load4(src[16:])
+	h6 := load3(src[20:]) << 7
+	h7 := load3(src[23:]) << 5
+	h8 := load3(src[26:]) << 4
+	h9 := load3(src[29:]) << 2
+
+	var carry [10]int64
+	carry[9] = (h9 + 1<<24) >> 25
+	h0 += carry[9] * 19
+	h9 -= carry[9] << 25
+	carry[1] = (h1 + 1<<24) >> 25
+	h2 += carry[1]
+	h1 -= carry[1] << 25
+	carry[3] = (h3 + 1<<24) >> 25
+	h4 += carry[3]
+	h3 -= carry[3] << 25
+	carry[5] = (h5 + 1<<24) >> 25
+	h6 += carry[5]
+	h5 -= carry[5] << 25
+	carry[7] = (h7 + 1<<24) >> 25
+	h8 += carry[7]
+	h7 -= carry[7] << 25
+
+	carry[0] = (h0 + 1<<25) >> 26
+	h1 += carry[0]
+	h0 -= carry[0] << 26
+	carry[2] = (h2 + 1<<25) >> 26
+	h3 += carry[2]
+	h2 -= carry[2] << 26
+	carry[4] = (h4 + 1<<25) >> 26
+	h5 += carry[4]
+	h4 -= carry[4] << 26
+	carry[6] = (h6 + 1<<25) >> 26
+	h7 += carry[6]
+	h6 -= carry[6] << 26
+	carry[8] = (h8 + 1<<25) >> 26
+	h9 += carry[8]
+	h8 -= carry[8] << 26
+
+	dst[0] = int32(h0)
+	dst[1] = int32(h1)
+	dst[2] = int32(h2)
+	dst[3] = int32(h3)
+	dst[4] = int32(h4)
+	dst[5] = int32(h5)
+	dst[6] = int32(h6)
+	dst[7] = int32(h7)
+	dst[8] = int32(h8)
+	dst[9] = int32(h9)
+}
+
+// feToBytes marshals h to s.
+// Preconditions:
+//   |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+//
+// Write p=2^255-19; q=floor(h/p).
+// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
+//
+// Proof:
+//   Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
+//   Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
+//
+//   Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
+//   Then 0<y<1.
+//
+//   Write r=h-pq.
+//   Have 0<=r<=p-1=2^255-20.
+//   Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
+//
+//   Write x=r+19(2^-255)r+y.
+//   Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
+//
+//   Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
+//   so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
+func feToBytes(s *[32]byte, h *fieldElement) {
+	var carry [10]int32
+
+	q := (19*h[9] + (1 << 24)) >> 25
+	q = (h[0] + q) >> 26
+	q = (h[1] + q) >> 25
+	q = (h[2] + q) >> 26
+	q = (h[3] + q) >> 25
+	q = (h[4] + q) >> 26
+	q = (h[5] + q) >> 25
+	q = (h[6] + q) >> 26
+	q = (h[7] + q) >> 25
+	q = (h[8] + q) >> 26
+	q = (h[9] + q) >> 25
+
+	// Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
+	h[0] += 19 * q
+	// Goal: Output h-2^255 q, which is between 0 and 2^255-20.
+
+	carry[0] = h[0] >> 26
+	h[1] += carry[0]
+	h[0] -= carry[0] << 26
+	carry[1] = h[1] >> 25
+	h[2] += carry[1]
+	h[1] -= carry[1] << 25
+	carry[2] = h[2] >> 26
+	h[3] += carry[2]
+	h[2] -= carry[2] << 26
+	carry[3] = h[3] >> 25
+	h[4] += carry[3]
+	h[3] -= carry[3] << 25
+	carry[4] = h[4] >> 26
+	h[5] += carry[4]
+	h[4] -= carry[4] << 26
+	carry[5] = h[5] >> 25
+	h[6] += carry[5]
+	h[5] -= carry[5] << 25
+	carry[6] = h[6] >> 26
+	h[7] += carry[6]
+	h[6] -= carry[6] << 26
+	carry[7] = h[7] >> 25
+	h[8] += carry[7]
+	h[7] -= carry[7] << 25
+	carry[8] = h[8] >> 26
+	h[9] += carry[8]
+	h[8] -= carry[8] << 26
+	carry[9] = h[9] >> 25
+	h[9] -= carry[9] << 25
+	// h10 = carry9
+
+	// Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
+	// Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
+	// evidently 2^255 h10-2^255 q = 0.
+	// Goal: Output h[0]+...+2^230 h[9].
+
+	s[0] = byte(h[0] >> 0)
+	s[1] = byte(h[0] >> 8)
+	s[2] = byte(h[0] >> 16)
+	s[3] = byte((h[0] >> 24) | (h[1] << 2))
+	s[4] = byte(h[1] >> 6)
+	s[5] = byte(h[1] >> 14)
+	s[6] = byte((h[1] >> 22) | (h[2] << 3))
+	s[7] = byte(h[2] >> 5)
+	s[8] = byte(h[2] >> 13)
+	s[9] = byte((h[2] >> 21) | (h[3] << 5))
+	s[10] = byte(h[3] >> 3)
+	s[11] = byte(h[3] >> 11)
+	s[12] = byte((h[3] >> 19) | (h[4] << 6))
+	s[13] = byte(h[4] >> 2)
+	s[14] = byte(h[4] >> 10)
+	s[15] = byte(h[4] >> 18)
+	s[16] = byte(h[5] >> 0)
+	s[17] = byte(h[5] >> 8)
+	s[18] = byte(h[5] >> 16)
+	s[19] = byte((h[5] >> 24) | (h[6] << 1))
+	s[20] = byte(h[6] >> 7)
+	s[21] = byte(h[6] >> 15)
+	s[22] = byte((h[6] >> 23) | (h[7] << 3))
+	s[23] = byte(h[7] >> 5)
+	s[24] = byte(h[7] >> 13)
+	s[25] = byte((h[7] >> 21) | (h[8] << 4))
+	s[26] = byte(h[8] >> 4)
+	s[27] = byte(h[8] >> 12)
+	s[28] = byte((h[8] >> 20) | (h[9] << 6))
+	s[29] = byte(h[9] >> 2)
+	s[30] = byte(h[9] >> 10)
+	s[31] = byte(h[9] >> 18)
+}
+
+// feMul calculates h = f * g
+// Can overlap h with f or g.
+//
+// Preconditions:
+//    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+//    |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+//
+// Postconditions:
+//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+//
+// Notes on implementation strategy:
+//
+// Using schoolbook multiplication.
+// Karatsuba would save a little in some cost models.
+//
+// Most multiplications by 2 and 19 are 32-bit precomputations;
+// cheaper than 64-bit postcomputations.
+//
+// There is one remaining multiplication by 19 in the carry chain;
+// one *19 precomputation can be merged into this,
+// but the resulting data flow is considerably less clean.
+//
+// There are 12 carries below.
+// 10 of them are 2-way parallelizable and vectorizable.
+// Can get away with 11 carries, but then data flow is much deeper.
+//
+// With tighter constraints on inputs can squeeze carries into int32.
+func feMul(h, f, g *fieldElement) {
+	f0 := f[0]
+	f1 := f[1]
+	f2 := f[2]
+	f3 := f[3]
+	f4 := f[4]
+	f5 := f[5]
+	f6 := f[6]
+	f7 := f[7]
+	f8 := f[8]
+	f9 := f[9]
+	g0 := g[0]
+	g1 := g[1]
+	g2 := g[2]
+	g3 := g[3]
+	g4 := g[4]
+	g5 := g[5]
+	g6 := g[6]
+	g7 := g[7]
+	g8 := g[8]
+	g9 := g[9]
+	g1_19 := 19 * g1 // 1.4*2^29
+	g2_19 := 19 * g2 // 1.4*2^30; still ok
+	g3_19 := 19 * g3
+	g4_19 := 19 * g4
+	g5_19 := 19 * g5
+	g6_19 := 19 * g6
+	g7_19 := 19 * g7
+	g8_19 := 19 * g8
+	g9_19 := 19 * g9
+	f1_2 := 2 * f1
+	f3_2 := 2 * f3
+	f5_2 := 2 * f5
+	f7_2 := 2 * f7
+	f9_2 := 2 * f9
+	f0g0 := int64(f0) * int64(g0)
+	f0g1 := int64(f0) * int64(g1)
+	f0g2 := int64(f0) * int64(g2)
+	f0g3 := int64(f0) * int64(g3)
+	f0g4 := int64(f0) * int64(g4)
+	f0g5 := int64(f0) * int64(g5)
+	f0g6 := int64(f0) * int64(g6)
+	f0g7 := int64(f0) * int64(g7)
+	f0g8 := int64(f0) * int64(g8)
+	f0g9 := int64(f0) * int64(g9)
+	f1g0 := int64(f1) * int64(g0)
+	f1g1_2 := int64(f1_2) * int64(g1)
+	f1g2 := int64(f1) * int64(g2)
+	f1g3_2 := int64(f1_2) * int64(g3)
+	f1g4 := int64(f1) * int64(g4)
+	f1g5_2 := int64(f1_2) * int64(g5)
+	f1g6 := int64(f1) * int64(g6)
+	f1g7_2 := int64(f1_2) * int64(g7)
+	f1g8 := int64(f1) * int64(g8)
+	f1g9_38 := int64(f1_2) * int64(g9_19)
+	f2g0 := int64(f2) * int64(g0)
+	f2g1 := int64(f2) * int64(g1)
+	f2g2 := int64(f2) * int64(g2)
+	f2g3 := int64(f2) * int64(g3)
+	f2g4 := int64(f2) * int64(g4)
+	f2g5 := int64(f2) * int64(g5)
+	f2g6 := int64(f2) * int64(g6)
+	f2g7 := int64(f2) * int64(g7)
+	f2g8_19 := int64(f2) * int64(g8_19)
+	f2g9_19 := int64(f2) * int64(g9_19)
+	f3g0 := int64(f3) * int64(g0)
+	f3g1_2 := int64(f3_2) * int64(g1)
+	f3g2 := int64(f3) * int64(g2)
+	f3g3_2 := int64(f3_2) * int64(g3)
+	f3g4 := int64(f3) * int64(g4)
+	f3g5_2 := int64(f3_2) * int64(g5)
+	f3g6 := int64(f3) * int64(g6)
+	f3g7_38 := int64(f3_2) * int64(g7_19)
+	f3g8_19 := int64(f3) * int64(g8_19)
+	f3g9_38 := int64(f3_2) * int64(g9_19)
+	f4g0 := int64(f4) * int64(g0)
+	f4g1 := int64(f4) * int64(g1)
+	f4g2 := int64(f4) * int64(g2)
+	f4g3 := int64(f4) * int64(g3)
+	f4g4 := int64(f4) * int64(g4)
+	f4g5 := int64(f4) * int64(g5)
+	f4g6_19 := int64(f4) * int64(g6_19)
+	f4g7_19 := int64(f4) * int64(g7_19)
+	f4g8_19 := int64(f4) * int64(g8_19)
+	f4g9_19 := int64(f4) * int64(g9_19)
+	f5g0 := int64(f5) * int64(g0)
+	f5g1_2 := int64(f5_2) * int64(g1)
+	f5g2 := int64(f5) * int64(g2)
+	f5g3_2 := int64(f5_2) * int64(g3)
+	f5g4 := int64(f5) * int64(g4)
+	f5g5_38 := int64(f5_2) * int64(g5_19)
+	f5g6_19 := int64(f5) * int64(g6_19)
+	f5g7_38 := int64(f5_2) * int64(g7_19)
+	f5g8_19 := int64(f5) * int64(g8_19)
+	f5g9_38 := int64(f5_2) * int64(g9_19)
+	f6g0 := int64(f6) * int64(g0)
+	f6g1 := int64(f6) * int64(g1)
+	f6g2 := int64(f6) * int64(g2)
+	f6g3 := int64(f6) * int64(g3)
+	f6g4_19 := int64(f6) * int64(g4_19)
+	f6g5_19 := int64(f6) * int64(g5_19)
+	f6g6_19 := int64(f6) * int64(g6_19)
+	f6g7_19 := int64(f6) * int64(g7_19)
+	f6g8_19 := int64(f6) * int64(g8_19)
+	f6g9_19 := int64(f6) * int64(g9_19)
+	f7g0 := int64(f7) * int64(g0)
+	f7g1_2 := int64(f7_2) * int64(g1)
+	f7g2 := int64(f7) * int64(g2)
+	f7g3_38 := int64(f7_2) * int64(g3_19)
+	f7g4_19 := int64(f7) * int64(g4_19)
+	f7g5_38 := int64(f7_2) * int64(g5_19)
+	f7g6_19 := int64(f7) * int64(g6_19)
+	f7g7_38 := int64(f7_2) * int64(g7_19)
+	f7g8_19 := int64(f7) * int64(g8_19)
+	f7g9_38 := int64(f7_2) * int64(g9_19)
+	f8g0 := int64(f8) * int64(g0)
+	f8g1 := int64(f8) * int64(g1)
+	f8g2_19 := int64(f8) * int64(g2_19)
+	f8g3_19 := int64(f8) * int64(g3_19)
+	f8g4_19 := int64(f8) * int64(g4_19)
+	f8g5_19 := int64(f8) * int64(g5_19)
+	f8g6_19 := int64(f8) * int64(g6_19)
+	f8g7_19 := int64(f8) * int64(g7_19)
+	f8g8_19 := int64(f8) * int64(g8_19)
+	f8g9_19 := int64(f8) * int64(g9_19)
+	f9g0 := int64(f9) * int64(g0)
+	f9g1_38 := int64(f9_2) * int64(g1_19)
+	f9g2_19 := int64(f9) * int64(g2_19)
+	f9g3_38 := int64(f9_2) * int64(g3_19)
+	f9g4_19 := int64(f9) * int64(g4_19)
+	f9g5_38 := int64(f9_2) * int64(g5_19)
+	f9g6_19 := int64(f9) * int64(g6_19)
+	f9g7_38 := int64(f9_2) * int64(g7_19)
+	f9g8_19 := int64(f9) * int64(g8_19)
+	f9g9_38 := int64(f9_2) * int64(g9_19)
+	h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38
+	h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19
+	h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38
+	h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19
+	h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38
+	h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19
+	h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38
+	h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19
+	h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38
+	h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0
+	var carry [10]int64
+
+	// |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
+	//   i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
+	// |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
+	//   i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
+
+	carry[0] = (h0 + (1 << 25)) >> 26
+	h1 += carry[0]
+	h0 -= carry[0] << 26
+	carry[4] = (h4 + (1 << 25)) >> 26
+	h5 += carry[4]
+	h4 -= carry[4] << 26
+	// |h0| <= 2^25
+	// |h4| <= 2^25
+	// |h1| <= 1.51*2^58
+	// |h5| <= 1.51*2^58
+
+	carry[1] = (h1 + (1 << 24)) >> 25
+	h2 += carry[1]
+	h1 -= carry[1] << 25
+	carry[5] = (h5 + (1 << 24)) >> 25
+	h6 += carry[5]
+	h5 -= carry[5] << 25
+	// |h1| <= 2^24; from now on fits into int32
+	// |h5| <= 2^24; from now on fits into int32
+	// |h2| <= 1.21*2^59
+	// |h6| <= 1.21*2^59
+
+	carry[2] = (h2 + (1 << 25)) >> 26
+	h3 += carry[2]
+	h2 -= carry[2] << 26
+	carry[6] = (h6 + (1 << 25)) >> 26
+	h7 += carry[6]
+	h6 -= carry[6] << 26
+	// |h2| <= 2^25; from now on fits into int32 unchanged
+	// |h6| <= 2^25; from now on fits into int32 unchanged
+	// |h3| <= 1.51*2^58
+	// |h7| <= 1.51*2^58
+
+	carry[3] = (h3 + (1 << 24)) >> 25
+	h4 += carry[3]
+	h3 -= carry[3] << 25
+	carry[7] = (h7 + (1 << 24)) >> 25
+	h8 += carry[7]
+	h7 -= carry[7] << 25
+	// |h3| <= 2^24; from now on fits into int32 unchanged
+	// |h7| <= 2^24; from now on fits into int32 unchanged
+	// |h4| <= 1.52*2^33
+	// |h8| <= 1.52*2^33
+
+	carry[4] = (h4 + (1 << 25)) >> 26
+	h5 += carry[4]
+	h4 -= carry[4] << 26
+	carry[8] = (h8 + (1 << 25)) >> 26
+	h9 += carry[8]
+	h8 -= carry[8] << 26
+	// |h4| <= 2^25; from now on fits into int32 unchanged
+	// |h8| <= 2^25; from now on fits into int32 unchanged
+	// |h5| <= 1.01*2^24
+	// |h9| <= 1.51*2^58
+
+	carry[9] = (h9 + (1 << 24)) >> 25
+	h0 += carry[9] * 19
+	h9 -= carry[9] << 25
+	// |h9| <= 2^24; from now on fits into int32 unchanged
+	// |h0| <= 1.8*2^37
+
+	carry[0] = (h0 + (1 << 25)) >> 26
+	h1 += carry[0]
+	h0 -= carry[0] << 26
+	// |h0| <= 2^25; from now on fits into int32 unchanged
+	// |h1| <= 1.01*2^24
+
+	h[0] = int32(h0)
+	h[1] = int32(h1)
+	h[2] = int32(h2)
+	h[3] = int32(h3)
+	h[4] = int32(h4)
+	h[5] = int32(h5)
+	h[6] = int32(h6)
+	h[7] = int32(h7)
+	h[8] = int32(h8)
+	h[9] = int32(h9)
+}
+
+// feSquare calculates h = f*f. Can overlap h with f.
+//
+// Preconditions:
+//    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+//
+// Postconditions:
+//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+func feSquare(h, f *fieldElement) {
+	f0 := f[0]
+	f1 := f[1]
+	f2 := f[2]
+	f3 := f[3]
+	f4 := f[4]
+	f5 := f[5]
+	f6 := f[6]
+	f7 := f[7]
+	f8 := f[8]
+	f9 := f[9]
+	f0_2 := 2 * f0
+	f1_2 := 2 * f1
+	f2_2 := 2 * f2
+	f3_2 := 2 * f3
+	f4_2 := 2 * f4
+	f5_2 := 2 * f5
+	f6_2 := 2 * f6
+	f7_2 := 2 * f7
+	f5_38 := 38 * f5 // 1.31*2^30
+	f6_19 := 19 * f6 // 1.31*2^30
+	f7_38 := 38 * f7 // 1.31*2^30
+	f8_19 := 19 * f8 // 1.31*2^30
+	f9_38 := 38 * f9 // 1.31*2^30
+	f0f0 := int64(f0) * int64(f0)
+	f0f1_2 := int64(f0_2) * int64(f1)
+	f0f2_2 := int64(f0_2) * int64(f2)
+	f0f3_2 := int64(f0_2) * int64(f3)
+	f0f4_2 := int64(f0_2) * int64(f4)
+	f0f5_2 := int64(f0_2) * int64(f5)
+	f0f6_2 := int64(f0_2) * int64(f6)
+	f0f7_2 := int64(f0_2) * int64(f7)
+	f0f8_2 := int64(f0_2) * int64(f8)
+	f0f9_2 := int64(f0_2) * int64(f9)
+	f1f1_2 := int64(f1_2) * int64(f1)
+	f1f2_2 := int64(f1_2) * int64(f2)
+	f1f3_4 := int64(f1_2) * int64(f3_2)
+	f1f4_2 := int64(f1_2) * int64(f4)
+	f1f5_4 := int64(f1_2) * int64(f5_2)
+	f1f6_2 := int64(f1_2) * int64(f6)
+	f1f7_4 := int64(f1_2) * int64(f7_2)
+	f1f8_2 := int64(f1_2) * int64(f8)
+	f1f9_76 := int64(f1_2) * int64(f9_38)
+	f2f2 := int64(f2) * int64(f2)
+	f2f3_2 := int64(f2_2) * int64(f3)
+	f2f4_2 := int64(f2_2) * int64(f4)
+	f2f5_2 := int64(f2_2) * int64(f5)
+	f2f6_2 := int64(f2_2) * int64(f6)
+	f2f7_2 := int64(f2_2) * int64(f7)
+	f2f8_38 := int64(f2_2) * int64(f8_19)
+	f2f9_38 := int64(f2) * int64(f9_38)
+	f3f3_2 := int64(f3_2) * int64(f3)
+	f3f4_2 := int64(f3_2) * int64(f4)
+	f3f5_4 := int64(f3_2) * int64(f5_2)
+	f3f6_2 := int64(f3_2) * int64(f6)
+	f3f7_76 := int64(f3_2) * int64(f7_38)
+	f3f8_38 := int64(f3_2) * int64(f8_19)
+	f3f9_76 := int64(f3_2) * int64(f9_38)
+	f4f4 := int64(f4) * int64(f4)
+	f4f5_2 := int64(f4_2) * int64(f5)
+	f4f6_38 := int64(f4_2) * int64(f6_19)
+	f4f7_38 := int64(f4) * int64(f7_38)
+	f4f8_38 := int64(f4_2) * int64(f8_19)
+	f4f9_38 := int64(f4) * int64(f9_38)
+	f5f5_38 := int64(f5) * int64(f5_38)
+	f5f6_38 := int64(f5_2) * int64(f6_19)
+	f5f7_76 := int64(f5_2) * int64(f7_38)
+	f5f8_38 := int64(f5_2) * int64(f8_19)
+	f5f9_76 := int64(f5_2) * int64(f9_38)
+	f6f6_19 := int64(f6) * int64(f6_19)
+	f6f7_38 := int64(f6) * int64(f7_38)
+	f6f8_38 := int64(f6_2) * int64(f8_19)
+	f6f9_38 := int64(f6) * int64(f9_38)
+	f7f7_38 := int64(f7) * int64(f7_38)
+	f7f8_38 := int64(f7_2) * int64(f8_19)
+	f7f9_76 := int64(f7_2) * int64(f9_38)
+	f8f8_19 := int64(f8) * int64(f8_19)
+	f8f9_38 := int64(f8) * int64(f9_38)
+	f9f9_38 := int64(f9) * int64(f9_38)
+	h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38
+	h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38
+	h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19
+	h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38
+	h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38
+	h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38
+	h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19
+	h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38
+	h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38
+	h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2
+	var carry [10]int64
+
+	carry[0] = (h0 + (1 << 25)) >> 26
+	h1 += carry[0]
+	h0 -= carry[0] << 26
+	carry[4] = (h4 + (1 << 25)) >> 26
+	h5 += carry[4]
+	h4 -= carry[4] << 26
+
+	carry[1] = (h1 + (1 << 24)) >> 25
+	h2 += carry[1]
+	h1 -= carry[1] << 25
+	carry[5] = (h5 + (1 << 24)) >> 25
+	h6 += carry[5]
+	h5 -= carry[5] << 25
+
+	carry[2] = (h2 + (1 << 25)) >> 26
+	h3 += carry[2]
+	h2 -= carry[2] << 26
+	carry[6] = (h6 + (1 << 25)) >> 26
+	h7 += carry[6]
+	h6 -= carry[6] << 26
+
+	carry[3] = (h3 + (1 << 24)) >> 25
+	h4 += carry[3]
+	h3 -= carry[3] << 25
+	carry[7] = (h7 + (1 << 24)) >> 25
+	h8 += carry[7]
+	h7 -= carry[7] << 25
+
+	carry[4] = (h4 + (1 << 25)) >> 26
+	h5 += carry[4]
+	h4 -= carry[4] << 26
+	carry[8] = (h8 + (1 << 25)) >> 26
+	h9 += carry[8]
+	h8 -= carry[8] << 26
+
+	carry[9] = (h9 + (1 << 24)) >> 25
+	h0 += carry[9] * 19
+	h9 -= carry[9] << 25
+
+	carry[0] = (h0 + (1 << 25)) >> 26
+	h1 += carry[0]
+	h0 -= carry[0] << 26
+
+	h[0] = int32(h0)
+	h[1] = int32(h1)
+	h[2] = int32(h2)
+	h[3] = int32(h3)
+	h[4] = int32(h4)
+	h[5] = int32(h5)
+	h[6] = int32(h6)
+	h[7] = int32(h7)
+	h[8] = int32(h8)
+	h[9] = int32(h9)
+}
+
+// feMul121666 calculates h = f * 121666. Can overlap h with f.
+//
+// Preconditions:
+//    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+//
+// Postconditions:
+//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+func feMul121666(h, f *fieldElement) {
+	h0 := int64(f[0]) * 121666
+	h1 := int64(f[1]) * 121666
+	h2 := int64(f[2]) * 121666
+	h3 := int64(f[3]) * 121666
+	h4 := int64(f[4]) * 121666
+	h5 := int64(f[5]) * 121666
+	h6 := int64(f[6]) * 121666
+	h7 := int64(f[7]) * 121666
+	h8 := int64(f[8]) * 121666
+	h9 := int64(f[9]) * 121666
+	var carry [10]int64
+
+	carry[9] = (h9 + (1 << 24)) >> 25
+	h0 += carry[9] * 19
+	h9 -= carry[9] << 25
+	carry[1] = (h1 + (1 << 24)) >> 25
+	h2 += carry[1]
+	h1 -= carry[1] << 25
+	carry[3] = (h3 + (1 << 24)) >> 25
+	h4 += carry[3]
+	h3 -= carry[3] << 25
+	carry[5] = (h5 + (1 << 24)) >> 25
+	h6 += carry[5]
+	h5 -= carry[5] << 25
+	carry[7] = (h7 + (1 << 24)) >> 25
+	h8 += carry[7]
+	h7 -= carry[7] << 25
+
+	carry[0] = (h0 + (1 << 25)) >> 26
+	h1 += carry[0]
+	h0 -= carry[0] << 26
+	carry[2] = (h2 + (1 << 25)) >> 26
+	h3 += carry[2]
+	h2 -= carry[2] << 26
+	carry[4] = (h4 + (1 << 25)) >> 26
+	h5 += carry[4]
+	h4 -= carry[4] << 26
+	carry[6] = (h6 + (1 << 25)) >> 26
+	h7 += carry[6]
+	h6 -= carry[6] << 26
+	carry[8] = (h8 + (1 << 25)) >> 26
+	h9 += carry[8]
+	h8 -= carry[8] << 26
+
+	h[0] = int32(h0)
+	h[1] = int32(h1)
+	h[2] = int32(h2)
+	h[3] = int32(h3)
+	h[4] = int32(h4)
+	h[5] = int32(h5)
+	h[6] = int32(h6)
+	h[7] = int32(h7)
+	h[8] = int32(h8)
+	h[9] = int32(h9)
+}
+
+// feInvert sets out = z^-1.
+func feInvert(out, z *fieldElement) {
+	var t0, t1, t2, t3 fieldElement
+	var i int
+
+	feSquare(&t0, z)
+	for i = 1; i < 1; i++ {
+		feSquare(&t0, &t0)
+	}
+	feSquare(&t1, &t0)
+	for i = 1; i < 2; i++ {
+		feSquare(&t1, &t1)
+	}
+	feMul(&t1, z, &t1)
+	feMul(&t0, &t0, &t1)
+	feSquare(&t2, &t0)
+	for i = 1; i < 1; i++ {
+		feSquare(&t2, &t2)
+	}
+	feMul(&t1, &t1, &t2)
+	feSquare(&t2, &t1)
+	for i = 1; i < 5; i++ {
+		feSquare(&t2, &t2)
+	}
+	feMul(&t1, &t2, &t1)
+	feSquare(&t2, &t1)
+	for i = 1; i < 10; i++ {
+		feSquare(&t2, &t2)
+	}
+	feMul(&t2, &t2, &t1)
+	feSquare(&t3, &t2)
+	for i = 1; i < 20; i++ {
+		feSquare(&t3, &t3)
+	}
+	feMul(&t2, &t3, &t2)
+	feSquare(&t2, &t2)
+	for i = 1; i < 10; i++ {
+		feSquare(&t2, &t2)
+	}
+	feMul(&t1, &t2, &t1)
+	feSquare(&t2, &t1)
+	for i = 1; i < 50; i++ {
+		feSquare(&t2, &t2)
+	}
+	feMul(&t2, &t2, &t1)
+	feSquare(&t3, &t2)
+	for i = 1; i < 100; i++ {
+		feSquare(&t3, &t3)
+	}
+	feMul(&t2, &t3, &t2)
+	feSquare(&t2, &t2)
+	for i = 1; i < 50; i++ {
+		feSquare(&t2, &t2)
+	}
+	feMul(&t1, &t2, &t1)
+	feSquare(&t1, &t1)
+	for i = 1; i < 5; i++ {
+		feSquare(&t1, &t1)
+	}
+	feMul(out, &t1, &t0)
+}
+
+func scalarMult(out, in, base *[32]byte) {
+	var e [32]byte
+
+	copy(e[:], in[:])
+	e[0] &= 248
+	e[31] &= 127
+	e[31] |= 64
+
+	var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement
+	feFromBytes(&x1, base)
+	feOne(&x2)
+	feCopy(&x3, &x1)
+	feOne(&z3)
+
+	swap := int32(0)
+	for pos := 254; pos >= 0; pos-- {
+		b := e[pos/8] >> uint(pos&7)
+		b &= 1
+		swap ^= int32(b)
+		feCSwap(&x2, &x3, swap)
+		feCSwap(&z2, &z3, swap)
+		swap = int32(b)
+
+		feSub(&tmp0, &x3, &z3)
+		feSub(&tmp1, &x2, &z2)
+		feAdd(&x2, &x2, &z2)
+		feAdd(&z2, &x3, &z3)
+		feMul(&z3, &tmp0, &x2)
+		feMul(&z2, &z2, &tmp1)
+		feSquare(&tmp0, &tmp1)
+		feSquare(&tmp1, &x2)
+		feAdd(&x3, &z3, &z2)
+		feSub(&z2, &z3, &z2)
+		feMul(&x2, &tmp1, &tmp0)
+		feSub(&tmp1, &tmp1, &tmp0)
+		feSquare(&z2, &z2)
+		feMul121666(&z3, &tmp1)
+		feSquare(&x3, &x3)
+		feAdd(&tmp0, &tmp0, &z3)
+		feMul(&z3, &x1, &z2)
+		feMul(&z2, &tmp1, &tmp0)
+	}
+
+	feCSwap(&x2, &x3, swap)
+	feCSwap(&z2, &z3, swap)
+
+	feInvert(&z2, &z2)
+	feMul(&x2, &x2, &z2)
+	feToBytes(out, &x2)
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/doc.go b/vendor/golang.org/x/crypto/curve25519/doc.go
new file mode 100644
index 0000000..da9b10d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/doc.go
@@ -0,0 +1,23 @@
+// Copyright 2012 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 curve25519 provides an implementation of scalar multiplication on
+// the elliptic curve known as curve25519. See https://cr.yp.to/ecdh.html
+package curve25519 // import "golang.org/x/crypto/curve25519"
+
+// basePoint is the x coordinate of the generator of the curve.
+var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+// ScalarMult sets dst to the product in*base where dst and base are the x
+// coordinates of group points and all values are in little-endian form.
+func ScalarMult(dst, in, base *[32]byte) {
+	scalarMult(dst, in, base)
+}
+
+// ScalarBaseMult sets dst to the product in*base where dst and base are the x
+// coordinates of group points, base is the standard generator and all values
+// are in little-endian form.
+func ScalarBaseMult(dst, in *[32]byte) {
+	ScalarMult(dst, in, &basePoint)
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s b/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
new file mode 100644
index 0000000..3908161
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/freeze_amd64.s
@@ -0,0 +1,73 @@
+// Copyright 2012 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.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+#include "const_amd64.h"
+
+// func freeze(inout *[5]uint64)
+TEXT ·freeze(SB),7,$0-8
+	MOVQ inout+0(FP), DI
+
+	MOVQ 0(DI),SI
+	MOVQ 8(DI),DX
+	MOVQ 16(DI),CX
+	MOVQ 24(DI),R8
+	MOVQ 32(DI),R9
+	MOVQ $REDMASK51,AX
+	MOVQ AX,R10
+	SUBQ $18,R10
+	MOVQ $3,R11
+REDUCELOOP:
+	MOVQ SI,R12
+	SHRQ $51,R12
+	ANDQ AX,SI
+	ADDQ R12,DX
+	MOVQ DX,R12
+	SHRQ $51,R12
+	ANDQ AX,DX
+	ADDQ R12,CX
+	MOVQ CX,R12
+	SHRQ $51,R12
+	ANDQ AX,CX
+	ADDQ R12,R8
+	MOVQ R8,R12
+	SHRQ $51,R12
+	ANDQ AX,R8
+	ADDQ R12,R9
+	MOVQ R9,R12
+	SHRQ $51,R12
+	ANDQ AX,R9
+	IMUL3Q $19,R12,R12
+	ADDQ R12,SI
+	SUBQ $1,R11
+	JA REDUCELOOP
+	MOVQ $1,R12
+	CMPQ R10,SI
+	CMOVQLT R11,R12
+	CMPQ AX,DX
+	CMOVQNE R11,R12
+	CMPQ AX,CX
+	CMOVQNE R11,R12
+	CMPQ AX,R8
+	CMOVQNE R11,R12
+	CMPQ AX,R9
+	CMOVQNE R11,R12
+	NEGQ R12
+	ANDQ R12,AX
+	ANDQ R12,R10
+	SUBQ R10,SI
+	SUBQ AX,DX
+	SUBQ AX,CX
+	SUBQ AX,R8
+	SUBQ AX,R9
+	MOVQ SI,0(DI)
+	MOVQ DX,8(DI)
+	MOVQ CX,16(DI)
+	MOVQ R8,24(DI)
+	MOVQ R9,32(DI)
+	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s b/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
new file mode 100644
index 0000000..9e9040b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s
@@ -0,0 +1,1377 @@
+// Copyright 2012 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.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+#include "const_amd64.h"
+
+// func ladderstep(inout *[5][5]uint64)
+TEXT ·ladderstep(SB),0,$296-8
+	MOVQ inout+0(FP),DI
+
+	MOVQ 40(DI),SI
+	MOVQ 48(DI),DX
+	MOVQ 56(DI),CX
+	MOVQ 64(DI),R8
+	MOVQ 72(DI),R9
+	MOVQ SI,AX
+	MOVQ DX,R10
+	MOVQ CX,R11
+	MOVQ R8,R12
+	MOVQ R9,R13
+	ADDQ ·_2P0(SB),AX
+	ADDQ ·_2P1234(SB),R10
+	ADDQ ·_2P1234(SB),R11
+	ADDQ ·_2P1234(SB),R12
+	ADDQ ·_2P1234(SB),R13
+	ADDQ 80(DI),SI
+	ADDQ 88(DI),DX
+	ADDQ 96(DI),CX
+	ADDQ 104(DI),R8
+	ADDQ 112(DI),R9
+	SUBQ 80(DI),AX
+	SUBQ 88(DI),R10
+	SUBQ 96(DI),R11
+	SUBQ 104(DI),R12
+	SUBQ 112(DI),R13
+	MOVQ SI,0(SP)
+	MOVQ DX,8(SP)
+	MOVQ CX,16(SP)
+	MOVQ R8,24(SP)
+	MOVQ R9,32(SP)
+	MOVQ AX,40(SP)
+	MOVQ R10,48(SP)
+	MOVQ R11,56(SP)
+	MOVQ R12,64(SP)
+	MOVQ R13,72(SP)
+	MOVQ 40(SP),AX
+	MULQ 40(SP)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 40(SP),AX
+	SHLQ $1,AX
+	MULQ 48(SP)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 40(SP),AX
+	SHLQ $1,AX
+	MULQ 56(SP)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 40(SP),AX
+	SHLQ $1,AX
+	MULQ 64(SP)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 40(SP),AX
+	SHLQ $1,AX
+	MULQ 72(SP)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 48(SP),AX
+	MULQ 48(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 48(SP),AX
+	SHLQ $1,AX
+	MULQ 56(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 48(SP),AX
+	SHLQ $1,AX
+	MULQ 64(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 48(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 72(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 56(SP),AX
+	MULQ 56(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 56(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 64(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 56(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 72(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 64(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 64(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 64(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 72(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 72(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 72(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	ANDQ DX,SI
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ADDQ R10,CX
+	ANDQ DX,R8
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ADDQ R12,CX
+	ANDQ DX,R9
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ADDQ R14,CX
+	ANDQ DX,AX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,80(SP)
+	MOVQ R8,88(SP)
+	MOVQ R9,96(SP)
+	MOVQ AX,104(SP)
+	MOVQ R10,112(SP)
+	MOVQ 0(SP),AX
+	MULQ 0(SP)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 0(SP),AX
+	SHLQ $1,AX
+	MULQ 8(SP)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 0(SP),AX
+	SHLQ $1,AX
+	MULQ 16(SP)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 0(SP),AX
+	SHLQ $1,AX
+	MULQ 24(SP)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 0(SP),AX
+	SHLQ $1,AX
+	MULQ 32(SP)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 8(SP),AX
+	MULQ 8(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 8(SP),AX
+	SHLQ $1,AX
+	MULQ 16(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 8(SP),AX
+	SHLQ $1,AX
+	MULQ 24(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 8(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 32(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 16(SP),AX
+	MULQ 16(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 16(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 24(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 16(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 32(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 24(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 24(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 24(SP),DX
+	IMUL3Q $38,DX,AX
+	MULQ 32(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 32(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	ANDQ DX,SI
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ADDQ R10,CX
+	ANDQ DX,R8
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ADDQ R12,CX
+	ANDQ DX,R9
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ADDQ R14,CX
+	ANDQ DX,AX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,120(SP)
+	MOVQ R8,128(SP)
+	MOVQ R9,136(SP)
+	MOVQ AX,144(SP)
+	MOVQ R10,152(SP)
+	MOVQ SI,SI
+	MOVQ R8,DX
+	MOVQ R9,CX
+	MOVQ AX,R8
+	MOVQ R10,R9
+	ADDQ ·_2P0(SB),SI
+	ADDQ ·_2P1234(SB),DX
+	ADDQ ·_2P1234(SB),CX
+	ADDQ ·_2P1234(SB),R8
+	ADDQ ·_2P1234(SB),R9
+	SUBQ 80(SP),SI
+	SUBQ 88(SP),DX
+	SUBQ 96(SP),CX
+	SUBQ 104(SP),R8
+	SUBQ 112(SP),R9
+	MOVQ SI,160(SP)
+	MOVQ DX,168(SP)
+	MOVQ CX,176(SP)
+	MOVQ R8,184(SP)
+	MOVQ R9,192(SP)
+	MOVQ 120(DI),SI
+	MOVQ 128(DI),DX
+	MOVQ 136(DI),CX
+	MOVQ 144(DI),R8
+	MOVQ 152(DI),R9
+	MOVQ SI,AX
+	MOVQ DX,R10
+	MOVQ CX,R11
+	MOVQ R8,R12
+	MOVQ R9,R13
+	ADDQ ·_2P0(SB),AX
+	ADDQ ·_2P1234(SB),R10
+	ADDQ ·_2P1234(SB),R11
+	ADDQ ·_2P1234(SB),R12
+	ADDQ ·_2P1234(SB),R13
+	ADDQ 160(DI),SI
+	ADDQ 168(DI),DX
+	ADDQ 176(DI),CX
+	ADDQ 184(DI),R8
+	ADDQ 192(DI),R9
+	SUBQ 160(DI),AX
+	SUBQ 168(DI),R10
+	SUBQ 176(DI),R11
+	SUBQ 184(DI),R12
+	SUBQ 192(DI),R13
+	MOVQ SI,200(SP)
+	MOVQ DX,208(SP)
+	MOVQ CX,216(SP)
+	MOVQ R8,224(SP)
+	MOVQ R9,232(SP)
+	MOVQ AX,240(SP)
+	MOVQ R10,248(SP)
+	MOVQ R11,256(SP)
+	MOVQ R12,264(SP)
+	MOVQ R13,272(SP)
+	MOVQ 224(SP),SI
+	IMUL3Q $19,SI,AX
+	MOVQ AX,280(SP)
+	MULQ 56(SP)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 232(SP),DX
+	IMUL3Q $19,DX,AX
+	MOVQ AX,288(SP)
+	MULQ 48(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 200(SP),AX
+	MULQ 40(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 200(SP),AX
+	MULQ 48(SP)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 200(SP),AX
+	MULQ 56(SP)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 200(SP),AX
+	MULQ 64(SP)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 200(SP),AX
+	MULQ 72(SP)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 208(SP),AX
+	MULQ 40(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 208(SP),AX
+	MULQ 48(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 208(SP),AX
+	MULQ 56(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 208(SP),AX
+	MULQ 64(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 208(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 72(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 216(SP),AX
+	MULQ 40(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 216(SP),AX
+	MULQ 48(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 216(SP),AX
+	MULQ 56(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 216(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 64(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 216(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 72(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 224(SP),AX
+	MULQ 40(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 224(SP),AX
+	MULQ 48(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 280(SP),AX
+	MULQ 64(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 280(SP),AX
+	MULQ 72(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 232(SP),AX
+	MULQ 40(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 288(SP),AX
+	MULQ 56(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 288(SP),AX
+	MULQ 64(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 288(SP),AX
+	MULQ 72(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ANDQ DX,SI
+	ADDQ R10,CX
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ANDQ DX,R8
+	ADDQ R12,CX
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ANDQ DX,R9
+	ADDQ R14,CX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	ANDQ DX,AX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,40(SP)
+	MOVQ R8,48(SP)
+	MOVQ R9,56(SP)
+	MOVQ AX,64(SP)
+	MOVQ R10,72(SP)
+	MOVQ 264(SP),SI
+	IMUL3Q $19,SI,AX
+	MOVQ AX,200(SP)
+	MULQ 16(SP)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 272(SP),DX
+	IMUL3Q $19,DX,AX
+	MOVQ AX,208(SP)
+	MULQ 8(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 240(SP),AX
+	MULQ 0(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 240(SP),AX
+	MULQ 8(SP)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 240(SP),AX
+	MULQ 16(SP)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 240(SP),AX
+	MULQ 24(SP)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 240(SP),AX
+	MULQ 32(SP)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 248(SP),AX
+	MULQ 0(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 248(SP),AX
+	MULQ 8(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 248(SP),AX
+	MULQ 16(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 248(SP),AX
+	MULQ 24(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 248(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 256(SP),AX
+	MULQ 0(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 256(SP),AX
+	MULQ 8(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 256(SP),AX
+	MULQ 16(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 256(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 24(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 256(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 264(SP),AX
+	MULQ 0(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 264(SP),AX
+	MULQ 8(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 200(SP),AX
+	MULQ 24(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 200(SP),AX
+	MULQ 32(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 272(SP),AX
+	MULQ 0(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 208(SP),AX
+	MULQ 16(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 208(SP),AX
+	MULQ 24(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 208(SP),AX
+	MULQ 32(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ANDQ DX,SI
+	ADDQ R10,CX
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ANDQ DX,R8
+	ADDQ R12,CX
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ANDQ DX,R9
+	ADDQ R14,CX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	ANDQ DX,AX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,DX
+	MOVQ R8,CX
+	MOVQ R9,R11
+	MOVQ AX,R12
+	MOVQ R10,R13
+	ADDQ ·_2P0(SB),DX
+	ADDQ ·_2P1234(SB),CX
+	ADDQ ·_2P1234(SB),R11
+	ADDQ ·_2P1234(SB),R12
+	ADDQ ·_2P1234(SB),R13
+	ADDQ 40(SP),SI
+	ADDQ 48(SP),R8
+	ADDQ 56(SP),R9
+	ADDQ 64(SP),AX
+	ADDQ 72(SP),R10
+	SUBQ 40(SP),DX
+	SUBQ 48(SP),CX
+	SUBQ 56(SP),R11
+	SUBQ 64(SP),R12
+	SUBQ 72(SP),R13
+	MOVQ SI,120(DI)
+	MOVQ R8,128(DI)
+	MOVQ R9,136(DI)
+	MOVQ AX,144(DI)
+	MOVQ R10,152(DI)
+	MOVQ DX,160(DI)
+	MOVQ CX,168(DI)
+	MOVQ R11,176(DI)
+	MOVQ R12,184(DI)
+	MOVQ R13,192(DI)
+	MOVQ 120(DI),AX
+	MULQ 120(DI)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 120(DI),AX
+	SHLQ $1,AX
+	MULQ 128(DI)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 120(DI),AX
+	SHLQ $1,AX
+	MULQ 136(DI)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 120(DI),AX
+	SHLQ $1,AX
+	MULQ 144(DI)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 120(DI),AX
+	SHLQ $1,AX
+	MULQ 152(DI)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 128(DI),AX
+	MULQ 128(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 128(DI),AX
+	SHLQ $1,AX
+	MULQ 136(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 128(DI),AX
+	SHLQ $1,AX
+	MULQ 144(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 128(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 152(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 136(DI),AX
+	MULQ 136(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 136(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 144(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 136(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 152(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 144(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 144(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 144(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 152(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 152(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 152(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	ANDQ DX,SI
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ADDQ R10,CX
+	ANDQ DX,R8
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ADDQ R12,CX
+	ANDQ DX,R9
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ADDQ R14,CX
+	ANDQ DX,AX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,120(DI)
+	MOVQ R8,128(DI)
+	MOVQ R9,136(DI)
+	MOVQ AX,144(DI)
+	MOVQ R10,152(DI)
+	MOVQ 160(DI),AX
+	MULQ 160(DI)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 160(DI),AX
+	SHLQ $1,AX
+	MULQ 168(DI)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 160(DI),AX
+	SHLQ $1,AX
+	MULQ 176(DI)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 160(DI),AX
+	SHLQ $1,AX
+	MULQ 184(DI)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 160(DI),AX
+	SHLQ $1,AX
+	MULQ 192(DI)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 168(DI),AX
+	MULQ 168(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 168(DI),AX
+	SHLQ $1,AX
+	MULQ 176(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 168(DI),AX
+	SHLQ $1,AX
+	MULQ 184(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 168(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 192(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 176(DI),AX
+	MULQ 176(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 176(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 184(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 176(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 192(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 184(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 184(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 184(DI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 192(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 192(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 192(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	ANDQ DX,SI
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ADDQ R10,CX
+	ANDQ DX,R8
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ADDQ R12,CX
+	ANDQ DX,R9
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ADDQ R14,CX
+	ANDQ DX,AX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,160(DI)
+	MOVQ R8,168(DI)
+	MOVQ R9,176(DI)
+	MOVQ AX,184(DI)
+	MOVQ R10,192(DI)
+	MOVQ 184(DI),SI
+	IMUL3Q $19,SI,AX
+	MOVQ AX,0(SP)
+	MULQ 16(DI)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 192(DI),DX
+	IMUL3Q $19,DX,AX
+	MOVQ AX,8(SP)
+	MULQ 8(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 160(DI),AX
+	MULQ 0(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 160(DI),AX
+	MULQ 8(DI)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 160(DI),AX
+	MULQ 16(DI)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 160(DI),AX
+	MULQ 24(DI)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 160(DI),AX
+	MULQ 32(DI)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 168(DI),AX
+	MULQ 0(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 168(DI),AX
+	MULQ 8(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 168(DI),AX
+	MULQ 16(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 168(DI),AX
+	MULQ 24(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 168(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 176(DI),AX
+	MULQ 0(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 176(DI),AX
+	MULQ 8(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 176(DI),AX
+	MULQ 16(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 176(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 24(DI)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 176(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 184(DI),AX
+	MULQ 0(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 184(DI),AX
+	MULQ 8(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 0(SP),AX
+	MULQ 24(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 0(SP),AX
+	MULQ 32(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 192(DI),AX
+	MULQ 0(DI)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 8(SP),AX
+	MULQ 16(DI)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 8(SP),AX
+	MULQ 24(DI)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 8(SP),AX
+	MULQ 32(DI)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ANDQ DX,SI
+	ADDQ R10,CX
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ANDQ DX,R8
+	ADDQ R12,CX
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ANDQ DX,R9
+	ADDQ R14,CX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	ANDQ DX,AX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,160(DI)
+	MOVQ R8,168(DI)
+	MOVQ R9,176(DI)
+	MOVQ AX,184(DI)
+	MOVQ R10,192(DI)
+	MOVQ 144(SP),SI
+	IMUL3Q $19,SI,AX
+	MOVQ AX,0(SP)
+	MULQ 96(SP)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 152(SP),DX
+	IMUL3Q $19,DX,AX
+	MOVQ AX,8(SP)
+	MULQ 88(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 120(SP),AX
+	MULQ 80(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 120(SP),AX
+	MULQ 88(SP)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 120(SP),AX
+	MULQ 96(SP)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 120(SP),AX
+	MULQ 104(SP)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 120(SP),AX
+	MULQ 112(SP)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 128(SP),AX
+	MULQ 80(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 128(SP),AX
+	MULQ 88(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 128(SP),AX
+	MULQ 96(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 128(SP),AX
+	MULQ 104(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 128(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 112(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 136(SP),AX
+	MULQ 80(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 136(SP),AX
+	MULQ 88(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 136(SP),AX
+	MULQ 96(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 136(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 104(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 136(SP),DX
+	IMUL3Q $19,DX,AX
+	MULQ 112(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 144(SP),AX
+	MULQ 80(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 144(SP),AX
+	MULQ 88(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 0(SP),AX
+	MULQ 104(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 0(SP),AX
+	MULQ 112(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 152(SP),AX
+	MULQ 80(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 8(SP),AX
+	MULQ 96(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 8(SP),AX
+	MULQ 104(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 8(SP),AX
+	MULQ 112(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ANDQ DX,SI
+	ADDQ R10,CX
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ANDQ DX,R8
+	ADDQ R12,CX
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ANDQ DX,R9
+	ADDQ R14,CX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	ANDQ DX,AX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,40(DI)
+	MOVQ R8,48(DI)
+	MOVQ R9,56(DI)
+	MOVQ AX,64(DI)
+	MOVQ R10,72(DI)
+	MOVQ 160(SP),AX
+	MULQ ·_121666_213(SB)
+	SHRQ $13,AX
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 168(SP),AX
+	MULQ ·_121666_213(SB)
+	SHRQ $13,AX
+	ADDQ AX,CX
+	MOVQ DX,R8
+	MOVQ 176(SP),AX
+	MULQ ·_121666_213(SB)
+	SHRQ $13,AX
+	ADDQ AX,R8
+	MOVQ DX,R9
+	MOVQ 184(SP),AX
+	MULQ ·_121666_213(SB)
+	SHRQ $13,AX
+	ADDQ AX,R9
+	MOVQ DX,R10
+	MOVQ 192(SP),AX
+	MULQ ·_121666_213(SB)
+	SHRQ $13,AX
+	ADDQ AX,R10
+	IMUL3Q $19,DX,DX
+	ADDQ DX,SI
+	ADDQ 80(SP),SI
+	ADDQ 88(SP),CX
+	ADDQ 96(SP),R8
+	ADDQ 104(SP),R9
+	ADDQ 112(SP),R10
+	MOVQ SI,80(DI)
+	MOVQ CX,88(DI)
+	MOVQ R8,96(DI)
+	MOVQ R9,104(DI)
+	MOVQ R10,112(DI)
+	MOVQ 104(DI),SI
+	IMUL3Q $19,SI,AX
+	MOVQ AX,0(SP)
+	MULQ 176(SP)
+	MOVQ AX,SI
+	MOVQ DX,CX
+	MOVQ 112(DI),DX
+	IMUL3Q $19,DX,AX
+	MOVQ AX,8(SP)
+	MULQ 168(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 80(DI),AX
+	MULQ 160(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 80(DI),AX
+	MULQ 168(SP)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 80(DI),AX
+	MULQ 176(SP)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 80(DI),AX
+	MULQ 184(SP)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 80(DI),AX
+	MULQ 192(SP)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 88(DI),AX
+	MULQ 160(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 88(DI),AX
+	MULQ 168(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 88(DI),AX
+	MULQ 176(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 88(DI),AX
+	MULQ 184(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 88(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 192(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 96(DI),AX
+	MULQ 160(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 96(DI),AX
+	MULQ 168(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 96(DI),AX
+	MULQ 176(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 96(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 184(SP)
+	ADDQ AX,SI
+	ADCQ DX,CX
+	MOVQ 96(DI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 192(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 104(DI),AX
+	MULQ 160(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 104(DI),AX
+	MULQ 168(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 0(SP),AX
+	MULQ 184(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 0(SP),AX
+	MULQ 192(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 112(DI),AX
+	MULQ 160(SP)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 8(SP),AX
+	MULQ 176(SP)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 8(SP),AX
+	MULQ 184(SP)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 8(SP),AX
+	MULQ 192(SP)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ $REDMASK51,DX
+	SHLQ $13,CX:SI
+	ANDQ DX,SI
+	SHLQ $13,R9:R8
+	ANDQ DX,R8
+	ADDQ CX,R8
+	SHLQ $13,R11:R10
+	ANDQ DX,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ DX,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ DX,R14
+	ADDQ R13,R14
+	IMUL3Q $19,R15,CX
+	ADDQ CX,SI
+	MOVQ SI,CX
+	SHRQ $51,CX
+	ADDQ R8,CX
+	MOVQ CX,R8
+	SHRQ $51,CX
+	ANDQ DX,SI
+	ADDQ R10,CX
+	MOVQ CX,R9
+	SHRQ $51,CX
+	ANDQ DX,R8
+	ADDQ R12,CX
+	MOVQ CX,AX
+	SHRQ $51,CX
+	ANDQ DX,R9
+	ADDQ R14,CX
+	MOVQ CX,R10
+	SHRQ $51,CX
+	ANDQ DX,AX
+	IMUL3Q $19,CX,CX
+	ADDQ CX,SI
+	ANDQ DX,R10
+	MOVQ SI,80(DI)
+	MOVQ R8,88(DI)
+	MOVQ R9,96(DI)
+	MOVQ AX,104(DI)
+	MOVQ R10,112(DI)
+	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go b/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
new file mode 100644
index 0000000..5822bd5
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go
@@ -0,0 +1,240 @@
+// Copyright 2012 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.
+
+// +build amd64,!gccgo,!appengine
+
+package curve25519
+
+// These functions are implemented in the .s files. The names of the functions
+// in the rest of the file are also taken from the SUPERCOP sources to help
+// people following along.
+
+//go:noescape
+
+func cswap(inout *[5]uint64, v uint64)
+
+//go:noescape
+
+func ladderstep(inout *[5][5]uint64)
+
+//go:noescape
+
+func freeze(inout *[5]uint64)
+
+//go:noescape
+
+func mul(dest, a, b *[5]uint64)
+
+//go:noescape
+
+func square(out, in *[5]uint64)
+
+// mladder uses a Montgomery ladder to calculate (xr/zr) *= s.
+func mladder(xr, zr *[5]uint64, s *[32]byte) {
+	var work [5][5]uint64
+
+	work[0] = *xr
+	setint(&work[1], 1)
+	setint(&work[2], 0)
+	work[3] = *xr
+	setint(&work[4], 1)
+
+	j := uint(6)
+	var prevbit byte
+
+	for i := 31; i >= 0; i-- {
+		for j < 8 {
+			bit := ((*s)[i] >> j) & 1
+			swap := bit ^ prevbit
+			prevbit = bit
+			cswap(&work[1], uint64(swap))
+			ladderstep(&work)
+			j--
+		}
+		j = 7
+	}
+
+	*xr = work[1]
+	*zr = work[2]
+}
+
+func scalarMult(out, in, base *[32]byte) {
+	var e [32]byte
+	copy(e[:], (*in)[:])
+	e[0] &= 248
+	e[31] &= 127
+	e[31] |= 64
+
+	var t, z [5]uint64
+	unpack(&t, base)
+	mladder(&t, &z, &e)
+	invert(&z, &z)
+	mul(&t, &t, &z)
+	pack(out, &t)
+}
+
+func setint(r *[5]uint64, v uint64) {
+	r[0] = v
+	r[1] = 0
+	r[2] = 0
+	r[3] = 0
+	r[4] = 0
+}
+
+// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian
+// order.
+func unpack(r *[5]uint64, x *[32]byte) {
+	r[0] = uint64(x[0]) |
+		uint64(x[1])<<8 |
+		uint64(x[2])<<16 |
+		uint64(x[3])<<24 |
+		uint64(x[4])<<32 |
+		uint64(x[5])<<40 |
+		uint64(x[6]&7)<<48
+
+	r[1] = uint64(x[6])>>3 |
+		uint64(x[7])<<5 |
+		uint64(x[8])<<13 |
+		uint64(x[9])<<21 |
+		uint64(x[10])<<29 |
+		uint64(x[11])<<37 |
+		uint64(x[12]&63)<<45
+
+	r[2] = uint64(x[12])>>6 |
+		uint64(x[13])<<2 |
+		uint64(x[14])<<10 |
+		uint64(x[15])<<18 |
+		uint64(x[16])<<26 |
+		uint64(x[17])<<34 |
+		uint64(x[18])<<42 |
+		uint64(x[19]&1)<<50
+
+	r[3] = uint64(x[19])>>1 |
+		uint64(x[20])<<7 |
+		uint64(x[21])<<15 |
+		uint64(x[22])<<23 |
+		uint64(x[23])<<31 |
+		uint64(x[24])<<39 |
+		uint64(x[25]&15)<<47
+
+	r[4] = uint64(x[25])>>4 |
+		uint64(x[26])<<4 |
+		uint64(x[27])<<12 |
+		uint64(x[28])<<20 |
+		uint64(x[29])<<28 |
+		uint64(x[30])<<36 |
+		uint64(x[31]&127)<<44
+}
+
+// pack sets out = x where out is the usual, little-endian form of the 5,
+// 51-bit limbs in x.
+func pack(out *[32]byte, x *[5]uint64) {
+	t := *x
+	freeze(&t)
+
+	out[0] = byte(t[0])
+	out[1] = byte(t[0] >> 8)
+	out[2] = byte(t[0] >> 16)
+	out[3] = byte(t[0] >> 24)
+	out[4] = byte(t[0] >> 32)
+	out[5] = byte(t[0] >> 40)
+	out[6] = byte(t[0] >> 48)
+
+	out[6] ^= byte(t[1]<<3) & 0xf8
+	out[7] = byte(t[1] >> 5)
+	out[8] = byte(t[1] >> 13)
+	out[9] = byte(t[1] >> 21)
+	out[10] = byte(t[1] >> 29)
+	out[11] = byte(t[1] >> 37)
+	out[12] = byte(t[1] >> 45)
+
+	out[12] ^= byte(t[2]<<6) & 0xc0
+	out[13] = byte(t[2] >> 2)
+	out[14] = byte(t[2] >> 10)
+	out[15] = byte(t[2] >> 18)
+	out[16] = byte(t[2] >> 26)
+	out[17] = byte(t[2] >> 34)
+	out[18] = byte(t[2] >> 42)
+	out[19] = byte(t[2] >> 50)
+
+	out[19] ^= byte(t[3]<<1) & 0xfe
+	out[20] = byte(t[3] >> 7)
+	out[21] = byte(t[3] >> 15)
+	out[22] = byte(t[3] >> 23)
+	out[23] = byte(t[3] >> 31)
+	out[24] = byte(t[3] >> 39)
+	out[25] = byte(t[3] >> 47)
+
+	out[25] ^= byte(t[4]<<4) & 0xf0
+	out[26] = byte(t[4] >> 4)
+	out[27] = byte(t[4] >> 12)
+	out[28] = byte(t[4] >> 20)
+	out[29] = byte(t[4] >> 28)
+	out[30] = byte(t[4] >> 36)
+	out[31] = byte(t[4] >> 44)
+}
+
+// invert calculates r = x^-1 mod p using Fermat's little theorem.
+func invert(r *[5]uint64, x *[5]uint64) {
+	var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64
+
+	square(&z2, x)        /* 2 */
+	square(&t, &z2)       /* 4 */
+	square(&t, &t)        /* 8 */
+	mul(&z9, &t, x)       /* 9 */
+	mul(&z11, &z9, &z2)   /* 11 */
+	square(&t, &z11)      /* 22 */
+	mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */
+
+	square(&t, &z2_5_0)      /* 2^6 - 2^1 */
+	for i := 1; i < 5; i++ { /* 2^20 - 2^10 */
+		square(&t, &t)
+	}
+	mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */
+
+	square(&t, &z2_10_0)      /* 2^11 - 2^1 */
+	for i := 1; i < 10; i++ { /* 2^20 - 2^10 */
+		square(&t, &t)
+	}
+	mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */
+
+	square(&t, &z2_20_0)      /* 2^21 - 2^1 */
+	for i := 1; i < 20; i++ { /* 2^40 - 2^20 */
+		square(&t, &t)
+	}
+	mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */
+
+	square(&t, &t)            /* 2^41 - 2^1 */
+	for i := 1; i < 10; i++ { /* 2^50 - 2^10 */
+		square(&t, &t)
+	}
+	mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */
+
+	square(&t, &z2_50_0)      /* 2^51 - 2^1 */
+	for i := 1; i < 50; i++ { /* 2^100 - 2^50 */
+		square(&t, &t)
+	}
+	mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */
+
+	square(&t, &z2_100_0)      /* 2^101 - 2^1 */
+	for i := 1; i < 100; i++ { /* 2^200 - 2^100 */
+		square(&t, &t)
+	}
+	mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */
+
+	square(&t, &t)            /* 2^201 - 2^1 */
+	for i := 1; i < 50; i++ { /* 2^250 - 2^50 */
+		square(&t, &t)
+	}
+	mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */
+
+	square(&t, &t) /* 2^251 - 2^1 */
+	square(&t, &t) /* 2^252 - 2^2 */
+	square(&t, &t) /* 2^253 - 2^3 */
+
+	square(&t, &t) /* 2^254 - 2^4 */
+
+	square(&t, &t)   /* 2^255 - 2^5 */
+	mul(r, &t, &z11) /* 2^255 - 21 */
+}
diff --git a/vendor/golang.org/x/crypto/curve25519/mul_amd64.s b/vendor/golang.org/x/crypto/curve25519/mul_amd64.s
new file mode 100644
index 0000000..5ce80a2
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/mul_amd64.s
@@ -0,0 +1,169 @@
+// Copyright 2012 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.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+#include "const_amd64.h"
+
+// func mul(dest, a, b *[5]uint64)
+TEXT ·mul(SB),0,$16-24
+	MOVQ dest+0(FP), DI
+	MOVQ a+8(FP), SI
+	MOVQ b+16(FP), DX
+
+	MOVQ DX,CX
+	MOVQ 24(SI),DX
+	IMUL3Q $19,DX,AX
+	MOVQ AX,0(SP)
+	MULQ 16(CX)
+	MOVQ AX,R8
+	MOVQ DX,R9
+	MOVQ 32(SI),DX
+	IMUL3Q $19,DX,AX
+	MOVQ AX,8(SP)
+	MULQ 8(CX)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 0(SI),AX
+	MULQ 0(CX)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 0(SI),AX
+	MULQ 8(CX)
+	MOVQ AX,R10
+	MOVQ DX,R11
+	MOVQ 0(SI),AX
+	MULQ 16(CX)
+	MOVQ AX,R12
+	MOVQ DX,R13
+	MOVQ 0(SI),AX
+	MULQ 24(CX)
+	MOVQ AX,R14
+	MOVQ DX,R15
+	MOVQ 0(SI),AX
+	MULQ 32(CX)
+	MOVQ AX,BX
+	MOVQ DX,BP
+	MOVQ 8(SI),AX
+	MULQ 0(CX)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 8(SI),AX
+	MULQ 8(CX)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 8(SI),AX
+	MULQ 16(CX)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 8(SI),AX
+	MULQ 24(CX)
+	ADDQ AX,BX
+	ADCQ DX,BP
+	MOVQ 8(SI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(CX)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 16(SI),AX
+	MULQ 0(CX)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 16(SI),AX
+	MULQ 8(CX)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 16(SI),AX
+	MULQ 16(CX)
+	ADDQ AX,BX
+	ADCQ DX,BP
+	MOVQ 16(SI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 24(CX)
+	ADDQ AX,R8
+	ADCQ DX,R9
+	MOVQ 16(SI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(CX)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 24(SI),AX
+	MULQ 0(CX)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ 24(SI),AX
+	MULQ 8(CX)
+	ADDQ AX,BX
+	ADCQ DX,BP
+	MOVQ 0(SP),AX
+	MULQ 24(CX)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 0(SP),AX
+	MULQ 32(CX)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 32(SI),AX
+	MULQ 0(CX)
+	ADDQ AX,BX
+	ADCQ DX,BP
+	MOVQ 8(SP),AX
+	MULQ 16(CX)
+	ADDQ AX,R10
+	ADCQ DX,R11
+	MOVQ 8(SP),AX
+	MULQ 24(CX)
+	ADDQ AX,R12
+	ADCQ DX,R13
+	MOVQ 8(SP),AX
+	MULQ 32(CX)
+	ADDQ AX,R14
+	ADCQ DX,R15
+	MOVQ $REDMASK51,SI
+	SHLQ $13,R9:R8
+	ANDQ SI,R8
+	SHLQ $13,R11:R10
+	ANDQ SI,R10
+	ADDQ R9,R10
+	SHLQ $13,R13:R12
+	ANDQ SI,R12
+	ADDQ R11,R12
+	SHLQ $13,R15:R14
+	ANDQ SI,R14
+	ADDQ R13,R14
+	SHLQ $13,BP:BX
+	ANDQ SI,BX
+	ADDQ R15,BX
+	IMUL3Q $19,BP,DX
+	ADDQ DX,R8
+	MOVQ R8,DX
+	SHRQ $51,DX
+	ADDQ R10,DX
+	MOVQ DX,CX
+	SHRQ $51,DX
+	ANDQ SI,R8
+	ADDQ R12,DX
+	MOVQ DX,R9
+	SHRQ $51,DX
+	ANDQ SI,CX
+	ADDQ R14,DX
+	MOVQ DX,AX
+	SHRQ $51,DX
+	ANDQ SI,R9
+	ADDQ BX,DX
+	MOVQ DX,R10
+	SHRQ $51,DX
+	ANDQ SI,AX
+	IMUL3Q $19,DX,DX
+	ADDQ DX,R8
+	ANDQ SI,R10
+	MOVQ R8,0(DI)
+	MOVQ CX,8(DI)
+	MOVQ R9,16(DI)
+	MOVQ AX,24(DI)
+	MOVQ R10,32(DI)
+	RET
diff --git a/vendor/golang.org/x/crypto/curve25519/square_amd64.s b/vendor/golang.org/x/crypto/curve25519/square_amd64.s
new file mode 100644
index 0000000..12f7373
--- /dev/null
+++ b/vendor/golang.org/x/crypto/curve25519/square_amd64.s
@@ -0,0 +1,132 @@
+// Copyright 2012 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.
+
+// This code was translated into a form compatible with 6a from the public
+// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
+
+// +build amd64,!gccgo,!appengine
+
+#include "const_amd64.h"
+
+// func square(out, in *[5]uint64)
+TEXT ·square(SB),7,$0-16
+	MOVQ out+0(FP), DI
+	MOVQ in+8(FP), SI
+
+	MOVQ 0(SI),AX
+	MULQ 0(SI)
+	MOVQ AX,CX
+	MOVQ DX,R8
+	MOVQ 0(SI),AX
+	SHLQ $1,AX
+	MULQ 8(SI)
+	MOVQ AX,R9
+	MOVQ DX,R10
+	MOVQ 0(SI),AX
+	SHLQ $1,AX
+	MULQ 16(SI)
+	MOVQ AX,R11
+	MOVQ DX,R12
+	MOVQ 0(SI),AX
+	SHLQ $1,AX
+	MULQ 24(SI)
+	MOVQ AX,R13
+	MOVQ DX,R14
+	MOVQ 0(SI),AX
+	SHLQ $1,AX
+	MULQ 32(SI)
+	MOVQ AX,R15
+	MOVQ DX,BX
+	MOVQ 8(SI),AX
+	MULQ 8(SI)
+	ADDQ AX,R11
+	ADCQ DX,R12
+	MOVQ 8(SI),AX
+	SHLQ $1,AX
+	MULQ 16(SI)
+	ADDQ AX,R13
+	ADCQ DX,R14
+	MOVQ 8(SI),AX
+	SHLQ $1,AX
+	MULQ 24(SI)
+	ADDQ AX,R15
+	ADCQ DX,BX
+	MOVQ 8(SI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 32(SI)
+	ADDQ AX,CX
+	ADCQ DX,R8
+	MOVQ 16(SI),AX
+	MULQ 16(SI)
+	ADDQ AX,R15
+	ADCQ DX,BX
+	MOVQ 16(SI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 24(SI)
+	ADDQ AX,CX
+	ADCQ DX,R8
+	MOVQ 16(SI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 32(SI)
+	ADDQ AX,R9
+	ADCQ DX,R10
+	MOVQ 24(SI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 24(SI)
+	ADDQ AX,R9
+	ADCQ DX,R10
+	MOVQ 24(SI),DX
+	IMUL3Q $38,DX,AX
+	MULQ 32(SI)
+	ADDQ AX,R11
+	ADCQ DX,R12
+	MOVQ 32(SI),DX
+	IMUL3Q $19,DX,AX
+	MULQ 32(SI)
+	ADDQ AX,R13
+	ADCQ DX,R14
+	MOVQ $REDMASK51,SI
+	SHLQ $13,R8:CX
+	ANDQ SI,CX
+	SHLQ $13,R10:R9
+	ANDQ SI,R9
+	ADDQ R8,R9
+	SHLQ $13,R12:R11
+	ANDQ SI,R11
+	ADDQ R10,R11
+	SHLQ $13,R14:R13
+	ANDQ SI,R13
+	ADDQ R12,R13
+	SHLQ $13,BX:R15
+	ANDQ SI,R15
+	ADDQ R14,R15
+	IMUL3Q $19,BX,DX
+	ADDQ DX,CX
+	MOVQ CX,DX
+	SHRQ $51,DX
+	ADDQ R9,DX
+	ANDQ SI,CX
+	MOVQ DX,R8
+	SHRQ $51,DX
+	ADDQ R11,DX
+	ANDQ SI,R8
+	MOVQ DX,R9
+	SHRQ $51,DX
+	ADDQ R13,DX
+	ANDQ SI,R9
+	MOVQ DX,AX
+	SHRQ $51,DX
+	ADDQ R15,DX
+	ANDQ SI,AX
+	MOVQ DX,R10
+	SHRQ $51,DX
+	IMUL3Q $19,DX,DX
+	ADDQ DX,CX
+	ANDQ SI,R10
+	MOVQ CX,0(DI)
+	MOVQ R8,8(DI)
+	MOVQ R9,16(DI)
+	MOVQ AX,24(DI)
+	MOVQ R10,32(DI)
+	RET
diff --git a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
index dbf31bb..1e1dff5 100644
--- a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
+++ b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
@@ -13,7 +13,7 @@
 message, etc. Nonces are long enough that randomly generated nonces have
 negligible risk of collision.
 
-This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html.
+This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
 */
 package secretbox // import "golang.org/x/crypto/nacl/secretbox"
 
diff --git a/vendor/golang.org/x/crypto/pkcs12/bmp-string.go b/vendor/golang.org/x/crypto/pkcs12/bmp-string.go
index 284d2a6..233b8b6 100644
--- a/vendor/golang.org/x/crypto/pkcs12/bmp-string.go
+++ b/vendor/golang.org/x/crypto/pkcs12/bmp-string.go
@@ -13,7 +13,7 @@
 func bmpString(s string) ([]byte, error) {
 	// References:
 	// https://tools.ietf.org/html/rfc7292#appendix-B.1
-	// http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
+	// https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
 	//  - non-BMP characters are encoded in UTF 16 by using a surrogate pair of 16-bit codes
 	//	  EncodeRune returns 0xfffd if the rune does not need special encoding
 	//  - the above RFC provides the info that BMPStrings are NULL terminated.
diff --git a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go
index ad6341e..eff9ad3 100644
--- a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go
+++ b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go
@@ -109,6 +109,10 @@
 
 	bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword)
 
+	if err != nil {
+		return nil, err
+	}
+
 	blocks := make([]*pem.Block, 0, len(bags))
 	for _, bag := range bags {
 		block, err := convertBag(&bag, encodedPassword)
diff --git a/vendor/golang.org/x/crypto/poly1305/const_amd64.s b/vendor/golang.org/x/crypto/poly1305/const_amd64.s
deleted file mode 100644
index 8e861f3..0000000
--- a/vendor/golang.org/x/crypto/poly1305/const_amd64.s
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 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.
-
-// This code was translated into a form compatible with 6a from the public
-// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
-
-// +build amd64,!gccgo,!appengine
-
-DATA ·SCALE(SB)/8, $0x37F4000000000000
-GLOBL ·SCALE(SB), 8, $8
-DATA ·TWO32(SB)/8, $0x41F0000000000000
-GLOBL ·TWO32(SB), 8, $8
-DATA ·TWO64(SB)/8, $0x43F0000000000000
-GLOBL ·TWO64(SB), 8, $8
-DATA ·TWO96(SB)/8, $0x45F0000000000000
-GLOBL ·TWO96(SB), 8, $8
-DATA ·ALPHA32(SB)/8, $0x45E8000000000000
-GLOBL ·ALPHA32(SB), 8, $8
-DATA ·ALPHA64(SB)/8, $0x47E8000000000000
-GLOBL ·ALPHA64(SB), 8, $8
-DATA ·ALPHA96(SB)/8, $0x49E8000000000000
-GLOBL ·ALPHA96(SB), 8, $8
-DATA ·ALPHA130(SB)/8, $0x4C08000000000000
-GLOBL ·ALPHA130(SB), 8, $8
-DATA ·DOFFSET0(SB)/8, $0x4330000000000000
-GLOBL ·DOFFSET0(SB), 8, $8
-DATA ·DOFFSET1(SB)/8, $0x4530000000000000
-GLOBL ·DOFFSET1(SB), 8, $8
-DATA ·DOFFSET2(SB)/8, $0x4730000000000000
-GLOBL ·DOFFSET2(SB), 8, $8
-DATA ·DOFFSET3(SB)/8, $0x4930000000000000
-GLOBL ·DOFFSET3(SB), 8, $8
-DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000
-GLOBL ·DOFFSET3MINUSTWO128(SB), 8, $8
-DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB
-GLOBL ·HOFFSET0(SB), 8, $8
-DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE
-GLOBL ·HOFFSET1(SB), 8, $8
-DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE
-GLOBL ·HOFFSET2(SB), 8, $8
-DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE
-GLOBL ·HOFFSET3(SB), 8, $8
-DATA ·ROUNDING(SB)/2, $0x137f
-GLOBL ·ROUNDING(SB), 8, $2
diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305.go b/vendor/golang.org/x/crypto/poly1305/poly1305.go
index 4a5f826..f562fa5 100644
--- a/vendor/golang.org/x/crypto/poly1305/poly1305.go
+++ b/vendor/golang.org/x/crypto/poly1305/poly1305.go
@@ -3,7 +3,8 @@
 // license that can be found in the LICENSE file.
 
 /*
-Package poly1305 implements Poly1305 one-time message authentication code as specified in http://cr.yp.to/mac/poly1305-20050329.pdf.
+Package poly1305 implements Poly1305 one-time message authentication code as
+specified in https://cr.yp.to/mac/poly1305-20050329.pdf.
 
 Poly1305 is a fast, one-time authentication function. It is infeasible for an
 attacker to generate an authenticator for a message without the key. However, a
diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s b/vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s
deleted file mode 100644
index f8d4ee9..0000000
--- a/vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright 2012 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.
-
-// This code was translated into a form compatible with 6a from the public
-// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
-
-// +build amd64,!gccgo,!appengine
-
-// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
-TEXT ·poly1305(SB),0,$224-32
-	MOVQ out+0(FP),DI
-	MOVQ m+8(FP),SI
-	MOVQ mlen+16(FP),DX
-	MOVQ key+24(FP),CX
-
-	MOVQ SP,R11
-	MOVQ $31,R9
-	NOTQ R9
-	ANDQ R9,SP
-	ADDQ $32,SP
-
-	MOVQ R11,32(SP)
-	MOVQ R12,40(SP)
-	MOVQ R13,48(SP)
-	MOVQ R14,56(SP)
-	MOVQ R15,64(SP)
-	MOVQ BX,72(SP)
-	MOVQ BP,80(SP)
-	FLDCW ·ROUNDING(SB)
-	MOVL 0(CX),R8
-	MOVL 4(CX),R9
-	MOVL 8(CX),AX
-	MOVL 12(CX),R10
-	MOVQ DI,88(SP)
-	MOVQ CX,96(SP)
-	MOVL $0X43300000,108(SP)
-	MOVL $0X45300000,116(SP)
-	MOVL $0X47300000,124(SP)
-	MOVL $0X49300000,132(SP)
-	ANDL $0X0FFFFFFF,R8
-	ANDL $0X0FFFFFFC,R9
-	ANDL $0X0FFFFFFC,AX
-	ANDL $0X0FFFFFFC,R10
-	MOVL R8,104(SP)
-	MOVL R9,112(SP)
-	MOVL AX,120(SP)
-	MOVL R10,128(SP)
-	FMOVD 104(SP), F0
-	FSUBD ·DOFFSET0(SB), F0
-	FMOVD 112(SP), F0
-	FSUBD ·DOFFSET1(SB), F0
-	FMOVD 120(SP), F0
-	FSUBD ·DOFFSET2(SB), F0
-	FMOVD 128(SP), F0
-	FSUBD ·DOFFSET3(SB), F0
-	FXCHD F0, F3
-	FMOVDP F0, 136(SP)
-	FXCHD F0, F1
-	FMOVD F0, 144(SP)
-	FMULD ·SCALE(SB), F0
-	FMOVDP F0, 152(SP)
-	FMOVD F0, 160(SP)
-	FMULD ·SCALE(SB), F0
-	FMOVDP F0, 168(SP)
-	FMOVD F0, 176(SP)
-	FMULD ·SCALE(SB), F0
-	FMOVDP F0, 184(SP)
-	FLDZ
-	FLDZ
-	FLDZ
-	FLDZ
-	CMPQ DX,$16
-	JB ADDATMOST15BYTES
-	INITIALATLEAST16BYTES:
-	MOVL 12(SI),DI
-	MOVL 8(SI),CX
-	MOVL 4(SI),R8
-	MOVL 0(SI),R9
-	MOVL DI,128(SP)
-	MOVL CX,120(SP)
-	MOVL R8,112(SP)
-	MOVL R9,104(SP)
-	ADDQ $16,SI
-	SUBQ $16,DX
-	FXCHD F0, F3
-	FADDD 128(SP), F0
-	FSUBD ·DOFFSET3MINUSTWO128(SB), F0
-	FXCHD F0, F1
-	FADDD 112(SP), F0
-	FSUBD ·DOFFSET1(SB), F0
-	FXCHD F0, F2
-	FADDD 120(SP), F0
-	FSUBD ·DOFFSET2(SB), F0
-	FXCHD F0, F3
-	FADDD 104(SP), F0
-	FSUBD ·DOFFSET0(SB), F0
-	CMPQ DX,$16
-	JB MULTIPLYADDATMOST15BYTES
-	MULTIPLYADDATLEAST16BYTES:
-	MOVL 12(SI),DI
-	MOVL 8(SI),CX
-	MOVL 4(SI),R8
-	MOVL 0(SI),R9
-	MOVL DI,128(SP)
-	MOVL CX,120(SP)
-	MOVL R8,112(SP)
-	MOVL R9,104(SP)
-	ADDQ $16,SI
-	SUBQ $16,DX
-	FMOVD ·ALPHA130(SB), F0
-	FADDD F2,F0
-	FSUBD ·ALPHA130(SB), F0
-	FSUBD F0,F2
-	FMULD ·SCALE(SB), F0
-	FMOVD ·ALPHA32(SB), F0
-	FADDD F2,F0
-	FSUBD ·ALPHA32(SB), F0
-	FSUBD F0,F2
-	FXCHD F0, F2
-	FADDDP F0,F1
-	FMOVD ·ALPHA64(SB), F0
-	FADDD F4,F0
-	FSUBD ·ALPHA64(SB), F0
-	FSUBD F0,F4
-	FMOVD ·ALPHA96(SB), F0
-	FADDD F6,F0
-	FSUBD ·ALPHA96(SB), F0
-	FSUBD F0,F6
-	FXCHD F0, F6
-	FADDDP F0,F1
-	FXCHD F0, F3
-	FADDDP F0,F5
-	FXCHD F0, F3
-	FADDDP F0,F1
-	FMOVD 176(SP), F0
-	FMULD F3,F0
-	FMOVD 160(SP), F0
-	FMULD F4,F0
-	FMOVD 144(SP), F0
-	FMULD F5,F0
-	FMOVD 136(SP), F0
-	FMULDP F0,F6
-	FMOVD 160(SP), F0
-	FMULD F4,F0
-	FADDDP F0,F3
-	FMOVD 144(SP), F0
-	FMULD F4,F0
-	FADDDP F0,F2
-	FMOVD 136(SP), F0
-	FMULD F4,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULDP F0,F4
-	FXCHD F0, F3
-	FADDDP F0,F5
-	FMOVD 144(SP), F0
-	FMULD F4,F0
-	FADDDP F0,F2
-	FMOVD 136(SP), F0
-	FMULD F4,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULD F4,F0
-	FADDDP F0,F3
-	FMOVD 168(SP), F0
-	FMULDP F0,F4
-	FXCHD F0, F3
-	FADDDP F0,F4
-	FMOVD 136(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F1
-	FXCHD F0, F3
-	FMOVD 184(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F3
-	FXCHD F0, F1
-	FMOVD 168(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F1
-	FMOVD 152(SP), F0
-	FMULDP F0,F5
-	FXCHD F0, F4
-	FADDDP F0,F1
-	CMPQ DX,$16
-	FXCHD F0, F2
-	FMOVD 128(SP), F0
-	FSUBD ·DOFFSET3MINUSTWO128(SB), F0
-	FADDDP F0,F1
-	FXCHD F0, F1
-	FMOVD 120(SP), F0
-	FSUBD ·DOFFSET2(SB), F0
-	FADDDP F0,F1
-	FXCHD F0, F3
-	FMOVD 112(SP), F0
-	FSUBD ·DOFFSET1(SB), F0
-	FADDDP F0,F1
-	FXCHD F0, F2
-	FMOVD 104(SP), F0
-	FSUBD ·DOFFSET0(SB), F0
-	FADDDP F0,F1
-	JAE MULTIPLYADDATLEAST16BYTES
-	MULTIPLYADDATMOST15BYTES:
-	FMOVD ·ALPHA130(SB), F0
-	FADDD F2,F0
-	FSUBD ·ALPHA130(SB), F0
-	FSUBD F0,F2
-	FMULD ·SCALE(SB), F0
-	FMOVD ·ALPHA32(SB), F0
-	FADDD F2,F0
-	FSUBD ·ALPHA32(SB), F0
-	FSUBD F0,F2
-	FMOVD ·ALPHA64(SB), F0
-	FADDD F5,F0
-	FSUBD ·ALPHA64(SB), F0
-	FSUBD F0,F5
-	FMOVD ·ALPHA96(SB), F0
-	FADDD F7,F0
-	FSUBD ·ALPHA96(SB), F0
-	FSUBD F0,F7
-	FXCHD F0, F7
-	FADDDP F0,F1
-	FXCHD F0, F5
-	FADDDP F0,F1
-	FXCHD F0, F3
-	FADDDP F0,F5
-	FADDDP F0,F1
-	FMOVD 176(SP), F0
-	FMULD F1,F0
-	FMOVD 160(SP), F0
-	FMULD F2,F0
-	FMOVD 144(SP), F0
-	FMULD F3,F0
-	FMOVD 136(SP), F0
-	FMULDP F0,F4
-	FMOVD 160(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F3
-	FMOVD 144(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F2
-	FMOVD 136(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULDP F0,F5
-	FXCHD F0, F4
-	FADDDP F0,F3
-	FMOVD 144(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F2
-	FMOVD 136(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F4
-	FMOVD 168(SP), F0
-	FMULDP F0,F5
-	FXCHD F0, F4
-	FADDDP F0,F2
-	FMOVD 136(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F4
-	FMOVD 168(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F3
-	FMOVD 152(SP), F0
-	FMULDP F0,F5
-	FXCHD F0, F4
-	FADDDP F0,F1
-	ADDATMOST15BYTES:
-	CMPQ DX,$0
-	JE NOMOREBYTES
-	MOVL $0,0(SP)
-	MOVL $0, 4 (SP)
-	MOVL $0, 8 (SP)
-	MOVL $0, 12 (SP)
-	LEAQ 0(SP),DI
-	MOVQ DX,CX
-	REP; MOVSB
-	MOVB $1,0(DI)
-	MOVL  12 (SP),DI
-	MOVL  8 (SP),SI
-	MOVL  4 (SP),DX
-	MOVL 0(SP),CX
-	MOVL DI,128(SP)
-	MOVL SI,120(SP)
-	MOVL DX,112(SP)
-	MOVL CX,104(SP)
-	FXCHD F0, F3
-	FADDD 128(SP), F0
-	FSUBD ·DOFFSET3(SB), F0
-	FXCHD F0, F2
-	FADDD 120(SP), F0
-	FSUBD ·DOFFSET2(SB), F0
-	FXCHD F0, F1
-	FADDD 112(SP), F0
-	FSUBD ·DOFFSET1(SB), F0
-	FXCHD F0, F3
-	FADDD 104(SP), F0
-	FSUBD ·DOFFSET0(SB), F0
-	FMOVD ·ALPHA130(SB), F0
-	FADDD F3,F0
-	FSUBD ·ALPHA130(SB), F0
-	FSUBD F0,F3
-	FMULD ·SCALE(SB), F0
-	FMOVD ·ALPHA32(SB), F0
-	FADDD F2,F0
-	FSUBD ·ALPHA32(SB), F0
-	FSUBD F0,F2
-	FMOVD ·ALPHA64(SB), F0
-	FADDD F6,F0
-	FSUBD ·ALPHA64(SB), F0
-	FSUBD F0,F6
-	FMOVD ·ALPHA96(SB), F0
-	FADDD F5,F0
-	FSUBD ·ALPHA96(SB), F0
-	FSUBD F0,F5
-	FXCHD F0, F4
-	FADDDP F0,F3
-	FXCHD F0, F6
-	FADDDP F0,F1
-	FXCHD F0, F3
-	FADDDP F0,F5
-	FXCHD F0, F3
-	FADDDP F0,F1
-	FMOVD 176(SP), F0
-	FMULD F3,F0
-	FMOVD 160(SP), F0
-	FMULD F4,F0
-	FMOVD 144(SP), F0
-	FMULD F5,F0
-	FMOVD 136(SP), F0
-	FMULDP F0,F6
-	FMOVD 160(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F3
-	FMOVD 144(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F2
-	FMOVD 136(SP), F0
-	FMULD F5,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULDP F0,F5
-	FXCHD F0, F4
-	FADDDP F0,F5
-	FMOVD 144(SP), F0
-	FMULD F6,F0
-	FADDDP F0,F2
-	FMOVD 136(SP), F0
-	FMULD F6,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULD F6,F0
-	FADDDP F0,F4
-	FMOVD 168(SP), F0
-	FMULDP F0,F6
-	FXCHD F0, F5
-	FADDDP F0,F4
-	FMOVD 136(SP), F0
-	FMULD F2,F0
-	FADDDP F0,F1
-	FMOVD 184(SP), F0
-	FMULD F2,F0
-	FADDDP F0,F5
-	FMOVD 168(SP), F0
-	FMULD F2,F0
-	FADDDP F0,F3
-	FMOVD 152(SP), F0
-	FMULDP F0,F2
-	FXCHD F0, F1
-	FADDDP F0,F3
-	FXCHD F0, F3
-	FXCHD F0, F2
-	NOMOREBYTES:
-	MOVL $0,R10
-	FMOVD ·ALPHA130(SB), F0
-	FADDD F4,F0
-	FSUBD ·ALPHA130(SB), F0
-	FSUBD F0,F4
-	FMULD ·SCALE(SB), F0
-	FMOVD ·ALPHA32(SB), F0
-	FADDD F2,F0
-	FSUBD ·ALPHA32(SB), F0
-	FSUBD F0,F2
-	FMOVD ·ALPHA64(SB), F0
-	FADDD F4,F0
-	FSUBD ·ALPHA64(SB), F0
-	FSUBD F0,F4
-	FMOVD ·ALPHA96(SB), F0
-	FADDD F6,F0
-	FSUBD ·ALPHA96(SB), F0
-	FXCHD F0, F6
-	FSUBD F6,F0
-	FXCHD F0, F4
-	FADDDP F0,F3
-	FXCHD F0, F4
-	FADDDP F0,F1
-	FXCHD F0, F2
-	FADDDP F0,F3
-	FXCHD F0, F4
-	FADDDP F0,F3
-	FXCHD F0, F3
-	FADDD ·HOFFSET0(SB), F0
-	FXCHD F0, F3
-	FADDD ·HOFFSET1(SB), F0
-	FXCHD F0, F1
-	FADDD ·HOFFSET2(SB), F0
-	FXCHD F0, F2
-	FADDD ·HOFFSET3(SB), F0
-	FXCHD F0, F3
-	FMOVDP F0, 104(SP)
-	FMOVDP F0, 112(SP)
-	FMOVDP F0, 120(SP)
-	FMOVDP F0, 128(SP)
-	MOVL 108(SP),DI
-	ANDL $63,DI
-	MOVL 116(SP),SI
-	ANDL $63,SI
-	MOVL 124(SP),DX
-	ANDL $63,DX
-	MOVL 132(SP),CX
-	ANDL $63,CX
-	MOVL 112(SP),R8
-	ADDL DI,R8
-	MOVQ R8,112(SP)
-	MOVL 120(SP),DI
-	ADCL SI,DI
-	MOVQ DI,120(SP)
-	MOVL 128(SP),DI
-	ADCL DX,DI
-	MOVQ DI,128(SP)
-	MOVL R10,DI
-	ADCL CX,DI
-	MOVQ DI,136(SP)
-	MOVQ $5,DI
-	MOVL 104(SP),SI
-	ADDL SI,DI
-	MOVQ DI,104(SP)
-	MOVL R10,DI
-	MOVQ 112(SP),DX
-	ADCL DX,DI
-	MOVQ DI,112(SP)
-	MOVL R10,DI
-	MOVQ 120(SP),CX
-	ADCL CX,DI
-	MOVQ DI,120(SP)
-	MOVL R10,DI
-	MOVQ 128(SP),R8
-	ADCL R8,DI
-	MOVQ DI,128(SP)
-	MOVQ $0XFFFFFFFC,DI
-	MOVQ 136(SP),R9
-	ADCL R9,DI
-	SARL $16,DI
-	MOVQ DI,R9
-	XORL $0XFFFFFFFF,R9
-	ANDQ DI,SI
-	MOVQ 104(SP),AX
-	ANDQ R9,AX
-	ORQ AX,SI
-	ANDQ DI,DX
-	MOVQ 112(SP),AX
-	ANDQ R9,AX
-	ORQ AX,DX
-	ANDQ DI,CX
-	MOVQ 120(SP),AX
-	ANDQ R9,AX
-	ORQ AX,CX
-	ANDQ DI,R8
-	MOVQ 128(SP),DI
-	ANDQ R9,DI
-	ORQ DI,R8
-	MOVQ 88(SP),DI
-	MOVQ 96(SP),R9
-	ADDL 16(R9),SI
-	ADCL 20(R9),DX
-	ADCL 24(R9),CX
-	ADCL 28(R9),R8
-	MOVL SI,0(DI)
-	MOVL DX,4(DI)
-	MOVL CX,8(DI)
-	MOVL R8,12(DI)
-	MOVQ 32(SP),R11
-	MOVQ 40(SP),R12
-	MOVQ 48(SP),R13
-	MOVQ 56(SP),R14
-	MOVQ 64(SP),R15
-	MOVQ 72(SP),BX
-	MOVQ 80(SP),BP
-	MOVQ R11,SP
-	RET
diff --git a/vendor/golang.org/x/crypto/poly1305/poly1305_arm.s b/vendor/golang.org/x/crypto/poly1305/poly1305_arm.s
deleted file mode 100644
index c153867..0000000
--- a/vendor/golang.org/x/crypto/poly1305/poly1305_arm.s
+++ /dev/null
@@ -1,379 +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.
-
-// This code was translated into a form compatible with 5a from the public
-// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
-
-// +build arm,!gccgo,!appengine
-
-DATA poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
-DATA poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
-DATA poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
-DATA poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
-DATA poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
-GLOBL poly1305_init_constants_armv6<>(SB), 8, $20
-
-// Warning: the linker may use R11 to synthesize certain instructions. Please
-// take care and verify that no synthetic instructions use it.
-
-TEXT poly1305_init_ext_armv6<>(SB),4,$-4
-  MOVM.DB.W [R4-R11], (R13)
-  MOVM.IA.W (R1), [R2-R5]
-  MOVW $poly1305_init_constants_armv6<>(SB), R7
-  MOVW R2, R8
-  MOVW R2>>26, R9
-  MOVW R3>>20, g
-  MOVW R4>>14, R11
-  MOVW R5>>8, R12
-  ORR R3<<6, R9, R9
-  ORR R4<<12, g, g
-  ORR R5<<18, R11, R11
-  MOVM.IA (R7), [R2-R6]
-  AND R8, R2, R2
-  AND R9, R3, R3
-  AND g, R4, R4
-  AND R11, R5, R5
-  AND R12, R6, R6
-  MOVM.IA.W [R2-R6], (R0)
-  EOR R2, R2, R2
-  EOR R3, R3, R3
-  EOR R4, R4, R4
-  EOR R5, R5, R5
-  EOR R6, R6, R6
-  MOVM.IA.W [R2-R6], (R0)
-  MOVM.IA.W (R1), [R2-R5]
-  MOVM.IA [R2-R6], (R0)
-  MOVM.IA.W (R13), [R4-R11]
-  RET
-
-#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
-  MOVBU (offset+0)(Rsrc), Rtmp; \
-  MOVBU Rtmp, (offset+0)(Rdst); \
-  MOVBU (offset+1)(Rsrc), Rtmp; \
-  MOVBU Rtmp, (offset+1)(Rdst); \
-  MOVBU (offset+2)(Rsrc), Rtmp; \
-  MOVBU Rtmp, (offset+2)(Rdst); \
-  MOVBU (offset+3)(Rsrc), Rtmp; \
-  MOVBU Rtmp, (offset+3)(Rdst)
-
-TEXT poly1305_blocks_armv6<>(SB),4,$-4
-  MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
-  SUB $128, R13
-  MOVW R0, 36(R13)
-  MOVW R1, 40(R13)
-  MOVW R2, 44(R13)
-  MOVW R1, R14
-  MOVW R2, R12
-  MOVW 56(R0), R8
-  WORD $0xe1180008 // TST R8, R8 not working see issue 5921
-  EOR R6, R6, R6
-  MOVW.EQ $(1<<24), R6
-  MOVW R6, 32(R13)
-  ADD $64, R13, g
-  MOVM.IA (R0), [R0-R9]
-  MOVM.IA [R0-R4], (g)
-  CMP $16, R12
-  BLO poly1305_blocks_armv6_done
-poly1305_blocks_armv6_mainloop:
-  WORD $0xe31e0003 // TST R14, #3 not working see issue 5921
-  BEQ poly1305_blocks_armv6_mainloop_aligned
-  ADD $48, R13, g
-  MOVW_UNALIGNED(R14, g, R0, 0)
-  MOVW_UNALIGNED(R14, g, R0, 4)
-  MOVW_UNALIGNED(R14, g, R0, 8)
-  MOVW_UNALIGNED(R14, g, R0, 12)
-  MOVM.IA (g), [R0-R3]
-  ADD $16, R14
-  B poly1305_blocks_armv6_mainloop_loaded
-poly1305_blocks_armv6_mainloop_aligned:
-  MOVM.IA.W (R14), [R0-R3]
-poly1305_blocks_armv6_mainloop_loaded:
-  MOVW R0>>26, g
-  MOVW R1>>20, R11
-  MOVW R2>>14, R12
-  MOVW R14, 40(R13)
-  MOVW R3>>8, R4
-  ORR R1<<6, g, g
-  ORR R2<<12, R11, R11
-  ORR R3<<18, R12, R12
-  BIC $0xfc000000, R0, R0
-  BIC $0xfc000000, g, g
-  MOVW 32(R13), R3
-  BIC $0xfc000000, R11, R11
-  BIC $0xfc000000, R12, R12
-  ADD R0, R5, R5
-  ADD g, R6, R6
-  ORR R3, R4, R4
-  ADD R11, R7, R7
-  ADD $64, R13, R14
-  ADD R12, R8, R8
-  ADD R4, R9, R9
-  MOVM.IA (R14), [R0-R4]
-  MULLU R4, R5, (R11, g)
-  MULLU R3, R5, (R14, R12)
-  MULALU R3, R6, (R11, g)
-  MULALU R2, R6, (R14, R12)
-  MULALU R2, R7, (R11, g)
-  MULALU R1, R7, (R14, R12)
-  ADD R4<<2, R4, R4
-  ADD R3<<2, R3, R3
-  MULALU R1, R8, (R11, g)
-  MULALU R0, R8, (R14, R12)
-  MULALU R0, R9, (R11, g)
-  MULALU R4, R9, (R14, R12)
-  MOVW g, 24(R13)
-  MOVW R11, 28(R13)
-  MOVW R12, 16(R13)
-  MOVW R14, 20(R13)
-  MULLU R2, R5, (R11, g)
-  MULLU R1, R5, (R14, R12)
-  MULALU R1, R6, (R11, g)
-  MULALU R0, R6, (R14, R12)
-  MULALU R0, R7, (R11, g)
-  MULALU R4, R7, (R14, R12)
-  ADD R2<<2, R2, R2
-  ADD R1<<2, R1, R1
-  MULALU R4, R8, (R11, g)
-  MULALU R3, R8, (R14, R12)
-  MULALU R3, R9, (R11, g)
-  MULALU R2, R9, (R14, R12)
-  MOVW g, 8(R13)
-  MOVW R11, 12(R13)
-  MOVW R12, 0(R13)
-  MOVW R14, w+4(SP)
-  MULLU R0, R5, (R11, g)
-  MULALU R4, R6, (R11, g)
-  MULALU R3, R7, (R11, g)
-  MULALU R2, R8, (R11, g)
-  MULALU R1, R9, (R11, g)
-  MOVM.IA (R13), [R0-R7]
-  MOVW g>>26, R12
-  MOVW R4>>26, R14
-  ORR R11<<6, R12, R12
-  ORR R5<<6, R14, R14
-  BIC $0xfc000000, g, g
-  BIC $0xfc000000, R4, R4
-  ADD.S R12, R0, R0
-  ADC $0, R1, R1
-  ADD.S R14, R6, R6
-  ADC $0, R7, R7
-  MOVW R0>>26, R12
-  MOVW R6>>26, R14
-  ORR R1<<6, R12, R12
-  ORR R7<<6, R14, R14
-  BIC $0xfc000000, R0, R0
-  BIC $0xfc000000, R6, R6
-  ADD R14<<2, R14, R14
-  ADD.S R12, R2, R2
-  ADC $0, R3, R3
-  ADD R14, g, g
-  MOVW R2>>26, R12
-  MOVW g>>26, R14
-  ORR R3<<6, R12, R12
-  BIC $0xfc000000, g, R5
-  BIC $0xfc000000, R2, R7
-  ADD R12, R4, R4
-  ADD R14, R0, R0
-  MOVW R4>>26, R12
-  BIC $0xfc000000, R4, R8
-  ADD R12, R6, R9
-  MOVW w+44(SP), R12
-  MOVW w+40(SP), R14
-  MOVW R0, R6
-  CMP $32, R12
-  SUB $16, R12, R12
-  MOVW R12, 44(R13)
-  BHS poly1305_blocks_armv6_mainloop
-poly1305_blocks_armv6_done:
-  MOVW 36(R13), R12
-  MOVW R5, 20(R12)
-  MOVW R6, 24(R12)
-  MOVW R7, 28(R12)
-  MOVW R8, 32(R12)
-  MOVW R9, 36(R12)
-  ADD $128, R13, R13
-  MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
-  RET
-
-#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
-  MOVBU.P 1(Rsrc), Rtmp; \
-  MOVBU.P Rtmp, 1(Rdst); \
-  MOVBU.P 1(Rsrc), Rtmp; \
-  MOVBU.P Rtmp, 1(Rdst)
-
-#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
-  MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
-  MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
-
-TEXT poly1305_finish_ext_armv6<>(SB),4,$-4
-  MOVM.DB.W [R4, R5, R6, R7, R8, R9, g, R11, R14], (R13)
-  SUB $16, R13, R13
-  MOVW R0, R5
-  MOVW R1, R6
-  MOVW R2, R7
-  MOVW R3, R8
-  AND.S R2, R2, R2
-  BEQ poly1305_finish_ext_armv6_noremaining
-  EOR R0, R0
-  MOVW R13, R9
-  MOVW R0, 0(R13)
-  MOVW R0, 4(R13)
-  MOVW R0, 8(R13)
-  MOVW R0, 12(R13)
-  WORD $0xe3110003 // TST R1, #3 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_aligned
-  WORD $0xe3120008 // TST R2, #8 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_skip8
-  MOVWP_UNALIGNED(R1, R9, g)
-  MOVWP_UNALIGNED(R1, R9, g)
-poly1305_finish_ext_armv6_skip8:
-  WORD $0xe3120004 // TST $4, R2 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_skip4
-  MOVWP_UNALIGNED(R1, R9, g)
-poly1305_finish_ext_armv6_skip4:
-  WORD $0xe3120002 // TST $2, R2 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_skip2
-  MOVHUP_UNALIGNED(R1, R9, g)
-  B poly1305_finish_ext_armv6_skip2
-poly1305_finish_ext_armv6_aligned:
-  WORD $0xe3120008 // TST R2, #8 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_skip8_aligned
-  MOVM.IA.W (R1), [g-R11]
-  MOVM.IA.W [g-R11], (R9)
-poly1305_finish_ext_armv6_skip8_aligned:
-  WORD $0xe3120004 // TST $4, R2 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_skip4_aligned
-  MOVW.P 4(R1), g
-  MOVW.P g, 4(R9)
-poly1305_finish_ext_armv6_skip4_aligned:
-  WORD $0xe3120002 // TST $2, R2 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_skip2
-  MOVHU.P 2(R1), g
-  MOVH.P g, 2(R9)
-poly1305_finish_ext_armv6_skip2:
-  WORD $0xe3120001 // TST $1, R2 not working see issue 5921
-  BEQ poly1305_finish_ext_armv6_skip1
-  MOVBU.P 1(R1), g
-  MOVBU.P g, 1(R9)
-poly1305_finish_ext_armv6_skip1:
-  MOVW $1, R11
-  MOVBU R11, 0(R9)
-  MOVW R11, 56(R5)
-  MOVW R5, R0
-  MOVW R13, R1
-  MOVW $16, R2
-  BL poly1305_blocks_armv6<>(SB)
-poly1305_finish_ext_armv6_noremaining:
-  MOVW 20(R5), R0
-  MOVW 24(R5), R1
-  MOVW 28(R5), R2
-  MOVW 32(R5), R3
-  MOVW 36(R5), R4
-  MOVW R4>>26, R12
-  BIC $0xfc000000, R4, R4
-  ADD R12<<2, R12, R12
-  ADD R12, R0, R0
-  MOVW R0>>26, R12
-  BIC $0xfc000000, R0, R0
-  ADD R12, R1, R1
-  MOVW R1>>26, R12
-  BIC $0xfc000000, R1, R1
-  ADD R12, R2, R2
-  MOVW R2>>26, R12
-  BIC $0xfc000000, R2, R2
-  ADD R12, R3, R3
-  MOVW R3>>26, R12
-  BIC $0xfc000000, R3, R3
-  ADD R12, R4, R4
-  ADD $5, R0, R6
-  MOVW R6>>26, R12
-  BIC $0xfc000000, R6, R6
-  ADD R12, R1, R7
-  MOVW R7>>26, R12
-  BIC $0xfc000000, R7, R7
-  ADD R12, R2, g
-  MOVW g>>26, R12
-  BIC $0xfc000000, g, g
-  ADD R12, R3, R11
-  MOVW $-(1<<26), R12
-  ADD R11>>26, R12, R12
-  BIC $0xfc000000, R11, R11
-  ADD R12, R4, R14
-  MOVW R14>>31, R12
-  SUB $1, R12
-  AND R12, R6, R6
-  AND R12, R7, R7
-  AND R12, g, g
-  AND R12, R11, R11
-  AND R12, R14, R14
-  MVN R12, R12
-  AND R12, R0, R0
-  AND R12, R1, R1
-  AND R12, R2, R2
-  AND R12, R3, R3
-  AND R12, R4, R4
-  ORR R6, R0, R0
-  ORR R7, R1, R1
-  ORR g, R2, R2
-  ORR R11, R3, R3
-  ORR R14, R4, R4
-  ORR R1<<26, R0, R0
-  MOVW R1>>6, R1
-  ORR R2<<20, R1, R1
-  MOVW R2>>12, R2
-  ORR R3<<14, R2, R2
-  MOVW R3>>18, R3
-  ORR R4<<8, R3, R3
-  MOVW 40(R5), R6
-  MOVW 44(R5), R7
-  MOVW 48(R5), g
-  MOVW 52(R5), R11
-  ADD.S R6, R0, R0
-  ADC.S R7, R1, R1
-  ADC.S g, R2, R2
-  ADC.S R11, R3, R3
-  MOVM.IA [R0-R3], (R8)
-  MOVW R5, R12
-  EOR R0, R0, R0
-  EOR R1, R1, R1
-  EOR R2, R2, R2
-  EOR R3, R3, R3
-  EOR R4, R4, R4
-  EOR R5, R5, R5
-  EOR R6, R6, R6
-  EOR R7, R7, R7
-  MOVM.IA.W [R0-R7], (R12)
-  MOVM.IA [R0-R7], (R12)
-  ADD $16, R13, R13
-  MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, g, R11, R14]
-  RET
-
-// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key)
-TEXT ·poly1305_auth_armv6(SB),0,$280-16
-  MOVW  out+0(FP), R4
-  MOVW  m+4(FP), R5
-  MOVW  mlen+8(FP), R6
-  MOVW  key+12(FP), R7
-
-  MOVW R13, R8
-  BIC $63, R13
-  SUB $64, R13, R13
-  MOVW  R13, R0
-  MOVW  R7, R1
-  BL poly1305_init_ext_armv6<>(SB)
-  BIC.S $15, R6, R2
-  BEQ poly1305_auth_armv6_noblocks
-  MOVW R13, R0
-  MOVW R5, R1
-  ADD R2, R5, R5
-  SUB R2, R6, R6
-  BL poly1305_blocks_armv6<>(SB)
-poly1305_auth_armv6_noblocks:
-  MOVW R13, R0
-  MOVW R5, R1
-  MOVW R6, R2
-  MOVW R4, R3
-  BL poly1305_finish_ext_armv6<>(SB)
-  MOVW R8, R13
-  RET
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
index 6775c70..4dd72fe 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_amd64.go
@@ -6,10 +6,8 @@
 
 package poly1305
 
-// This function is implemented in poly1305_amd64.s
-
+// This function is implemented in sum_amd64.s
 //go:noescape
-
 func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte)
 
 // Sum generates an authenticator for m using a one-time key and puts the
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_amd64.s b/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
new file mode 100644
index 0000000..2edae63
--- /dev/null
+++ b/vendor/golang.org/x/crypto/poly1305/sum_amd64.s
@@ -0,0 +1,125 @@
+// Copyright 2012 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.
+
+// +build amd64,!gccgo,!appengine
+
+#include "textflag.h"
+
+#define POLY1305_ADD(msg, h0, h1, h2) \
+	ADDQ 0(msg), h0;  \
+	ADCQ 8(msg), h1;  \
+	ADCQ $1, h2;      \
+	LEAQ 16(msg), msg
+
+#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \
+	MOVQ  r0, AX;                  \
+	MULQ  h0;                      \
+	MOVQ  AX, t0;                  \
+	MOVQ  DX, t1;                  \
+	MOVQ  r0, AX;                  \
+	MULQ  h1;                      \
+	ADDQ  AX, t1;                  \
+	ADCQ  $0, DX;                  \
+	MOVQ  r0, t2;                  \
+	IMULQ h2, t2;                  \
+	ADDQ  DX, t2;                  \
+	                               \
+	MOVQ  r1, AX;                  \
+	MULQ  h0;                      \
+	ADDQ  AX, t1;                  \
+	ADCQ  $0, DX;                  \
+	MOVQ  DX, h0;                  \
+	MOVQ  r1, t3;                  \
+	IMULQ h2, t3;                  \
+	MOVQ  r1, AX;                  \
+	MULQ  h1;                      \
+	ADDQ  AX, t2;                  \
+	ADCQ  DX, t3;                  \
+	ADDQ  h0, t2;                  \
+	ADCQ  $0, t3;                  \
+	                               \
+	MOVQ  t0, h0;                  \
+	MOVQ  t1, h1;                  \
+	MOVQ  t2, h2;                  \
+	ANDQ  $3, h2;                  \
+	MOVQ  t2, t0;                  \
+	ANDQ  $0xFFFFFFFFFFFFFFFC, t0; \
+	ADDQ  t0, h0;                  \
+	ADCQ  t3, h1;                  \
+	ADCQ  $0, h2;                  \
+	SHRQ  $2, t3, t2;              \
+	SHRQ  $2, t3;                  \
+	ADDQ  t2, h0;                  \
+	ADCQ  t3, h1;                  \
+	ADCQ  $0, h2
+
+DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF
+DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC
+GLOBL ·poly1305Mask<>(SB), RODATA, $16
+
+// func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]key)
+TEXT ·poly1305(SB), $0-32
+	MOVQ out+0(FP), DI
+	MOVQ m+8(FP), SI
+	MOVQ mlen+16(FP), R15
+	MOVQ key+24(FP), AX
+
+	MOVQ 0(AX), R11
+	MOVQ 8(AX), R12
+	ANDQ ·poly1305Mask<>(SB), R11   // r0
+	ANDQ ·poly1305Mask<>+8(SB), R12 // r1
+	XORQ R8, R8                    // h0
+	XORQ R9, R9                    // h1
+	XORQ R10, R10                  // h2
+
+	CMPQ R15, $16
+	JB   bytes_between_0_and_15
+
+loop:
+	POLY1305_ADD(SI, R8, R9, R10)
+
+multiply:
+	POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14)
+	SUBQ $16, R15
+	CMPQ R15, $16
+	JAE  loop
+
+bytes_between_0_and_15:
+	TESTQ R15, R15
+	JZ    done
+	MOVQ  $1, BX
+	XORQ  CX, CX
+	XORQ  R13, R13
+	ADDQ  R15, SI
+
+flush_buffer:
+	SHLQ $8, BX, CX
+	SHLQ $8, BX
+	MOVB -1(SI), R13
+	XORQ R13, BX
+	DECQ SI
+	DECQ R15
+	JNZ  flush_buffer
+
+	ADDQ BX, R8
+	ADCQ CX, R9
+	ADCQ $0, R10
+	MOVQ $16, R15
+	JMP  multiply
+
+done:
+	MOVQ    R8, AX
+	MOVQ    R9, BX
+	SUBQ    $0xFFFFFFFFFFFFFFFB, AX
+	SBBQ    $0xFFFFFFFFFFFFFFFF, BX
+	SBBQ    $3, R10
+	CMOVQCS R8, AX
+	CMOVQCS R9, BX
+	MOVQ    key+24(FP), R8
+	ADDQ    16(R8), AX
+	ADCQ    24(R8), BX
+
+	MOVQ AX, 0(DI)
+	MOVQ BX, 8(DI)
+	RET
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_arm.go b/vendor/golang.org/x/crypto/poly1305/sum_arm.go
index 50b979c..5dc321c 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_arm.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_arm.go
@@ -2,14 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build arm,!gccgo,!appengine
+// +build arm,!gccgo,!appengine,!nacl
 
 package poly1305
 
-// This function is implemented in poly1305_arm.s
-
+// This function is implemented in sum_arm.s
 //go:noescape
-
 func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte)
 
 // Sum generates an authenticator for m using a one-time key and puts the
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_arm.s b/vendor/golang.org/x/crypto/poly1305/sum_arm.s
new file mode 100644
index 0000000..f70b4ac
--- /dev/null
+++ b/vendor/golang.org/x/crypto/poly1305/sum_arm.s
@@ -0,0 +1,427 @@
+// 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.
+
+// +build arm,!gccgo,!appengine,!nacl
+
+#include "textflag.h"
+
+// This code was translated into a form compatible with 5a from the public
+// domain source by Andrew Moon: github.com/floodyberry/poly1305-opt/blob/master/app/extensions/poly1305.
+
+DATA ·poly1305_init_constants_armv6<>+0x00(SB)/4, $0x3ffffff
+DATA ·poly1305_init_constants_armv6<>+0x04(SB)/4, $0x3ffff03
+DATA ·poly1305_init_constants_armv6<>+0x08(SB)/4, $0x3ffc0ff
+DATA ·poly1305_init_constants_armv6<>+0x0c(SB)/4, $0x3f03fff
+DATA ·poly1305_init_constants_armv6<>+0x10(SB)/4, $0x00fffff
+GLOBL ·poly1305_init_constants_armv6<>(SB), 8, $20
+
+// Warning: the linker may use R11 to synthesize certain instructions. Please
+// take care and verify that no synthetic instructions use it.
+
+TEXT poly1305_init_ext_armv6<>(SB), NOSPLIT, $0
+	// Needs 16 bytes of stack and 64 bytes of space pointed to by R0.  (It
+	// might look like it's only 60 bytes of space but the final four bytes
+	// will be written by another function.) We need to skip over four
+	// bytes of stack because that's saving the value of 'g'.
+	ADD       $4, R13, R8
+	MOVM.IB   [R4-R7], (R8)
+	MOVM.IA.W (R1), [R2-R5]
+	MOVW      $·poly1305_init_constants_armv6<>(SB), R7
+	MOVW      R2, R8
+	MOVW      R2>>26, R9
+	MOVW      R3>>20, g
+	MOVW      R4>>14, R11
+	MOVW      R5>>8, R12
+	ORR       R3<<6, R9, R9
+	ORR       R4<<12, g, g
+	ORR       R5<<18, R11, R11
+	MOVM.IA   (R7), [R2-R6]
+	AND       R8, R2, R2
+	AND       R9, R3, R3
+	AND       g, R4, R4
+	AND       R11, R5, R5
+	AND       R12, R6, R6
+	MOVM.IA.W [R2-R6], (R0)
+	EOR       R2, R2, R2
+	EOR       R3, R3, R3
+	EOR       R4, R4, R4
+	EOR       R5, R5, R5
+	EOR       R6, R6, R6
+	MOVM.IA.W [R2-R6], (R0)
+	MOVM.IA.W (R1), [R2-R5]
+	MOVM.IA   [R2-R6], (R0)
+	ADD       $20, R13, R0
+	MOVM.DA   (R0), [R4-R7]
+	RET
+
+#define MOVW_UNALIGNED(Rsrc, Rdst, Rtmp, offset) \
+	MOVBU (offset+0)(Rsrc), Rtmp; \
+	MOVBU Rtmp, (offset+0)(Rdst); \
+	MOVBU (offset+1)(Rsrc), Rtmp; \
+	MOVBU Rtmp, (offset+1)(Rdst); \
+	MOVBU (offset+2)(Rsrc), Rtmp; \
+	MOVBU Rtmp, (offset+2)(Rdst); \
+	MOVBU (offset+3)(Rsrc), Rtmp; \
+	MOVBU Rtmp, (offset+3)(Rdst)
+
+TEXT poly1305_blocks_armv6<>(SB), NOSPLIT, $0
+	// Needs 24 bytes of stack for saved registers and then 88 bytes of
+	// scratch space after that. We assume that 24 bytes at (R13) have
+	// already been used: four bytes for the link register saved in the
+	// prelude of poly1305_auth_armv6, four bytes for saving the value of g
+	// in that function and 16 bytes of scratch space used around
+	// poly1305_finish_ext_armv6_skip1.
+	ADD     $24, R13, R12
+	MOVM.IB [R4-R8, R14], (R12)
+	MOVW    R0, 88(R13)
+	MOVW    R1, 92(R13)
+	MOVW    R2, 96(R13)
+	MOVW    R1, R14
+	MOVW    R2, R12
+	MOVW    56(R0), R8
+	WORD    $0xe1180008                // TST R8, R8 not working see issue 5921
+	EOR     R6, R6, R6
+	MOVW.EQ $(1<<24), R6
+	MOVW    R6, 84(R13)
+	ADD     $116, R13, g
+	MOVM.IA (R0), [R0-R9]
+	MOVM.IA [R0-R4], (g)
+	CMP     $16, R12
+	BLO     poly1305_blocks_armv6_done
+
+poly1305_blocks_armv6_mainloop:
+	WORD    $0xe31e0003                            // TST R14, #3 not working see issue 5921
+	BEQ     poly1305_blocks_armv6_mainloop_aligned
+	ADD     $100, R13, g
+	MOVW_UNALIGNED(R14, g, R0, 0)
+	MOVW_UNALIGNED(R14, g, R0, 4)
+	MOVW_UNALIGNED(R14, g, R0, 8)
+	MOVW_UNALIGNED(R14, g, R0, 12)
+	MOVM.IA (g), [R0-R3]
+	ADD     $16, R14
+	B       poly1305_blocks_armv6_mainloop_loaded
+
+poly1305_blocks_armv6_mainloop_aligned:
+	MOVM.IA.W (R14), [R0-R3]
+
+poly1305_blocks_armv6_mainloop_loaded:
+	MOVW    R0>>26, g
+	MOVW    R1>>20, R11
+	MOVW    R2>>14, R12
+	MOVW    R14, 92(R13)
+	MOVW    R3>>8, R4
+	ORR     R1<<6, g, g
+	ORR     R2<<12, R11, R11
+	ORR     R3<<18, R12, R12
+	BIC     $0xfc000000, R0, R0
+	BIC     $0xfc000000, g, g
+	MOVW    84(R13), R3
+	BIC     $0xfc000000, R11, R11
+	BIC     $0xfc000000, R12, R12
+	ADD     R0, R5, R5
+	ADD     g, R6, R6
+	ORR     R3, R4, R4
+	ADD     R11, R7, R7
+	ADD     $116, R13, R14
+	ADD     R12, R8, R8
+	ADD     R4, R9, R9
+	MOVM.IA (R14), [R0-R4]
+	MULLU   R4, R5, (R11, g)
+	MULLU   R3, R5, (R14, R12)
+	MULALU  R3, R6, (R11, g)
+	MULALU  R2, R6, (R14, R12)
+	MULALU  R2, R7, (R11, g)
+	MULALU  R1, R7, (R14, R12)
+	ADD     R4<<2, R4, R4
+	ADD     R3<<2, R3, R3
+	MULALU  R1, R8, (R11, g)
+	MULALU  R0, R8, (R14, R12)
+	MULALU  R0, R9, (R11, g)
+	MULALU  R4, R9, (R14, R12)
+	MOVW    g, 76(R13)
+	MOVW    R11, 80(R13)
+	MOVW    R12, 68(R13)
+	MOVW    R14, 72(R13)
+	MULLU   R2, R5, (R11, g)
+	MULLU   R1, R5, (R14, R12)
+	MULALU  R1, R6, (R11, g)
+	MULALU  R0, R6, (R14, R12)
+	MULALU  R0, R7, (R11, g)
+	MULALU  R4, R7, (R14, R12)
+	ADD     R2<<2, R2, R2
+	ADD     R1<<2, R1, R1
+	MULALU  R4, R8, (R11, g)
+	MULALU  R3, R8, (R14, R12)
+	MULALU  R3, R9, (R11, g)
+	MULALU  R2, R9, (R14, R12)
+	MOVW    g, 60(R13)
+	MOVW    R11, 64(R13)
+	MOVW    R12, 52(R13)
+	MOVW    R14, 56(R13)
+	MULLU   R0, R5, (R11, g)
+	MULALU  R4, R6, (R11, g)
+	MULALU  R3, R7, (R11, g)
+	MULALU  R2, R8, (R11, g)
+	MULALU  R1, R9, (R11, g)
+	ADD     $52, R13, R0
+	MOVM.IA (R0), [R0-R7]
+	MOVW    g>>26, R12
+	MOVW    R4>>26, R14
+	ORR     R11<<6, R12, R12
+	ORR     R5<<6, R14, R14
+	BIC     $0xfc000000, g, g
+	BIC     $0xfc000000, R4, R4
+	ADD.S   R12, R0, R0
+	ADC     $0, R1, R1
+	ADD.S   R14, R6, R6
+	ADC     $0, R7, R7
+	MOVW    R0>>26, R12
+	MOVW    R6>>26, R14
+	ORR     R1<<6, R12, R12
+	ORR     R7<<6, R14, R14
+	BIC     $0xfc000000, R0, R0
+	BIC     $0xfc000000, R6, R6
+	ADD     R14<<2, R14, R14
+	ADD.S   R12, R2, R2
+	ADC     $0, R3, R3
+	ADD     R14, g, g
+	MOVW    R2>>26, R12
+	MOVW    g>>26, R14
+	ORR     R3<<6, R12, R12
+	BIC     $0xfc000000, g, R5
+	BIC     $0xfc000000, R2, R7
+	ADD     R12, R4, R4
+	ADD     R14, R0, R0
+	MOVW    R4>>26, R12
+	BIC     $0xfc000000, R4, R8
+	ADD     R12, R6, R9
+	MOVW    96(R13), R12
+	MOVW    92(R13), R14
+	MOVW    R0, R6
+	CMP     $32, R12
+	SUB     $16, R12, R12
+	MOVW    R12, 96(R13)
+	BHS     poly1305_blocks_armv6_mainloop
+
+poly1305_blocks_armv6_done:
+	MOVW    88(R13), R12
+	MOVW    R5, 20(R12)
+	MOVW    R6, 24(R12)
+	MOVW    R7, 28(R12)
+	MOVW    R8, 32(R12)
+	MOVW    R9, 36(R12)
+	ADD     $48, R13, R0
+	MOVM.DA (R0), [R4-R8, R14]
+	RET
+
+#define MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp) \
+	MOVBU.P 1(Rsrc), Rtmp; \
+	MOVBU.P Rtmp, 1(Rdst); \
+	MOVBU.P 1(Rsrc), Rtmp; \
+	MOVBU.P Rtmp, 1(Rdst)
+
+#define MOVWP_UNALIGNED(Rsrc, Rdst, Rtmp) \
+	MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp); \
+	MOVHUP_UNALIGNED(Rsrc, Rdst, Rtmp)
+
+// func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]key)
+TEXT ·poly1305_auth_armv6(SB), $196-16
+	// The value 196, just above, is the sum of 64 (the size of the context
+	// structure) and 132 (the amount of stack needed).
+	//
+	// At this point, the stack pointer (R13) has been moved down. It
+	// points to the saved link register and there's 196 bytes of free
+	// space above it.
+	//
+	// The stack for this function looks like:
+	//
+	// +---------------------
+	// |
+	// | 64 bytes of context structure
+	// |
+	// +---------------------
+	// |
+	// | 112 bytes for poly1305_blocks_armv6
+	// |
+	// +---------------------
+	// | 16 bytes of final block, constructed at
+	// | poly1305_finish_ext_armv6_skip8
+	// +---------------------
+	// | four bytes of saved 'g'
+	// +---------------------
+	// | lr, saved by prelude    <- R13 points here
+	// +---------------------
+	MOVW g, 4(R13)
+
+	MOVW out+0(FP), R4
+	MOVW m+4(FP), R5
+	MOVW mlen+8(FP), R6
+	MOVW key+12(FP), R7
+
+	ADD  $136, R13, R0 // 136 = 4 + 4 + 16 + 112
+	MOVW R7, R1
+
+	// poly1305_init_ext_armv6 will write to the stack from R13+4, but
+	// that's ok because none of the other values have been written yet.
+	BL    poly1305_init_ext_armv6<>(SB)
+	BIC.S $15, R6, R2
+	BEQ   poly1305_auth_armv6_noblocks
+	ADD   $136, R13, R0
+	MOVW  R5, R1
+	ADD   R2, R5, R5
+	SUB   R2, R6, R6
+	BL    poly1305_blocks_armv6<>(SB)
+
+poly1305_auth_armv6_noblocks:
+	ADD  $136, R13, R0
+	MOVW R5, R1
+	MOVW R6, R2
+	MOVW R4, R3
+
+	MOVW  R0, R5
+	MOVW  R1, R6
+	MOVW  R2, R7
+	MOVW  R3, R8
+	AND.S R2, R2, R2
+	BEQ   poly1305_finish_ext_armv6_noremaining
+	EOR   R0, R0
+	ADD   $8, R13, R9                           // 8 = offset to 16 byte scratch space
+	MOVW  R0, (R9)
+	MOVW  R0, 4(R9)
+	MOVW  R0, 8(R9)
+	MOVW  R0, 12(R9)
+	WORD  $0xe3110003                           // TST R1, #3 not working see issue 5921
+	BEQ   poly1305_finish_ext_armv6_aligned
+	WORD  $0xe3120008                           // TST R2, #8 not working see issue 5921
+	BEQ   poly1305_finish_ext_armv6_skip8
+	MOVWP_UNALIGNED(R1, R9, g)
+	MOVWP_UNALIGNED(R1, R9, g)
+
+poly1305_finish_ext_armv6_skip8:
+	WORD $0xe3120004                     // TST $4, R2 not working see issue 5921
+	BEQ  poly1305_finish_ext_armv6_skip4
+	MOVWP_UNALIGNED(R1, R9, g)
+
+poly1305_finish_ext_armv6_skip4:
+	WORD $0xe3120002                     // TST $2, R2 not working see issue 5921
+	BEQ  poly1305_finish_ext_armv6_skip2
+	MOVHUP_UNALIGNED(R1, R9, g)
+	B    poly1305_finish_ext_armv6_skip2
+
+poly1305_finish_ext_armv6_aligned:
+	WORD      $0xe3120008                             // TST R2, #8 not working see issue 5921
+	BEQ       poly1305_finish_ext_armv6_skip8_aligned
+	MOVM.IA.W (R1), [g-R11]
+	MOVM.IA.W [g-R11], (R9)
+
+poly1305_finish_ext_armv6_skip8_aligned:
+	WORD   $0xe3120004                             // TST $4, R2 not working see issue 5921
+	BEQ    poly1305_finish_ext_armv6_skip4_aligned
+	MOVW.P 4(R1), g
+	MOVW.P g, 4(R9)
+
+poly1305_finish_ext_armv6_skip4_aligned:
+	WORD    $0xe3120002                     // TST $2, R2 not working see issue 5921
+	BEQ     poly1305_finish_ext_armv6_skip2
+	MOVHU.P 2(R1), g
+	MOVH.P  g, 2(R9)
+
+poly1305_finish_ext_armv6_skip2:
+	WORD    $0xe3120001                     // TST $1, R2 not working see issue 5921
+	BEQ     poly1305_finish_ext_armv6_skip1
+	MOVBU.P 1(R1), g
+	MOVBU.P g, 1(R9)
+
+poly1305_finish_ext_armv6_skip1:
+	MOVW  $1, R11
+	MOVBU R11, 0(R9)
+	MOVW  R11, 56(R5)
+	MOVW  R5, R0
+	ADD   $8, R13, R1
+	MOVW  $16, R2
+	BL    poly1305_blocks_armv6<>(SB)
+
+poly1305_finish_ext_armv6_noremaining:
+	MOVW      20(R5), R0
+	MOVW      24(R5), R1
+	MOVW      28(R5), R2
+	MOVW      32(R5), R3
+	MOVW      36(R5), R4
+	MOVW      R4>>26, R12
+	BIC       $0xfc000000, R4, R4
+	ADD       R12<<2, R12, R12
+	ADD       R12, R0, R0
+	MOVW      R0>>26, R12
+	BIC       $0xfc000000, R0, R0
+	ADD       R12, R1, R1
+	MOVW      R1>>26, R12
+	BIC       $0xfc000000, R1, R1
+	ADD       R12, R2, R2
+	MOVW      R2>>26, R12
+	BIC       $0xfc000000, R2, R2
+	ADD       R12, R3, R3
+	MOVW      R3>>26, R12
+	BIC       $0xfc000000, R3, R3
+	ADD       R12, R4, R4
+	ADD       $5, R0, R6
+	MOVW      R6>>26, R12
+	BIC       $0xfc000000, R6, R6
+	ADD       R12, R1, R7
+	MOVW      R7>>26, R12
+	BIC       $0xfc000000, R7, R7
+	ADD       R12, R2, g
+	MOVW      g>>26, R12
+	BIC       $0xfc000000, g, g
+	ADD       R12, R3, R11
+	MOVW      $-(1<<26), R12
+	ADD       R11>>26, R12, R12
+	BIC       $0xfc000000, R11, R11
+	ADD       R12, R4, R9
+	MOVW      R9>>31, R12
+	SUB       $1, R12
+	AND       R12, R6, R6
+	AND       R12, R7, R7
+	AND       R12, g, g
+	AND       R12, R11, R11
+	AND       R12, R9, R9
+	MVN       R12, R12
+	AND       R12, R0, R0
+	AND       R12, R1, R1
+	AND       R12, R2, R2
+	AND       R12, R3, R3
+	AND       R12, R4, R4
+	ORR       R6, R0, R0
+	ORR       R7, R1, R1
+	ORR       g, R2, R2
+	ORR       R11, R3, R3
+	ORR       R9, R4, R4
+	ORR       R1<<26, R0, R0
+	MOVW      R1>>6, R1
+	ORR       R2<<20, R1, R1
+	MOVW      R2>>12, R2
+	ORR       R3<<14, R2, R2
+	MOVW      R3>>18, R3
+	ORR       R4<<8, R3, R3
+	MOVW      40(R5), R6
+	MOVW      44(R5), R7
+	MOVW      48(R5), g
+	MOVW      52(R5), R11
+	ADD.S     R6, R0, R0
+	ADC.S     R7, R1, R1
+	ADC.S     g, R2, R2
+	ADC.S     R11, R3, R3
+	MOVM.IA   [R0-R3], (R8)
+	MOVW      R5, R12
+	EOR       R0, R0, R0
+	EOR       R1, R1, R1
+	EOR       R2, R2, R2
+	EOR       R3, R3, R3
+	EOR       R4, R4, R4
+	EOR       R5, R5, R5
+	EOR       R6, R6, R6
+	EOR       R7, R7, R7
+	MOVM.IA.W [R0-R7], (R12)
+	MOVM.IA   [R0-R7], (R12)
+	MOVW      4(R13), g
+	RET
diff --git a/vendor/golang.org/x/crypto/poly1305/sum_ref.go b/vendor/golang.org/x/crypto/poly1305/sum_ref.go
index 0b24fc7..b2805a5 100644
--- a/vendor/golang.org/x/crypto/poly1305/sum_ref.go
+++ b/vendor/golang.org/x/crypto/poly1305/sum_ref.go
@@ -2,1530 +2,140 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!arm gccgo appengine
+// +build !amd64,!arm gccgo appengine nacl
 
 package poly1305
 
-// Based on original, public domain implementation from NaCl by D. J.
-// Bernstein.
+import "encoding/binary"
 
-import "math"
-
-const (
-	alpham80 = 0.00000000558793544769287109375
-	alpham48 = 24.0
-	alpham16 = 103079215104.0
-	alpha0   = 6755399441055744.0
-	alpha18  = 1770887431076116955136.0
-	alpha32  = 29014219670751100192948224.0
-	alpha50  = 7605903601369376408980219232256.0
-	alpha64  = 124615124604835863084731911901282304.0
-	alpha82  = 32667107224410092492483962313449748299776.0
-	alpha96  = 535217884764734955396857238543560676143529984.0
-	alpha112 = 35076039295941670036888435985190792471742381031424.0
-	alpha130 = 9194973245195333150150082162901855101712434733101613056.0
-	scale    = 0.0000000000000000000000000000000000000036734198463196484624023016788195177431833298649127735047148490821200539357960224151611328125
-	offset0  = 6755408030990331.0
-	offset1  = 29014256564239239022116864.0
-	offset2  = 124615283061160854719918951570079744.0
-	offset3  = 535219245894202480694386063513315216128475136.0
-)
-
-// Sum generates an authenticator for m using a one-time key and puts the
+// Sum generates an authenticator for msg using a one-time key and puts the
 // 16-byte result into out. Authenticating two different messages with the same
 // key allows an attacker to forge messages at will.
-func Sum(out *[16]byte, m []byte, key *[32]byte) {
-	r := key
-	s := key[16:]
+func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) {
 	var (
-		y7        float64
-		y6        float64
-		y1        float64
-		y0        float64
-		y5        float64
-		y4        float64
-		x7        float64
-		x6        float64
-		x1        float64
-		x0        float64
-		y3        float64
-		y2        float64
-		x5        float64
-		r3lowx0   float64
-		x4        float64
-		r0lowx6   float64
-		x3        float64
-		r3highx0  float64
-		x2        float64
-		r0highx6  float64
-		r0lowx0   float64
-		sr1lowx6  float64
-		r0highx0  float64
-		sr1highx6 float64
-		sr3low    float64
-		r1lowx0   float64
-		sr2lowx6  float64
-		r1highx0  float64
-		sr2highx6 float64
-		r2lowx0   float64
-		sr3lowx6  float64
-		r2highx0  float64
-		sr3highx6 float64
-		r1highx4  float64
-		r1lowx4   float64
-		r0highx4  float64
-		r0lowx4   float64
-		sr3highx4 float64
-		sr3lowx4  float64
-		sr2highx4 float64
-		sr2lowx4  float64
-		r0lowx2   float64
-		r0highx2  float64
-		r1lowx2   float64
-		r1highx2  float64
-		r2lowx2   float64
-		r2highx2  float64
-		sr3lowx2  float64
-		sr3highx2 float64
-		z0        float64
-		z1        float64
-		z2        float64
-		z3        float64
-		m0        int64
-		m1        int64
-		m2        int64
-		m3        int64
-		m00       uint32
-		m01       uint32
-		m02       uint32
-		m03       uint32
-		m10       uint32
-		m11       uint32
-		m12       uint32
-		m13       uint32
-		m20       uint32
-		m21       uint32
-		m22       uint32
-		m23       uint32
-		m30       uint32
-		m31       uint32
-		m32       uint32
-		m33       uint64
-		lbelow2   int32
-		lbelow3   int32
-		lbelow4   int32
-		lbelow5   int32
-		lbelow6   int32
-		lbelow7   int32
-		lbelow8   int32
-		lbelow9   int32
-		lbelow10  int32
-		lbelow11  int32
-		lbelow12  int32
-		lbelow13  int32
-		lbelow14  int32
-		lbelow15  int32
-		s00       uint32
-		s01       uint32
-		s02       uint32
-		s03       uint32
-		s10       uint32
-		s11       uint32
-		s12       uint32
-		s13       uint32
-		s20       uint32
-		s21       uint32
-		s22       uint32
-		s23       uint32
-		s30       uint32
-		s31       uint32
-		s32       uint32
-		s33       uint32
-		bits32    uint64
-		f         uint64
-		f0        uint64
-		f1        uint64
-		f2        uint64
-		f3        uint64
-		f4        uint64
-		g         uint64
-		g0        uint64
-		g1        uint64
-		g2        uint64
-		g3        uint64
-		g4        uint64
+		h0, h1, h2, h3, h4 uint32 // the hash accumulators
+		r0, r1, r2, r3, r4 uint64 // the r part of the key
 	)
 
-	var p int32
+	r0 = uint64(binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff)
+	r1 = uint64((binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03)
+	r2 = uint64((binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff)
+	r3 = uint64((binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff)
+	r4 = uint64((binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff)
 
-	l := int32(len(m))
+	R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5
 
-	r00 := uint32(r[0])
+	for len(msg) >= TagSize {
+		// h += msg
+		h0 += binary.LittleEndian.Uint32(msg[0:]) & 0x3ffffff
+		h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff
+		h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff
+		h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff
+		h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | (1 << 24)
 
-	r01 := uint32(r[1])
+		// h *= r
+		d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
+		d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
+		d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
+		d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
+		d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
 
-	r02 := uint32(r[2])
-	r0 := int64(2151)
+		// h %= p
+		h0 = uint32(d0) & 0x3ffffff
+		h1 = uint32(d1) & 0x3ffffff
+		h2 = uint32(d2) & 0x3ffffff
+		h3 = uint32(d3) & 0x3ffffff
+		h4 = uint32(d4) & 0x3ffffff
 
-	r03 := uint32(r[3])
-	r03 &= 15
-	r0 <<= 51
+		h0 += uint32(d4>>26) * 5
+		h1 += h0 >> 26
+		h0 = h0 & 0x3ffffff
 
-	r10 := uint32(r[4])
-	r10 &= 252
-	r01 <<= 8
-	r0 += int64(r00)
-
-	r11 := uint32(r[5])
-	r02 <<= 16
-	r0 += int64(r01)
-
-	r12 := uint32(r[6])
-	r03 <<= 24
-	r0 += int64(r02)
-
-	r13 := uint32(r[7])
-	r13 &= 15
-	r1 := int64(2215)
-	r0 += int64(r03)
-
-	d0 := r0
-	r1 <<= 51
-	r2 := int64(2279)
-
-	r20 := uint32(r[8])
-	r20 &= 252
-	r11 <<= 8
-	r1 += int64(r10)
-
-	r21 := uint32(r[9])
-	r12 <<= 16
-	r1 += int64(r11)
-
-	r22 := uint32(r[10])
-	r13 <<= 24
-	r1 += int64(r12)
-
-	r23 := uint32(r[11])
-	r23 &= 15
-	r2 <<= 51
-	r1 += int64(r13)
-
-	d1 := r1
-	r21 <<= 8
-	r2 += int64(r20)
-
-	r30 := uint32(r[12])
-	r30 &= 252
-	r22 <<= 16
-	r2 += int64(r21)
-
-	r31 := uint32(r[13])
-	r23 <<= 24
-	r2 += int64(r22)
-
-	r32 := uint32(r[14])
-	r2 += int64(r23)
-	r3 := int64(2343)
-
-	d2 := r2
-	r3 <<= 51
-
-	r33 := uint32(r[15])
-	r33 &= 15
-	r31 <<= 8
-	r3 += int64(r30)
-
-	r32 <<= 16
-	r3 += int64(r31)
-
-	r33 <<= 24
-	r3 += int64(r32)
-
-	r3 += int64(r33)
-	h0 := alpha32 - alpha32
-
-	d3 := r3
-	h1 := alpha32 - alpha32
-
-	h2 := alpha32 - alpha32
-
-	h3 := alpha32 - alpha32
-
-	h4 := alpha32 - alpha32
-
-	r0low := math.Float64frombits(uint64(d0))
-	h5 := alpha32 - alpha32
-
-	r1low := math.Float64frombits(uint64(d1))
-	h6 := alpha32 - alpha32
-
-	r2low := math.Float64frombits(uint64(d2))
-	h7 := alpha32 - alpha32
-
-	r0low -= alpha0
-
-	r1low -= alpha32
-
-	r2low -= alpha64
-
-	r0high := r0low + alpha18
-
-	r3low := math.Float64frombits(uint64(d3))
-
-	r1high := r1low + alpha50
-	sr1low := scale * r1low
-
-	r2high := r2low + alpha82
-	sr2low := scale * r2low
-
-	r0high -= alpha18
-	r0high_stack := r0high
-
-	r3low -= alpha96
-
-	r1high -= alpha50
-	r1high_stack := r1high
-
-	sr1high := sr1low + alpham80
-
-	r0low -= r0high
-
-	r2high -= alpha82
-	sr3low = scale * r3low
-
-	sr2high := sr2low + alpham48
-
-	r1low -= r1high
-	r1low_stack := r1low
-
-	sr1high -= alpham80
-	sr1high_stack := sr1high
-
-	r2low -= r2high
-	r2low_stack := r2low
-
-	sr2high -= alpham48
-	sr2high_stack := sr2high
-
-	r3high := r3low + alpha112
-	r0low_stack := r0low
-
-	sr1low -= sr1high
-	sr1low_stack := sr1low
-
-	sr3high := sr3low + alpham16
-	r2high_stack := r2high
-
-	sr2low -= sr2high
-	sr2low_stack := sr2low
-
-	r3high -= alpha112
-	r3high_stack := r3high
-
-	sr3high -= alpham16
-	sr3high_stack := sr3high
-
-	r3low -= r3high
-	r3low_stack := r3low
-
-	sr3low -= sr3high
-	sr3low_stack := sr3low
-
-	if l < 16 {
-		goto addatmost15bytes
+		msg = msg[TagSize:]
 	}
 
-	m00 = uint32(m[p+0])
-	m0 = 2151
+	if len(msg) > 0 {
+		var block [TagSize]byte
+		off := copy(block[:], msg)
+		block[off] = 0x01
 
-	m0 <<= 51
-	m1 = 2215
-	m01 = uint32(m[p+1])
+		// h += msg
+		h0 += binary.LittleEndian.Uint32(block[0:]) & 0x3ffffff
+		h1 += (binary.LittleEndian.Uint32(block[3:]) >> 2) & 0x3ffffff
+		h2 += (binary.LittleEndian.Uint32(block[6:]) >> 4) & 0x3ffffff
+		h3 += (binary.LittleEndian.Uint32(block[9:]) >> 6) & 0x3ffffff
+		h4 += (binary.LittleEndian.Uint32(block[12:]) >> 8)
 
-	m1 <<= 51
-	m2 = 2279
-	m02 = uint32(m[p+2])
+		// h *= r
+		d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1)
+		d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2)
+		d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3)
+		d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4)
+		d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0)
 
-	m2 <<= 51
-	m3 = 2343
-	m03 = uint32(m[p+3])
+		// h %= p
+		h0 = uint32(d0) & 0x3ffffff
+		h1 = uint32(d1) & 0x3ffffff
+		h2 = uint32(d2) & 0x3ffffff
+		h3 = uint32(d3) & 0x3ffffff
+		h4 = uint32(d4) & 0x3ffffff
 
-	m10 = uint32(m[p+4])
-	m01 <<= 8
-	m0 += int64(m00)
-
-	m11 = uint32(m[p+5])
-	m02 <<= 16
-	m0 += int64(m01)
-
-	m12 = uint32(m[p+6])
-	m03 <<= 24
-	m0 += int64(m02)
-
-	m13 = uint32(m[p+7])
-	m3 <<= 51
-	m0 += int64(m03)
-
-	m20 = uint32(m[p+8])
-	m11 <<= 8
-	m1 += int64(m10)
-
-	m21 = uint32(m[p+9])
-	m12 <<= 16
-	m1 += int64(m11)
-
-	m22 = uint32(m[p+10])
-	m13 <<= 24
-	m1 += int64(m12)
-
-	m23 = uint32(m[p+11])
-	m1 += int64(m13)
-
-	m30 = uint32(m[p+12])
-	m21 <<= 8
-	m2 += int64(m20)
-
-	m31 = uint32(m[p+13])
-	m22 <<= 16
-	m2 += int64(m21)
-
-	m32 = uint32(m[p+14])
-	m23 <<= 24
-	m2 += int64(m22)
-
-	m33 = uint64(m[p+15])
-	m2 += int64(m23)
-
-	d0 = m0
-	m31 <<= 8
-	m3 += int64(m30)
-
-	d1 = m1
-	m32 <<= 16
-	m3 += int64(m31)
-
-	d2 = m2
-	m33 += 256
-
-	m33 <<= 24
-	m3 += int64(m32)
-
-	m3 += int64(m33)
-	d3 = m3
-
-	p += 16
-	l -= 16
-
-	z0 = math.Float64frombits(uint64(d0))
-
-	z1 = math.Float64frombits(uint64(d1))
-
-	z2 = math.Float64frombits(uint64(d2))
-
-	z3 = math.Float64frombits(uint64(d3))
-
-	z0 -= alpha0
-
-	z1 -= alpha32
-
-	z2 -= alpha64
-
-	z3 -= alpha96
-
-	h0 += z0
-
-	h1 += z1
-
-	h3 += z2
-
-	h5 += z3
-
-	if l < 16 {
-		goto multiplyaddatmost15bytes
+		h0 += uint32(d4>>26) * 5
+		h1 += h0 >> 26
+		h0 = h0 & 0x3ffffff
 	}
 
-multiplyaddatleast16bytes:
+	// h %= p reduction
+	h2 += h1 >> 26
+	h1 &= 0x3ffffff
+	h3 += h2 >> 26
+	h2 &= 0x3ffffff
+	h4 += h3 >> 26
+	h3 &= 0x3ffffff
+	h0 += 5 * (h4 >> 26)
+	h4 &= 0x3ffffff
+	h1 += h0 >> 26
+	h0 &= 0x3ffffff
 
-	m2 = 2279
-	m20 = uint32(m[p+8])
-	y7 = h7 + alpha130
+	// h - p
+	t0 := h0 + 5
+	t1 := h1 + (t0 >> 26)
+	t2 := h2 + (t1 >> 26)
+	t3 := h3 + (t2 >> 26)
+	t4 := h4 + (t3 >> 26) - (1 << 26)
+	t0 &= 0x3ffffff
+	t1 &= 0x3ffffff
+	t2 &= 0x3ffffff
+	t3 &= 0x3ffffff
 
-	m2 <<= 51
-	m3 = 2343
-	m21 = uint32(m[p+9])
-	y6 = h6 + alpha130
+	// select h if h < p else h - p
+	t_mask := (t4 >> 31) - 1
+	h_mask := ^t_mask
+	h0 = (h0 & h_mask) | (t0 & t_mask)
+	h1 = (h1 & h_mask) | (t1 & t_mask)
+	h2 = (h2 & h_mask) | (t2 & t_mask)
+	h3 = (h3 & h_mask) | (t3 & t_mask)
+	h4 = (h4 & h_mask) | (t4 & t_mask)
 
-	m3 <<= 51
-	m0 = 2151
-	m22 = uint32(m[p+10])
-	y1 = h1 + alpha32
+	// h %= 2^128
+	h0 |= h1 << 26
+	h1 = ((h1 >> 6) | (h2 << 20))
+	h2 = ((h2 >> 12) | (h3 << 14))
+	h3 = ((h3 >> 18) | (h4 << 8))
 
-	m0 <<= 51
-	m1 = 2215
-	m23 = uint32(m[p+11])
-	y0 = h0 + alpha32
+	// s: the s part of the key
+	// tag = (h + s) % (2^128)
+	t := uint64(h0) + uint64(binary.LittleEndian.Uint32(key[16:]))
+	h0 = uint32(t)
+	t = uint64(h1) + uint64(binary.LittleEndian.Uint32(key[20:])) + (t >> 32)
+	h1 = uint32(t)
+	t = uint64(h2) + uint64(binary.LittleEndian.Uint32(key[24:])) + (t >> 32)
+	h2 = uint32(t)
+	t = uint64(h3) + uint64(binary.LittleEndian.Uint32(key[28:])) + (t >> 32)
+	h3 = uint32(t)
 
-	m1 <<= 51
-	m30 = uint32(m[p+12])
-	y7 -= alpha130
-
-	m21 <<= 8
-	m2 += int64(m20)
-	m31 = uint32(m[p+13])
-	y6 -= alpha130
-
-	m22 <<= 16
-	m2 += int64(m21)
-	m32 = uint32(m[p+14])
-	y1 -= alpha32
-
-	m23 <<= 24
-	m2 += int64(m22)
-	m33 = uint64(m[p+15])
-	y0 -= alpha32
-
-	m2 += int64(m23)
-	m00 = uint32(m[p+0])
-	y5 = h5 + alpha96
-
-	m31 <<= 8
-	m3 += int64(m30)
-	m01 = uint32(m[p+1])
-	y4 = h4 + alpha96
-
-	m32 <<= 16
-	m02 = uint32(m[p+2])
-	x7 = h7 - y7
-	y7 *= scale
-
-	m33 += 256
-	m03 = uint32(m[p+3])
-	x6 = h6 - y6
-	y6 *= scale
-
-	m33 <<= 24
-	m3 += int64(m31)
-	m10 = uint32(m[p+4])
-	x1 = h1 - y1
-
-	m01 <<= 8
-	m3 += int64(m32)
-	m11 = uint32(m[p+5])
-	x0 = h0 - y0
-
-	m3 += int64(m33)
-	m0 += int64(m00)
-	m12 = uint32(m[p+6])
-	y5 -= alpha96
-
-	m02 <<= 16
-	m0 += int64(m01)
-	m13 = uint32(m[p+7])
-	y4 -= alpha96
-
-	m03 <<= 24
-	m0 += int64(m02)
-	d2 = m2
-	x1 += y7
-
-	m0 += int64(m03)
-	d3 = m3
-	x0 += y6
-
-	m11 <<= 8
-	m1 += int64(m10)
-	d0 = m0
-	x7 += y5
-
-	m12 <<= 16
-	m1 += int64(m11)
-	x6 += y4
-
-	m13 <<= 24
-	m1 += int64(m12)
-	y3 = h3 + alpha64
-
-	m1 += int64(m13)
-	d1 = m1
-	y2 = h2 + alpha64
-
-	x0 += x1
-
-	x6 += x7
-
-	y3 -= alpha64
-	r3low = r3low_stack
-
-	y2 -= alpha64
-	r0low = r0low_stack
-
-	x5 = h5 - y5
-	r3lowx0 = r3low * x0
-	r3high = r3high_stack
-
-	x4 = h4 - y4
-	r0lowx6 = r0low * x6
-	r0high = r0high_stack
-
-	x3 = h3 - y3
-	r3highx0 = r3high * x0
-	sr1low = sr1low_stack
-
-	x2 = h2 - y2
-	r0highx6 = r0high * x6
-	sr1high = sr1high_stack
-
-	x5 += y3
-	r0lowx0 = r0low * x0
-	r1low = r1low_stack
-
-	h6 = r3lowx0 + r0lowx6
-	sr1lowx6 = sr1low * x6
-	r1high = r1high_stack
-
-	x4 += y2
-	r0highx0 = r0high * x0
-	sr2low = sr2low_stack
-
-	h7 = r3highx0 + r0highx6
-	sr1highx6 = sr1high * x6
-	sr2high = sr2high_stack
-
-	x3 += y1
-	r1lowx0 = r1low * x0
-	r2low = r2low_stack
-
-	h0 = r0lowx0 + sr1lowx6
-	sr2lowx6 = sr2low * x6
-	r2high = r2high_stack
-
-	x2 += y0
-	r1highx0 = r1high * x0
-	sr3low = sr3low_stack
-
-	h1 = r0highx0 + sr1highx6
-	sr2highx6 = sr2high * x6
-	sr3high = sr3high_stack
-
-	x4 += x5
-	r2lowx0 = r2low * x0
-	z2 = math.Float64frombits(uint64(d2))
-
-	h2 = r1lowx0 + sr2lowx6
-	sr3lowx6 = sr3low * x6
-
-	x2 += x3
-	r2highx0 = r2high * x0
-	z3 = math.Float64frombits(uint64(d3))
-
-	h3 = r1highx0 + sr2highx6
-	sr3highx6 = sr3high * x6
-
-	r1highx4 = r1high * x4
-	z2 -= alpha64
-
-	h4 = r2lowx0 + sr3lowx6
-	r1lowx4 = r1low * x4
-
-	r0highx4 = r0high * x4
-	z3 -= alpha96
-
-	h5 = r2highx0 + sr3highx6
-	r0lowx4 = r0low * x4
-
-	h7 += r1highx4
-	sr3highx4 = sr3high * x4
-
-	h6 += r1lowx4
-	sr3lowx4 = sr3low * x4
-
-	h5 += r0highx4
-	sr2highx4 = sr2high * x4
-
-	h4 += r0lowx4
-	sr2lowx4 = sr2low * x4
-
-	h3 += sr3highx4
-	r0lowx2 = r0low * x2
-
-	h2 += sr3lowx4
-	r0highx2 = r0high * x2
-
-	h1 += sr2highx4
-	r1lowx2 = r1low * x2
-
-	h0 += sr2lowx4
-	r1highx2 = r1high * x2
-
-	h2 += r0lowx2
-	r2lowx2 = r2low * x2
-
-	h3 += r0highx2
-	r2highx2 = r2high * x2
-
-	h4 += r1lowx2
-	sr3lowx2 = sr3low * x2
-
-	h5 += r1highx2
-	sr3highx2 = sr3high * x2
-
-	p += 16
-	l -= 16
-	h6 += r2lowx2
-
-	h7 += r2highx2
-
-	z1 = math.Float64frombits(uint64(d1))
-	h0 += sr3lowx2
-
-	z0 = math.Float64frombits(uint64(d0))
-	h1 += sr3highx2
-
-	z1 -= alpha32
-
-	z0 -= alpha0
-
-	h5 += z3
-
-	h3 += z2
-
-	h1 += z1
-
-	h0 += z0
-
-	if l >= 16 {
-		goto multiplyaddatleast16bytes
-	}
-
-multiplyaddatmost15bytes:
-
-	y7 = h7 + alpha130
-
-	y6 = h6 + alpha130
-
-	y1 = h1 + alpha32
-
-	y0 = h0 + alpha32
-
-	y7 -= alpha130
-
-	y6 -= alpha130
-
-	y1 -= alpha32
-
-	y0 -= alpha32
-
-	y5 = h5 + alpha96
-
-	y4 = h4 + alpha96
-
-	x7 = h7 - y7
-	y7 *= scale
-
-	x6 = h6 - y6
-	y6 *= scale
-
-	x1 = h1 - y1
-
-	x0 = h0 - y0
-
-	y5 -= alpha96
-
-	y4 -= alpha96
-
-	x1 += y7
-
-	x0 += y6
-
-	x7 += y5
-
-	x6 += y4
-
-	y3 = h3 + alpha64
-
-	y2 = h2 + alpha64
-
-	x0 += x1
-
-	x6 += x7
-
-	y3 -= alpha64
-	r3low = r3low_stack
-
-	y2 -= alpha64
-	r0low = r0low_stack
-
-	x5 = h5 - y5
-	r3lowx0 = r3low * x0
-	r3high = r3high_stack
-
-	x4 = h4 - y4
-	r0lowx6 = r0low * x6
-	r0high = r0high_stack
-
-	x3 = h3 - y3
-	r3highx0 = r3high * x0
-	sr1low = sr1low_stack
-
-	x2 = h2 - y2
-	r0highx6 = r0high * x6
-	sr1high = sr1high_stack
-
-	x5 += y3
-	r0lowx0 = r0low * x0
-	r1low = r1low_stack
-
-	h6 = r3lowx0 + r0lowx6
-	sr1lowx6 = sr1low * x6
-	r1high = r1high_stack
-
-	x4 += y2
-	r0highx0 = r0high * x0
-	sr2low = sr2low_stack
-
-	h7 = r3highx0 + r0highx6
-	sr1highx6 = sr1high * x6
-	sr2high = sr2high_stack
-
-	x3 += y1
-	r1lowx0 = r1low * x0
-	r2low = r2low_stack
-
-	h0 = r0lowx0 + sr1lowx6
-	sr2lowx6 = sr2low * x6
-	r2high = r2high_stack
-
-	x2 += y0
-	r1highx0 = r1high * x0
-	sr3low = sr3low_stack
-
-	h1 = r0highx0 + sr1highx6
-	sr2highx6 = sr2high * x6
-	sr3high = sr3high_stack
-
-	x4 += x5
-	r2lowx0 = r2low * x0
-
-	h2 = r1lowx0 + sr2lowx6
-	sr3lowx6 = sr3low * x6
-
-	x2 += x3
-	r2highx0 = r2high * x0
-
-	h3 = r1highx0 + sr2highx6
-	sr3highx6 = sr3high * x6
-
-	r1highx4 = r1high * x4
-
-	h4 = r2lowx0 + sr3lowx6
-	r1lowx4 = r1low * x4
-
-	r0highx4 = r0high * x4
-
-	h5 = r2highx0 + sr3highx6
-	r0lowx4 = r0low * x4
-
-	h7 += r1highx4
-	sr3highx4 = sr3high * x4
-
-	h6 += r1lowx4
-	sr3lowx4 = sr3low * x4
-
-	h5 += r0highx4
-	sr2highx4 = sr2high * x4
-
-	h4 += r0lowx4
-	sr2lowx4 = sr2low * x4
-
-	h3 += sr3highx4
-	r0lowx2 = r0low * x2
-
-	h2 += sr3lowx4
-	r0highx2 = r0high * x2
-
-	h1 += sr2highx4
-	r1lowx2 = r1low * x2
-
-	h0 += sr2lowx4
-	r1highx2 = r1high * x2
-
-	h2 += r0lowx2
-	r2lowx2 = r2low * x2
-
-	h3 += r0highx2
-	r2highx2 = r2high * x2
-
-	h4 += r1lowx2
-	sr3lowx2 = sr3low * x2
-
-	h5 += r1highx2
-	sr3highx2 = sr3high * x2
-
-	h6 += r2lowx2
-
-	h7 += r2highx2
-
-	h0 += sr3lowx2
-
-	h1 += sr3highx2
-
-addatmost15bytes:
-
-	if l == 0 {
-		goto nomorebytes
-	}
-
-	lbelow2 = l - 2
-
-	lbelow3 = l - 3
-
-	lbelow2 >>= 31
-	lbelow4 = l - 4
-
-	m00 = uint32(m[p+0])
-	lbelow3 >>= 31
-	p += lbelow2
-
-	m01 = uint32(m[p+1])
-	lbelow4 >>= 31
-	p += lbelow3
-
-	m02 = uint32(m[p+2])
-	p += lbelow4
-	m0 = 2151
-
-	m03 = uint32(m[p+3])
-	m0 <<= 51
-	m1 = 2215
-
-	m0 += int64(m00)
-	m01 &^= uint32(lbelow2)
-
-	m02 &^= uint32(lbelow3)
-	m01 -= uint32(lbelow2)
-
-	m01 <<= 8
-	m03 &^= uint32(lbelow4)
-
-	m0 += int64(m01)
-	lbelow2 -= lbelow3
-
-	m02 += uint32(lbelow2)
-	lbelow3 -= lbelow4
-
-	m02 <<= 16
-	m03 += uint32(lbelow3)
-
-	m03 <<= 24
-	m0 += int64(m02)
-
-	m0 += int64(m03)
-	lbelow5 = l - 5
-
-	lbelow6 = l - 6
-	lbelow7 = l - 7
-
-	lbelow5 >>= 31
-	lbelow8 = l - 8
-
-	lbelow6 >>= 31
-	p += lbelow5
-
-	m10 = uint32(m[p+4])
-	lbelow7 >>= 31
-	p += lbelow6
-
-	m11 = uint32(m[p+5])
-	lbelow8 >>= 31
-	p += lbelow7
-
-	m12 = uint32(m[p+6])
-	m1 <<= 51
-	p += lbelow8
-
-	m13 = uint32(m[p+7])
-	m10 &^= uint32(lbelow5)
-	lbelow4 -= lbelow5
-
-	m10 += uint32(lbelow4)
-	lbelow5 -= lbelow6
-
-	m11 &^= uint32(lbelow6)
-	m11 += uint32(lbelow5)
-
-	m11 <<= 8
-	m1 += int64(m10)
-
-	m1 += int64(m11)
-	m12 &^= uint32(lbelow7)
-
-	lbelow6 -= lbelow7
-	m13 &^= uint32(lbelow8)
-
-	m12 += uint32(lbelow6)
-	lbelow7 -= lbelow8
-
-	m12 <<= 16
-	m13 += uint32(lbelow7)
-
-	m13 <<= 24
-	m1 += int64(m12)
-
-	m1 += int64(m13)
-	m2 = 2279
-
-	lbelow9 = l - 9
-	m3 = 2343
-
-	lbelow10 = l - 10
-	lbelow11 = l - 11
-
-	lbelow9 >>= 31
-	lbelow12 = l - 12
-
-	lbelow10 >>= 31
-	p += lbelow9
-
-	m20 = uint32(m[p+8])
-	lbelow11 >>= 31
-	p += lbelow10
-
-	m21 = uint32(m[p+9])
-	lbelow12 >>= 31
-	p += lbelow11
-
-	m22 = uint32(m[p+10])
-	m2 <<= 51
-	p += lbelow12
-
-	m23 = uint32(m[p+11])
-	m20 &^= uint32(lbelow9)
-	lbelow8 -= lbelow9
-
-	m20 += uint32(lbelow8)
-	lbelow9 -= lbelow10
-
-	m21 &^= uint32(lbelow10)
-	m21 += uint32(lbelow9)
-
-	m21 <<= 8
-	m2 += int64(m20)
-
-	m2 += int64(m21)
-	m22 &^= uint32(lbelow11)
-
-	lbelow10 -= lbelow11
-	m23 &^= uint32(lbelow12)
-
-	m22 += uint32(lbelow10)
-	lbelow11 -= lbelow12
-
-	m22 <<= 16
-	m23 += uint32(lbelow11)
-
-	m23 <<= 24
-	m2 += int64(m22)
-
-	m3 <<= 51
-	lbelow13 = l - 13
-
-	lbelow13 >>= 31
-	lbelow14 = l - 14
-
-	lbelow14 >>= 31
-	p += lbelow13
-	lbelow15 = l - 15
-
-	m30 = uint32(m[p+12])
-	lbelow15 >>= 31
-	p += lbelow14
-
-	m31 = uint32(m[p+13])
-	p += lbelow15
-	m2 += int64(m23)
-
-	m32 = uint32(m[p+14])
-	m30 &^= uint32(lbelow13)
-	lbelow12 -= lbelow13
-
-	m30 += uint32(lbelow12)
-	lbelow13 -= lbelow14
-
-	m3 += int64(m30)
-	m31 &^= uint32(lbelow14)
-
-	m31 += uint32(lbelow13)
-	m32 &^= uint32(lbelow15)
-
-	m31 <<= 8
-	lbelow14 -= lbelow15
-
-	m3 += int64(m31)
-	m32 += uint32(lbelow14)
-	d0 = m0
-
-	m32 <<= 16
-	m33 = uint64(lbelow15 + 1)
-	d1 = m1
-
-	m33 <<= 24
-	m3 += int64(m32)
-	d2 = m2
-
-	m3 += int64(m33)
-	d3 = m3
-
-	z3 = math.Float64frombits(uint64(d3))
-
-	z2 = math.Float64frombits(uint64(d2))
-
-	z1 = math.Float64frombits(uint64(d1))
-
-	z0 = math.Float64frombits(uint64(d0))
-
-	z3 -= alpha96
-
-	z2 -= alpha64
-
-	z1 -= alpha32
-
-	z0 -= alpha0
-
-	h5 += z3
-
-	h3 += z2
-
-	h1 += z1
-
-	h0 += z0
-
-	y7 = h7 + alpha130
-
-	y6 = h6 + alpha130
-
-	y1 = h1 + alpha32
-
-	y0 = h0 + alpha32
-
-	y7 -= alpha130
-
-	y6 -= alpha130
-
-	y1 -= alpha32
-
-	y0 -= alpha32
-
-	y5 = h5 + alpha96
-
-	y4 = h4 + alpha96
-
-	x7 = h7 - y7
-	y7 *= scale
-
-	x6 = h6 - y6
-	y6 *= scale
-
-	x1 = h1 - y1
-
-	x0 = h0 - y0
-
-	y5 -= alpha96
-
-	y4 -= alpha96
-
-	x1 += y7
-
-	x0 += y6
-
-	x7 += y5
-
-	x6 += y4
-
-	y3 = h3 + alpha64
-
-	y2 = h2 + alpha64
-
-	x0 += x1
-
-	x6 += x7
-
-	y3 -= alpha64
-	r3low = r3low_stack
-
-	y2 -= alpha64
-	r0low = r0low_stack
-
-	x5 = h5 - y5
-	r3lowx0 = r3low * x0
-	r3high = r3high_stack
-
-	x4 = h4 - y4
-	r0lowx6 = r0low * x6
-	r0high = r0high_stack
-
-	x3 = h3 - y3
-	r3highx0 = r3high * x0
-	sr1low = sr1low_stack
-
-	x2 = h2 - y2
-	r0highx6 = r0high * x6
-	sr1high = sr1high_stack
-
-	x5 += y3
-	r0lowx0 = r0low * x0
-	r1low = r1low_stack
-
-	h6 = r3lowx0 + r0lowx6
-	sr1lowx6 = sr1low * x6
-	r1high = r1high_stack
-
-	x4 += y2
-	r0highx0 = r0high * x0
-	sr2low = sr2low_stack
-
-	h7 = r3highx0 + r0highx6
-	sr1highx6 = sr1high * x6
-	sr2high = sr2high_stack
-
-	x3 += y1
-	r1lowx0 = r1low * x0
-	r2low = r2low_stack
-
-	h0 = r0lowx0 + sr1lowx6
-	sr2lowx6 = sr2low * x6
-	r2high = r2high_stack
-
-	x2 += y0
-	r1highx0 = r1high * x0
-	sr3low = sr3low_stack
-
-	h1 = r0highx0 + sr1highx6
-	sr2highx6 = sr2high * x6
-	sr3high = sr3high_stack
-
-	x4 += x5
-	r2lowx0 = r2low * x0
-
-	h2 = r1lowx0 + sr2lowx6
-	sr3lowx6 = sr3low * x6
-
-	x2 += x3
-	r2highx0 = r2high * x0
-
-	h3 = r1highx0 + sr2highx6
-	sr3highx6 = sr3high * x6
-
-	r1highx4 = r1high * x4
-
-	h4 = r2lowx0 + sr3lowx6
-	r1lowx4 = r1low * x4
-
-	r0highx4 = r0high * x4
-
-	h5 = r2highx0 + sr3highx6
-	r0lowx4 = r0low * x4
-
-	h7 += r1highx4
-	sr3highx4 = sr3high * x4
-
-	h6 += r1lowx4
-	sr3lowx4 = sr3low * x4
-
-	h5 += r0highx4
-	sr2highx4 = sr2high * x4
-
-	h4 += r0lowx4
-	sr2lowx4 = sr2low * x4
-
-	h3 += sr3highx4
-	r0lowx2 = r0low * x2
-
-	h2 += sr3lowx4
-	r0highx2 = r0high * x2
-
-	h1 += sr2highx4
-	r1lowx2 = r1low * x2
-
-	h0 += sr2lowx4
-	r1highx2 = r1high * x2
-
-	h2 += r0lowx2
-	r2lowx2 = r2low * x2
-
-	h3 += r0highx2
-	r2highx2 = r2high * x2
-
-	h4 += r1lowx2
-	sr3lowx2 = sr3low * x2
-
-	h5 += r1highx2
-	sr3highx2 = sr3high * x2
-
-	h6 += r2lowx2
-
-	h7 += r2highx2
-
-	h0 += sr3lowx2
-
-	h1 += sr3highx2
-
-nomorebytes:
-
-	y7 = h7 + alpha130
-
-	y0 = h0 + alpha32
-
-	y1 = h1 + alpha32
-
-	y2 = h2 + alpha64
-
-	y7 -= alpha130
-
-	y3 = h3 + alpha64
-
-	y4 = h4 + alpha96
-
-	y5 = h5 + alpha96
-
-	x7 = h7 - y7
-	y7 *= scale
-
-	y0 -= alpha32
-
-	y1 -= alpha32
-
-	y2 -= alpha64
-
-	h6 += x7
-
-	y3 -= alpha64
-
-	y4 -= alpha96
-
-	y5 -= alpha96
-
-	y6 = h6 + alpha130
-
-	x0 = h0 - y0
-
-	x1 = h1 - y1
-
-	x2 = h2 - y2
-
-	y6 -= alpha130
-
-	x0 += y7
-
-	x3 = h3 - y3
-
-	x4 = h4 - y4
-
-	x5 = h5 - y5
-
-	x6 = h6 - y6
-
-	y6 *= scale
-
-	x2 += y0
-
-	x3 += y1
-
-	x4 += y2
-
-	x0 += y6
-
-	x5 += y3
-
-	x6 += y4
-
-	x2 += x3
-
-	x0 += x1
-
-	x4 += x5
-
-	x6 += y5
-
-	x2 += offset1
-	d1 = int64(math.Float64bits(x2))
-
-	x0 += offset0
-	d0 = int64(math.Float64bits(x0))
-
-	x4 += offset2
-	d2 = int64(math.Float64bits(x4))
-
-	x6 += offset3
-	d3 = int64(math.Float64bits(x6))
-
-	f0 = uint64(d0)
-
-	f1 = uint64(d1)
-	bits32 = math.MaxUint64
-
-	f2 = uint64(d2)
-	bits32 >>= 32
-
-	f3 = uint64(d3)
-	f = f0 >> 32
-
-	f0 &= bits32
-	f &= 255
-
-	f1 += f
-	g0 = f0 + 5
-
-	g = g0 >> 32
-	g0 &= bits32
-
-	f = f1 >> 32
-	f1 &= bits32
-
-	f &= 255
-	g1 = f1 + g
-
-	g = g1 >> 32
-	f2 += f
-
-	f = f2 >> 32
-	g1 &= bits32
-
-	f2 &= bits32
-	f &= 255
-
-	f3 += f
-	g2 = f2 + g
-
-	g = g2 >> 32
-	g2 &= bits32
-
-	f4 = f3 >> 32
-	f3 &= bits32
-
-	f4 &= 255
-	g3 = f3 + g
-
-	g = g3 >> 32
-	g3 &= bits32
-
-	g4 = f4 + g
-
-	g4 = g4 - 4
-	s00 = uint32(s[0])
-
-	f = uint64(int64(g4) >> 63)
-	s01 = uint32(s[1])
-
-	f0 &= f
-	g0 &^= f
-	s02 = uint32(s[2])
-
-	f1 &= f
-	f0 |= g0
-	s03 = uint32(s[3])
-
-	g1 &^= f
-	f2 &= f
-	s10 = uint32(s[4])
-
-	f3 &= f
-	g2 &^= f
-	s11 = uint32(s[5])
-
-	g3 &^= f
-	f1 |= g1
-	s12 = uint32(s[6])
-
-	f2 |= g2
-	f3 |= g3
-	s13 = uint32(s[7])
-
-	s01 <<= 8
-	f0 += uint64(s00)
-	s20 = uint32(s[8])
-
-	s02 <<= 16
-	f0 += uint64(s01)
-	s21 = uint32(s[9])
-
-	s03 <<= 24
-	f0 += uint64(s02)
-	s22 = uint32(s[10])
-
-	s11 <<= 8
-	f1 += uint64(s10)
-	s23 = uint32(s[11])
-
-	s12 <<= 16
-	f1 += uint64(s11)
-	s30 = uint32(s[12])
-
-	s13 <<= 24
-	f1 += uint64(s12)
-	s31 = uint32(s[13])
-
-	f0 += uint64(s03)
-	f1 += uint64(s13)
-	s32 = uint32(s[14])
-
-	s21 <<= 8
-	f2 += uint64(s20)
-	s33 = uint32(s[15])
-
-	s22 <<= 16
-	f2 += uint64(s21)
-
-	s23 <<= 24
-	f2 += uint64(s22)
-
-	s31 <<= 8
-	f3 += uint64(s30)
-
-	s32 <<= 16
-	f3 += uint64(s31)
-
-	s33 <<= 24
-	f3 += uint64(s32)
-
-	f2 += uint64(s23)
-	f3 += uint64(s33)
-
-	out[0] = byte(f0)
-	f0 >>= 8
-	out[1] = byte(f0)
-	f0 >>= 8
-	out[2] = byte(f0)
-	f0 >>= 8
-	out[3] = byte(f0)
-	f0 >>= 8
-	f1 += f0
-
-	out[4] = byte(f1)
-	f1 >>= 8
-	out[5] = byte(f1)
-	f1 >>= 8
-	out[6] = byte(f1)
-	f1 >>= 8
-	out[7] = byte(f1)
-	f1 >>= 8
-	f2 += f1
-
-	out[8] = byte(f2)
-	f2 >>= 8
-	out[9] = byte(f2)
-	f2 >>= 8
-	out[10] = byte(f2)
-	f2 >>= 8
-	out[11] = byte(f2)
-	f2 >>= 8
-	f3 += f2
-
-	out[12] = byte(f3)
-	f3 >>= 8
-	out[13] = byte(f3)
-	f3 >>= 8
-	out[14] = byte(f3)
-	f3 >>= 8
-	out[15] = byte(f3)
+	binary.LittleEndian.PutUint32(out[0:], h0)
+	binary.LittleEndian.PutUint32(out[4:], h1)
+	binary.LittleEndian.PutUint32(out[8:], h2)
+	binary.LittleEndian.PutUint32(out[12:], h3)
 }
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s b/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s
index 6e1df96..22afbdc 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s
+++ b/vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s
@@ -5,29 +5,23 @@
 // +build amd64,!appengine,!gccgo
 
 // This code was translated into a form compatible with 6a from the public
-// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
+// domain sources in SUPERCOP: https://bench.cr.yp.to/supercop.html
 
 // func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
-TEXT ·salsa2020XORKeyStream(SB),0,$512-40
+// This needs up to 64 bytes at 360(SP); hence the non-obvious frame size.
+TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
 	MOVQ out+0(FP),DI
 	MOVQ in+8(FP),SI
 	MOVQ n+16(FP),DX
 	MOVQ nonce+24(FP),CX
 	MOVQ key+32(FP),R8
 
-	MOVQ SP,R11
-	MOVQ $31,R9
-	NOTQ R9
-	ANDQ R9,SP
-	ADDQ $32,SP
+	MOVQ SP,R12
+	MOVQ SP,R9
+	ADDQ $31, R9
+	ANDQ $~31, R9
+	MOVQ R9, SP
 
-	MOVQ R11,352(SP)
-	MOVQ R12,360(SP)
-	MOVQ R13,368(SP)
-	MOVQ R14,376(SP)
-	MOVQ R15,384(SP)
-	MOVQ BX,392(SP)
-	MOVQ BP,400(SP)
 	MOVQ DX,R9
 	MOVQ CX,DX
 	MOVQ R8,R10
@@ -133,7 +127,7 @@
 	SHRQ $32,CX
 	MOVL DX,16(SP)
 	MOVL CX, 36 (SP)
-	MOVQ R9,408(SP)
+	MOVQ R9,352(SP)
 	MOVQ $20,DX
 	MOVOA 64(SP),X0
 	MOVOA 80(SP),X1
@@ -650,7 +644,7 @@
 	MOVL CX,244(DI)
 	MOVL R8,248(DI)
 	MOVL R9,252(DI)
-	MOVQ 408(SP),R9
+	MOVQ 352(SP),R9
 	SUBQ $256,R9
 	ADDQ $256,SI
 	ADDQ $256,DI
@@ -662,13 +656,13 @@
 	CMPQ R9,$64
 	JAE NOCOPY
 	MOVQ DI,DX
-	LEAQ 416(SP),DI
+	LEAQ 360(SP),DI
 	MOVQ R9,CX
 	REP; MOVSB
-	LEAQ 416(SP),DI
-	LEAQ 416(SP),SI
+	LEAQ 360(SP),DI
+	LEAQ 360(SP),SI
 	NOCOPY:
-	MOVQ R9,408(SP)
+	MOVQ R9,352(SP)
 	MOVOA 48(SP),X0
 	MOVOA 0(SP),X1
 	MOVOA 16(SP),X2
@@ -867,7 +861,7 @@
 	MOVL R8,44(DI)
 	MOVL R9,28(DI)
 	MOVL AX,12(DI)
-	MOVQ 408(SP),R9
+	MOVQ 352(SP),R9
 	MOVL 16(SP),CX
 	MOVL  36 (SP),R8
 	ADDQ $1,CX
@@ -886,14 +880,7 @@
 	REP; MOVSB
 	BYTESATLEAST64:
 	DONE:
-	MOVQ 352(SP),R11
-	MOVQ 360(SP),R12
-	MOVQ 368(SP),R13
-	MOVQ 376(SP),R14
-	MOVQ 384(SP),R15
-	MOVQ 392(SP),BX
-	MOVQ 400(SP),BP
-	MOVQ R11,SP
+	MOVQ R12,SP
 	RET
 	BYTESATLEAST65:
 	SUBQ $64,R9
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/terminal.go b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
new file mode 100644
index 0000000..18379a9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/terminal.go
@@ -0,0 +1,951 @@
+// 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 terminal
+
+import (
+	"bytes"
+	"io"
+	"sync"
+	"unicode/utf8"
+)
+
+// EscapeCodes contains escape sequences that can be written to the terminal in
+// order to achieve different styles of text.
+type EscapeCodes struct {
+	// Foreground colors
+	Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte
+
+	// Reset all attributes
+	Reset []byte
+}
+
+var vt100EscapeCodes = EscapeCodes{
+	Black:   []byte{keyEscape, '[', '3', '0', 'm'},
+	Red:     []byte{keyEscape, '[', '3', '1', 'm'},
+	Green:   []byte{keyEscape, '[', '3', '2', 'm'},
+	Yellow:  []byte{keyEscape, '[', '3', '3', 'm'},
+	Blue:    []byte{keyEscape, '[', '3', '4', 'm'},
+	Magenta: []byte{keyEscape, '[', '3', '5', 'm'},
+	Cyan:    []byte{keyEscape, '[', '3', '6', 'm'},
+	White:   []byte{keyEscape, '[', '3', '7', 'm'},
+
+	Reset: []byte{keyEscape, '[', '0', 'm'},
+}
+
+// Terminal contains the state for running a VT100 terminal that is capable of
+// reading lines of input.
+type Terminal struct {
+	// AutoCompleteCallback, if non-null, is called for each keypress with
+	// the full input line and the current position of the cursor (in
+	// bytes, as an index into |line|). If it returns ok=false, the key
+	// press is processed normally. Otherwise it returns a replacement line
+	// and the new cursor position.
+	AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool)
+
+	// Escape contains a pointer to the escape codes for this terminal.
+	// It's always a valid pointer, although the escape codes themselves
+	// may be empty if the terminal doesn't support them.
+	Escape *EscapeCodes
+
+	// lock protects the terminal and the state in this object from
+	// concurrent processing of a key press and a Write() call.
+	lock sync.Mutex
+
+	c      io.ReadWriter
+	prompt []rune
+
+	// line is the current line being entered.
+	line []rune
+	// pos is the logical position of the cursor in line
+	pos int
+	// echo is true if local echo is enabled
+	echo bool
+	// pasteActive is true iff there is a bracketed paste operation in
+	// progress.
+	pasteActive bool
+
+	// cursorX contains the current X value of the cursor where the left
+	// edge is 0. cursorY contains the row number where the first row of
+	// the current line is 0.
+	cursorX, cursorY int
+	// maxLine is the greatest value of cursorY so far.
+	maxLine int
+
+	termWidth, termHeight int
+
+	// outBuf contains the terminal data to be sent.
+	outBuf []byte
+	// remainder contains the remainder of any partial key sequences after
+	// a read. It aliases into inBuf.
+	remainder []byte
+	inBuf     [256]byte
+
+	// history contains previously entered commands so that they can be
+	// accessed with the up and down keys.
+	history stRingBuffer
+	// historyIndex stores the currently accessed history entry, where zero
+	// means the immediately previous entry.
+	historyIndex int
+	// When navigating up and down the history it's possible to return to
+	// the incomplete, initial line. That value is stored in
+	// historyPending.
+	historyPending string
+}
+
+// NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is
+// a local terminal, that terminal must first have been put into raw mode.
+// prompt is a string that is written at the start of each input line (i.e.
+// "> ").
+func NewTerminal(c io.ReadWriter, prompt string) *Terminal {
+	return &Terminal{
+		Escape:       &vt100EscapeCodes,
+		c:            c,
+		prompt:       []rune(prompt),
+		termWidth:    80,
+		termHeight:   24,
+		echo:         true,
+		historyIndex: -1,
+	}
+}
+
+const (
+	keyCtrlD     = 4
+	keyCtrlU     = 21
+	keyEnter     = '\r'
+	keyEscape    = 27
+	keyBackspace = 127
+	keyUnknown   = 0xd800 /* UTF-16 surrogate area */ + iota
+	keyUp
+	keyDown
+	keyLeft
+	keyRight
+	keyAltLeft
+	keyAltRight
+	keyHome
+	keyEnd
+	keyDeleteWord
+	keyDeleteLine
+	keyClearScreen
+	keyPasteStart
+	keyPasteEnd
+)
+
+var (
+	crlf       = []byte{'\r', '\n'}
+	pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'}
+	pasteEnd   = []byte{keyEscape, '[', '2', '0', '1', '~'}
+)
+
+// bytesToKey tries to parse a key sequence from b. If successful, it returns
+// the key and the remainder of the input. Otherwise it returns utf8.RuneError.
+func bytesToKey(b []byte, pasteActive bool) (rune, []byte) {
+	if len(b) == 0 {
+		return utf8.RuneError, nil
+	}
+
+	if !pasteActive {
+		switch b[0] {
+		case 1: // ^A
+			return keyHome, b[1:]
+		case 5: // ^E
+			return keyEnd, b[1:]
+		case 8: // ^H
+			return keyBackspace, b[1:]
+		case 11: // ^K
+			return keyDeleteLine, b[1:]
+		case 12: // ^L
+			return keyClearScreen, b[1:]
+		case 23: // ^W
+			return keyDeleteWord, b[1:]
+		}
+	}
+
+	if b[0] != keyEscape {
+		if !utf8.FullRune(b) {
+			return utf8.RuneError, b
+		}
+		r, l := utf8.DecodeRune(b)
+		return r, b[l:]
+	}
+
+	if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' {
+		switch b[2] {
+		case 'A':
+			return keyUp, b[3:]
+		case 'B':
+			return keyDown, b[3:]
+		case 'C':
+			return keyRight, b[3:]
+		case 'D':
+			return keyLeft, b[3:]
+		case 'H':
+			return keyHome, b[3:]
+		case 'F':
+			return keyEnd, b[3:]
+		}
+	}
+
+	if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' {
+		switch b[5] {
+		case 'C':
+			return keyAltRight, b[6:]
+		case 'D':
+			return keyAltLeft, b[6:]
+		}
+	}
+
+	if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) {
+		return keyPasteStart, b[6:]
+	}
+
+	if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) {
+		return keyPasteEnd, b[6:]
+	}
+
+	// If we get here then we have a key that we don't recognise, or a
+	// partial sequence. It's not clear how one should find the end of a
+	// sequence without knowing them all, but it seems that [a-zA-Z~] only
+	// appears at the end of a sequence.
+	for i, c := range b[0:] {
+		if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' {
+			return keyUnknown, b[i+1:]
+		}
+	}
+
+	return utf8.RuneError, b
+}
+
+// queue appends data to the end of t.outBuf
+func (t *Terminal) queue(data []rune) {
+	t.outBuf = append(t.outBuf, []byte(string(data))...)
+}
+
+var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
+var space = []rune{' '}
+
+func isPrintable(key rune) bool {
+	isInSurrogateArea := key >= 0xd800 && key <= 0xdbff
+	return key >= 32 && !isInSurrogateArea
+}
+
+// moveCursorToPos appends data to t.outBuf which will move the cursor to the
+// given, logical position in the text.
+func (t *Terminal) moveCursorToPos(pos int) {
+	if !t.echo {
+		return
+	}
+
+	x := visualLength(t.prompt) + pos
+	y := x / t.termWidth
+	x = x % t.termWidth
+
+	up := 0
+	if y < t.cursorY {
+		up = t.cursorY - y
+	}
+
+	down := 0
+	if y > t.cursorY {
+		down = y - t.cursorY
+	}
+
+	left := 0
+	if x < t.cursorX {
+		left = t.cursorX - x
+	}
+
+	right := 0
+	if x > t.cursorX {
+		right = x - t.cursorX
+	}
+
+	t.cursorX = x
+	t.cursorY = y
+	t.move(up, down, left, right)
+}
+
+func (t *Terminal) move(up, down, left, right int) {
+	movement := make([]rune, 3*(up+down+left+right))
+	m := movement
+	for i := 0; i < up; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'A'
+		m = m[3:]
+	}
+	for i := 0; i < down; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'B'
+		m = m[3:]
+	}
+	for i := 0; i < left; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'D'
+		m = m[3:]
+	}
+	for i := 0; i < right; i++ {
+		m[0] = keyEscape
+		m[1] = '['
+		m[2] = 'C'
+		m = m[3:]
+	}
+
+	t.queue(movement)
+}
+
+func (t *Terminal) clearLineToRight() {
+	op := []rune{keyEscape, '[', 'K'}
+	t.queue(op)
+}
+
+const maxLineLength = 4096
+
+func (t *Terminal) setLine(newLine []rune, newPos int) {
+	if t.echo {
+		t.moveCursorToPos(0)
+		t.writeLine(newLine)
+		for i := len(newLine); i < len(t.line); i++ {
+			t.writeLine(space)
+		}
+		t.moveCursorToPos(newPos)
+	}
+	t.line = newLine
+	t.pos = newPos
+}
+
+func (t *Terminal) advanceCursor(places int) {
+	t.cursorX += places
+	t.cursorY += t.cursorX / t.termWidth
+	if t.cursorY > t.maxLine {
+		t.maxLine = t.cursorY
+	}
+	t.cursorX = t.cursorX % t.termWidth
+
+	if places > 0 && t.cursorX == 0 {
+		// Normally terminals will advance the current position
+		// when writing a character. But that doesn't happen
+		// for the last character in a line. However, when
+		// writing a character (except a new line) that causes
+		// a line wrap, the position will be advanced two
+		// places.
+		//
+		// So, if we are stopping at the end of a line, we
+		// need to write a newline so that our cursor can be
+		// advanced to the next line.
+		t.outBuf = append(t.outBuf, '\r', '\n')
+	}
+}
+
+func (t *Terminal) eraseNPreviousChars(n int) {
+	if n == 0 {
+		return
+	}
+
+	if t.pos < n {
+		n = t.pos
+	}
+	t.pos -= n
+	t.moveCursorToPos(t.pos)
+
+	copy(t.line[t.pos:], t.line[n+t.pos:])
+	t.line = t.line[:len(t.line)-n]
+	if t.echo {
+		t.writeLine(t.line[t.pos:])
+		for i := 0; i < n; i++ {
+			t.queue(space)
+		}
+		t.advanceCursor(n)
+		t.moveCursorToPos(t.pos)
+	}
+}
+
+// countToLeftWord returns then number of characters from the cursor to the
+// start of the previous word.
+func (t *Terminal) countToLeftWord() int {
+	if t.pos == 0 {
+		return 0
+	}
+
+	pos := t.pos - 1
+	for pos > 0 {
+		if t.line[pos] != ' ' {
+			break
+		}
+		pos--
+	}
+	for pos > 0 {
+		if t.line[pos] == ' ' {
+			pos++
+			break
+		}
+		pos--
+	}
+
+	return t.pos - pos
+}
+
+// countToRightWord returns then number of characters from the cursor to the
+// start of the next word.
+func (t *Terminal) countToRightWord() int {
+	pos := t.pos
+	for pos < len(t.line) {
+		if t.line[pos] == ' ' {
+			break
+		}
+		pos++
+	}
+	for pos < len(t.line) {
+		if t.line[pos] != ' ' {
+			break
+		}
+		pos++
+	}
+	return pos - t.pos
+}
+
+// visualLength returns the number of visible glyphs in s.
+func visualLength(runes []rune) int {
+	inEscapeSeq := false
+	length := 0
+
+	for _, r := range runes {
+		switch {
+		case inEscapeSeq:
+			if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') {
+				inEscapeSeq = false
+			}
+		case r == '\x1b':
+			inEscapeSeq = true
+		default:
+			length++
+		}
+	}
+
+	return length
+}
+
+// handleKey processes the given key and, optionally, returns a line of text
+// that the user has entered.
+func (t *Terminal) handleKey(key rune) (line string, ok bool) {
+	if t.pasteActive && key != keyEnter {
+		t.addKeyToLine(key)
+		return
+	}
+
+	switch key {
+	case keyBackspace:
+		if t.pos == 0 {
+			return
+		}
+		t.eraseNPreviousChars(1)
+	case keyAltLeft:
+		// move left by a word.
+		t.pos -= t.countToLeftWord()
+		t.moveCursorToPos(t.pos)
+	case keyAltRight:
+		// move right by a word.
+		t.pos += t.countToRightWord()
+		t.moveCursorToPos(t.pos)
+	case keyLeft:
+		if t.pos == 0 {
+			return
+		}
+		t.pos--
+		t.moveCursorToPos(t.pos)
+	case keyRight:
+		if t.pos == len(t.line) {
+			return
+		}
+		t.pos++
+		t.moveCursorToPos(t.pos)
+	case keyHome:
+		if t.pos == 0 {
+			return
+		}
+		t.pos = 0
+		t.moveCursorToPos(t.pos)
+	case keyEnd:
+		if t.pos == len(t.line) {
+			return
+		}
+		t.pos = len(t.line)
+		t.moveCursorToPos(t.pos)
+	case keyUp:
+		entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1)
+		if !ok {
+			return "", false
+		}
+		if t.historyIndex == -1 {
+			t.historyPending = string(t.line)
+		}
+		t.historyIndex++
+		runes := []rune(entry)
+		t.setLine(runes, len(runes))
+	case keyDown:
+		switch t.historyIndex {
+		case -1:
+			return
+		case 0:
+			runes := []rune(t.historyPending)
+			t.setLine(runes, len(runes))
+			t.historyIndex--
+		default:
+			entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1)
+			if ok {
+				t.historyIndex--
+				runes := []rune(entry)
+				t.setLine(runes, len(runes))
+			}
+		}
+	case keyEnter:
+		t.moveCursorToPos(len(t.line))
+		t.queue([]rune("\r\n"))
+		line = string(t.line)
+		ok = true
+		t.line = t.line[:0]
+		t.pos = 0
+		t.cursorX = 0
+		t.cursorY = 0
+		t.maxLine = 0
+	case keyDeleteWord:
+		// Delete zero or more spaces and then one or more characters.
+		t.eraseNPreviousChars(t.countToLeftWord())
+	case keyDeleteLine:
+		// Delete everything from the current cursor position to the
+		// end of line.
+		for i := t.pos; i < len(t.line); i++ {
+			t.queue(space)
+			t.advanceCursor(1)
+		}
+		t.line = t.line[:t.pos]
+		t.moveCursorToPos(t.pos)
+	case keyCtrlD:
+		// Erase the character under the current position.
+		// The EOF case when the line is empty is handled in
+		// readLine().
+		if t.pos < len(t.line) {
+			t.pos++
+			t.eraseNPreviousChars(1)
+		}
+	case keyCtrlU:
+		t.eraseNPreviousChars(t.pos)
+	case keyClearScreen:
+		// Erases the screen and moves the cursor to the home position.
+		t.queue([]rune("\x1b[2J\x1b[H"))
+		t.queue(t.prompt)
+		t.cursorX, t.cursorY = 0, 0
+		t.advanceCursor(visualLength(t.prompt))
+		t.setLine(t.line, t.pos)
+	default:
+		if t.AutoCompleteCallback != nil {
+			prefix := string(t.line[:t.pos])
+			suffix := string(t.line[t.pos:])
+
+			t.lock.Unlock()
+			newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key)
+			t.lock.Lock()
+
+			if completeOk {
+				t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos]))
+				return
+			}
+		}
+		if !isPrintable(key) {
+			return
+		}
+		if len(t.line) == maxLineLength {
+			return
+		}
+		t.addKeyToLine(key)
+	}
+	return
+}
+
+// addKeyToLine inserts the given key at the current position in the current
+// line.
+func (t *Terminal) addKeyToLine(key rune) {
+	if len(t.line) == cap(t.line) {
+		newLine := make([]rune, len(t.line), 2*(1+len(t.line)))
+		copy(newLine, t.line)
+		t.line = newLine
+	}
+	t.line = t.line[:len(t.line)+1]
+	copy(t.line[t.pos+1:], t.line[t.pos:])
+	t.line[t.pos] = key
+	if t.echo {
+		t.writeLine(t.line[t.pos:])
+	}
+	t.pos++
+	t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) writeLine(line []rune) {
+	for len(line) != 0 {
+		remainingOnLine := t.termWidth - t.cursorX
+		todo := len(line)
+		if todo > remainingOnLine {
+			todo = remainingOnLine
+		}
+		t.queue(line[:todo])
+		t.advanceCursor(visualLength(line[:todo]))
+		line = line[todo:]
+	}
+}
+
+// writeWithCRLF writes buf to w but replaces all occurrences of \n with \r\n.
+func writeWithCRLF(w io.Writer, buf []byte) (n int, err error) {
+	for len(buf) > 0 {
+		i := bytes.IndexByte(buf, '\n')
+		todo := len(buf)
+		if i >= 0 {
+			todo = i
+		}
+
+		var nn int
+		nn, err = w.Write(buf[:todo])
+		n += nn
+		if err != nil {
+			return n, err
+		}
+		buf = buf[todo:]
+
+		if i >= 0 {
+			if _, err = w.Write(crlf); err != nil {
+				return n, err
+			}
+			n += 1
+			buf = buf[1:]
+		}
+	}
+
+	return n, nil
+}
+
+func (t *Terminal) Write(buf []byte) (n int, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if t.cursorX == 0 && t.cursorY == 0 {
+		// This is the easy case: there's nothing on the screen that we
+		// have to move out of the way.
+		return writeWithCRLF(t.c, buf)
+	}
+
+	// We have a prompt and possibly user input on the screen. We
+	// have to clear it first.
+	t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */)
+	t.cursorX = 0
+	t.clearLineToRight()
+
+	for t.cursorY > 0 {
+		t.move(1 /* up */, 0, 0, 0)
+		t.cursorY--
+		t.clearLineToRight()
+	}
+
+	if _, err = t.c.Write(t.outBuf); err != nil {
+		return
+	}
+	t.outBuf = t.outBuf[:0]
+
+	if n, err = writeWithCRLF(t.c, buf); err != nil {
+		return
+	}
+
+	t.writeLine(t.prompt)
+	if t.echo {
+		t.writeLine(t.line)
+	}
+
+	t.moveCursorToPos(t.pos)
+
+	if _, err = t.c.Write(t.outBuf); err != nil {
+		return
+	}
+	t.outBuf = t.outBuf[:0]
+	return
+}
+
+// ReadPassword temporarily changes the prompt and reads a password, without
+// echo, from the terminal.
+func (t *Terminal) ReadPassword(prompt string) (line string, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	oldPrompt := t.prompt
+	t.prompt = []rune(prompt)
+	t.echo = false
+
+	line, err = t.readLine()
+
+	t.prompt = oldPrompt
+	t.echo = true
+
+	return
+}
+
+// ReadLine returns a line of input from the terminal.
+func (t *Terminal) ReadLine() (line string, err error) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	return t.readLine()
+}
+
+func (t *Terminal) readLine() (line string, err error) {
+	// t.lock must be held at this point
+
+	if t.cursorX == 0 && t.cursorY == 0 {
+		t.writeLine(t.prompt)
+		t.c.Write(t.outBuf)
+		t.outBuf = t.outBuf[:0]
+	}
+
+	lineIsPasted := t.pasteActive
+
+	for {
+		rest := t.remainder
+		lineOk := false
+		for !lineOk {
+			var key rune
+			key, rest = bytesToKey(rest, t.pasteActive)
+			if key == utf8.RuneError {
+				break
+			}
+			if !t.pasteActive {
+				if key == keyCtrlD {
+					if len(t.line) == 0 {
+						return "", io.EOF
+					}
+				}
+				if key == keyPasteStart {
+					t.pasteActive = true
+					if len(t.line) == 0 {
+						lineIsPasted = true
+					}
+					continue
+				}
+			} else if key == keyPasteEnd {
+				t.pasteActive = false
+				continue
+			}
+			if !t.pasteActive {
+				lineIsPasted = false
+			}
+			line, lineOk = t.handleKey(key)
+		}
+		if len(rest) > 0 {
+			n := copy(t.inBuf[:], rest)
+			t.remainder = t.inBuf[:n]
+		} else {
+			t.remainder = nil
+		}
+		t.c.Write(t.outBuf)
+		t.outBuf = t.outBuf[:0]
+		if lineOk {
+			if t.echo {
+				t.historyIndex = -1
+				t.history.Add(line)
+			}
+			if lineIsPasted {
+				err = ErrPasteIndicator
+			}
+			return
+		}
+
+		// t.remainder is a slice at the beginning of t.inBuf
+		// containing a partial key sequence
+		readBuf := t.inBuf[len(t.remainder):]
+		var n int
+
+		t.lock.Unlock()
+		n, err = t.c.Read(readBuf)
+		t.lock.Lock()
+
+		if err != nil {
+			return
+		}
+
+		t.remainder = t.inBuf[:n+len(t.remainder)]
+	}
+}
+
+// SetPrompt sets the prompt to be used when reading subsequent lines.
+func (t *Terminal) SetPrompt(prompt string) {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	t.prompt = []rune(prompt)
+}
+
+func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) {
+	// Move cursor to column zero at the start of the line.
+	t.move(t.cursorY, 0, t.cursorX, 0)
+	t.cursorX, t.cursorY = 0, 0
+	t.clearLineToRight()
+	for t.cursorY < numPrevLines {
+		// Move down a line
+		t.move(0, 1, 0, 0)
+		t.cursorY++
+		t.clearLineToRight()
+	}
+	// Move back to beginning.
+	t.move(t.cursorY, 0, 0, 0)
+	t.cursorX, t.cursorY = 0, 0
+
+	t.queue(t.prompt)
+	t.advanceCursor(visualLength(t.prompt))
+	t.writeLine(t.line)
+	t.moveCursorToPos(t.pos)
+}
+
+func (t *Terminal) SetSize(width, height int) error {
+	t.lock.Lock()
+	defer t.lock.Unlock()
+
+	if width == 0 {
+		width = 1
+	}
+
+	oldWidth := t.termWidth
+	t.termWidth, t.termHeight = width, height
+
+	switch {
+	case width == oldWidth:
+		// If the width didn't change then nothing else needs to be
+		// done.
+		return nil
+	case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0:
+		// If there is nothing on current line and no prompt printed,
+		// just do nothing
+		return nil
+	case width < oldWidth:
+		// Some terminals (e.g. xterm) will truncate lines that were
+		// too long when shinking. Others, (e.g. gnome-terminal) will
+		// attempt to wrap them. For the former, repainting t.maxLine
+		// works great, but that behaviour goes badly wrong in the case
+		// of the latter because they have doubled every full line.
+
+		// We assume that we are working on a terminal that wraps lines
+		// and adjust the cursor position based on every previous line
+		// wrapping and turning into two. This causes the prompt on
+		// xterms to move upwards, which isn't great, but it avoids a
+		// huge mess with gnome-terminal.
+		if t.cursorX >= t.termWidth {
+			t.cursorX = t.termWidth - 1
+		}
+		t.cursorY *= 2
+		t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2)
+	case width > oldWidth:
+		// If the terminal expands then our position calculations will
+		// be wrong in the future because we think the cursor is
+		// |t.pos| chars into the string, but there will be a gap at
+		// the end of any wrapped line.
+		//
+		// But the position will actually be correct until we move, so
+		// we can move back to the beginning and repaint everything.
+		t.clearAndRepaintLinePlusNPrevious(t.maxLine)
+	}
+
+	_, err := t.c.Write(t.outBuf)
+	t.outBuf = t.outBuf[:0]
+	return err
+}
+
+type pasteIndicatorError struct{}
+
+func (pasteIndicatorError) Error() string {
+	return "terminal: ErrPasteIndicator not correctly handled"
+}
+
+// ErrPasteIndicator may be returned from ReadLine as the error, in addition
+// to valid line data. It indicates that bracketed paste mode is enabled and
+// that the returned line consists only of pasted data. Programs may wish to
+// interpret pasted data more literally than typed data.
+var ErrPasteIndicator = pasteIndicatorError{}
+
+// SetBracketedPasteMode requests that the terminal bracket paste operations
+// with markers. Not all terminals support this but, if it is supported, then
+// enabling this mode will stop any autocomplete callback from running due to
+// pastes. Additionally, any lines that are completely pasted will be returned
+// from ReadLine with the error set to ErrPasteIndicator.
+func (t *Terminal) SetBracketedPasteMode(on bool) {
+	if on {
+		io.WriteString(t.c, "\x1b[?2004h")
+	} else {
+		io.WriteString(t.c, "\x1b[?2004l")
+	}
+}
+
+// stRingBuffer is a ring buffer of strings.
+type stRingBuffer struct {
+	// entries contains max elements.
+	entries []string
+	max     int
+	// head contains the index of the element most recently added to the ring.
+	head int
+	// size contains the number of elements in the ring.
+	size int
+}
+
+func (s *stRingBuffer) Add(a string) {
+	if s.entries == nil {
+		const defaultNumEntries = 100
+		s.entries = make([]string, defaultNumEntries)
+		s.max = defaultNumEntries
+	}
+
+	s.head = (s.head + 1) % s.max
+	s.entries[s.head] = a
+	if s.size < s.max {
+		s.size++
+	}
+}
+
+// NthPreviousEntry returns the value passed to the nth previous call to Add.
+// If n is zero then the immediately prior value is returned, if one, then the
+// next most recent, and so on. If such an element doesn't exist then ok is
+// false.
+func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
+	if n >= s.size {
+		return "", false
+	}
+	index := s.head - n
+	if index < 0 {
+		index += s.max
+	}
+	return s.entries[index], true
+}
+
+// readPasswordLine reads from reader until it finds \n or io.EOF.
+// The slice returned does not include the \n.
+// readPasswordLine also ignores any \r it finds.
+func readPasswordLine(reader io.Reader) ([]byte, error) {
+	var buf [1]byte
+	var ret []byte
+
+	for {
+		n, err := reader.Read(buf[:])
+		if n > 0 {
+			switch buf[0] {
+			case '\n':
+				return ret, nil
+			case '\r':
+				// remove \r from passwords on Windows
+			default:
+				ret = append(ret, buf[0])
+			}
+			continue
+		}
+		if err != nil {
+			if err == io.EOF && len(ret) > 0 {
+				return ret, nil
+			}
+			return ret, err
+		}
+	}
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util.go b/vendor/golang.org/x/crypto/ssh/terminal/util.go
new file mode 100644
index 0000000..d019196
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util.go
@@ -0,0 +1,119 @@
+// 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.
+
+// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
+
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+// 	oldState, err := terminal.MakeRaw(0)
+// 	if err != nil {
+// 	        panic(err)
+// 	}
+// 	defer terminal.Restore(0, oldState)
+package terminal // import "golang.org/x/crypto/ssh/terminal"
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// State contains the state of a terminal.
+type State struct {
+	termios syscall.Termios
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	var termios syscall.Termios
+	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
+	return err == 0
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	var oldState State
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+		return nil, err
+	}
+
+	newState := oldState.termios
+	// This attempts to replicate the behaviour documented for cfmakeraw in
+	// the termios(3) manpage.
+	newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
+	newState.Oflag &^= syscall.OPOST
+	newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
+	newState.Cflag &^= syscall.CSIZE | syscall.PARENB
+	newState.Cflag |= syscall.CS8
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+		return nil, err
+	}
+
+	return &oldState, nil
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	var oldState State
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
+		return nil, err
+	}
+
+	return &oldState, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0); err != 0 {
+		return err
+	}
+	return nil
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	var dimensions [4]uint16
+
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
+		return -1, -1, err
+	}
+	return int(dimensions[1]), int(dimensions[0]), nil
+}
+
+// passwordReader is an io.Reader that reads from a specific file descriptor.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+	return syscall.Read(int(r), buf)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	var oldState syscall.Termios
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
+		return nil, err
+	}
+
+	newState := oldState
+	newState.Lflag &^= syscall.ECHO
+	newState.Lflag |= syscall.ICANON | syscall.ISIG
+	newState.Iflag |= syscall.ICRNL
+	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
+		return nil, err
+	}
+
+	defer func() {
+		syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
+	}()
+
+	return readPasswordLine(passwordReader(fd))
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
new file mode 100644
index 0000000..cb23a59
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go
@@ -0,0 +1,12 @@
+// 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package terminal
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TIOCGETA
+const ioctlWriteTermios = unix.TIOCSETA
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
new file mode 100644
index 0000000..5fadfe8
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_linux.go
@@ -0,0 +1,10 @@
+// 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 terminal
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
+const ioctlWriteTermios = unix.TCSETS
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go
new file mode 100644
index 0000000..799f049
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go
@@ -0,0 +1,58 @@
+// Copyright 2016 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 terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+// 	oldState, err := terminal.MakeRaw(0)
+// 	if err != nil {
+// 	        panic(err)
+// 	}
+// 	defer terminal.Restore(0, oldState)
+package terminal
+
+import (
+	"fmt"
+	"runtime"
+)
+
+type State struct{}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	return false
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+	return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
new file mode 100644
index 0000000..a2e1b57
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
@@ -0,0 +1,128 @@
+// 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.
+
+// +build solaris
+
+package terminal // import "golang.org/x/crypto/ssh/terminal"
+
+import (
+	"golang.org/x/sys/unix"
+	"io"
+	"syscall"
+)
+
+// State contains the state of a terminal.
+type State struct {
+	state *unix.Termios
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
+	return err == nil
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	// see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c
+	val, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	if err != nil {
+		return nil, err
+	}
+	oldState := *val
+
+	newState := oldState
+	newState.Lflag &^= syscall.ECHO
+	newState.Lflag |= syscall.ICANON | syscall.ISIG
+	newState.Iflag |= syscall.ICRNL
+	err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState)
+	if err != nil {
+		return nil, err
+	}
+
+	defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState)
+
+	var buf [16]byte
+	var ret []byte
+	for {
+		n, err := syscall.Read(fd, buf[:])
+		if err != nil {
+			return nil, err
+		}
+		if n == 0 {
+			if len(ret) == 0 {
+				return nil, io.EOF
+			}
+			break
+		}
+		if buf[n-1] == '\n' {
+			n--
+		}
+		ret = append(ret, buf[:n]...)
+		if n < len(buf) {
+			break
+		}
+	}
+
+	return ret, nil
+}
+
+// MakeRaw puts the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+// see http://cr.illumos.org/~webrev/andy_js/1060/
+func MakeRaw(fd int) (*State, error) {
+	oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	if err != nil {
+		return nil, err
+	}
+	oldTermios := *oldTermiosPtr
+
+	newTermios := oldTermios
+	newTermios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
+	newTermios.Oflag &^= syscall.OPOST
+	newTermios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
+	newTermios.Cflag &^= syscall.CSIZE | syscall.PARENB
+	newTermios.Cflag |= syscall.CS8
+	newTermios.Cc[unix.VMIN] = 1
+	newTermios.Cc[unix.VTIME] = 0
+
+	if err := unix.IoctlSetTermios(fd, unix.TCSETS, &newTermios); err != nil {
+		return nil, err
+	}
+
+	return &State{
+		state: oldTermiosPtr,
+	}, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, oldState *State) error {
+	return unix.IoctlSetTermios(fd, unix.TCSETS, oldState.state)
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
+	if err != nil {
+		return nil, err
+	}
+
+	return &State{
+		state: oldTermiosPtr,
+	}, nil
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+	if err != nil {
+		return 0, 0, err
+	}
+	return int(ws.Col), int(ws.Row), nil
+}
diff --git a/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
new file mode 100644
index 0000000..e0a1f36
--- /dev/null
+++ b/vendor/golang.org/x/crypto/ssh/terminal/util_windows.go
@@ -0,0 +1,155 @@
+// 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.
+
+// +build windows
+
+// Package terminal provides support functions for dealing with terminals, as
+// commonly found on UNIX systems.
+//
+// Putting a terminal into raw mode is the most common requirement:
+//
+// 	oldState, err := terminal.MakeRaw(0)
+// 	if err != nil {
+// 	        panic(err)
+// 	}
+// 	defer terminal.Restore(0, oldState)
+package terminal
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const (
+	enableLineInput       = 2
+	enableEchoInput       = 4
+	enableProcessedInput  = 1
+	enableWindowInput     = 8
+	enableMouseInput      = 16
+	enableInsertMode      = 32
+	enableQuickEditMode   = 64
+	enableExtendedFlags   = 128
+	enableAutoPosition    = 256
+	enableProcessedOutput = 1
+	enableWrapAtEolOutput = 2
+)
+
+var kernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+var (
+	procGetConsoleMode             = kernel32.NewProc("GetConsoleMode")
+	procSetConsoleMode             = kernel32.NewProc("SetConsoleMode")
+	procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
+)
+
+type (
+	short int16
+	word  uint16
+
+	coord struct {
+		x short
+		y short
+	}
+	smallRect struct {
+		left   short
+		top    short
+		right  short
+		bottom short
+	}
+	consoleScreenBufferInfo struct {
+		size              coord
+		cursorPosition    coord
+		attributes        word
+		window            smallRect
+		maximumWindowSize coord
+	}
+)
+
+type State struct {
+	mode uint32
+}
+
+// IsTerminal returns true if the given file descriptor is a terminal.
+func IsTerminal(fd int) bool {
+	var st uint32
+	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
+	return r != 0 && e == 0
+}
+
+// MakeRaw put the terminal connected to the given file descriptor into raw
+// mode and returns the previous state of the terminal so that it can be
+// restored.
+func MakeRaw(fd int) (*State, error) {
+	var st uint32
+	_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
+	if e != 0 {
+		return nil, error(e)
+	}
+	raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)
+	_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0)
+	if e != 0 {
+		return nil, error(e)
+	}
+	return &State{st}, nil
+}
+
+// GetState returns the current state of a terminal which may be useful to
+// restore the terminal after a signal.
+func GetState(fd int) (*State, error) {
+	var st uint32
+	_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
+	if e != 0 {
+		return nil, error(e)
+	}
+	return &State{st}, nil
+}
+
+// Restore restores the terminal connected to the given file descriptor to a
+// previous state.
+func Restore(fd int, state *State) error {
+	_, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0)
+	return err
+}
+
+// GetSize returns the dimensions of the given terminal.
+func GetSize(fd int) (width, height int, err error) {
+	var info consoleScreenBufferInfo
+	_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0)
+	if e != 0 {
+		return 0, 0, error(e)
+	}
+	return int(info.size.x), int(info.size.y), nil
+}
+
+// passwordReader is an io.Reader that reads from a specific Windows HANDLE.
+type passwordReader int
+
+func (r passwordReader) Read(buf []byte) (int, error) {
+	return syscall.Read(syscall.Handle(r), buf)
+}
+
+// ReadPassword reads a line of input from a terminal without local echo.  This
+// is commonly used for inputting passwords and other sensitive data. The slice
+// returned does not include the \n.
+func ReadPassword(fd int) ([]byte, error) {
+	var st uint32
+	_, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
+	if e != 0 {
+		return nil, error(e)
+	}
+	old := st
+
+	st &^= (enableEchoInput)
+	st |= (enableProcessedInput | enableLineInput | enableProcessedOutput)
+	_, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0)
+	if e != 0 {
+		return nil, error(e)
+	}
+
+	defer func() {
+		syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0)
+	}()
+
+	return readPasswordLine(passwordReader(fd))
+}
diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s b/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
new file mode 100644
index 0000000..469bfa1
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s
@@ -0,0 +1,29 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !gccgo
+
+#include "textflag.h"
+
+//
+// System call support for ARM, OpenBSD
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	B	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	B	syscall·Syscall6(SB)
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	B	syscall·Syscall9(SB)
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-28
+	B	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	B	syscall·RawSyscall6(SB)
diff --git a/vendor/golang.org/x/sys/unix/cap_freebsd.go b/vendor/golang.org/x/sys/unix/cap_freebsd.go
new file mode 100644
index 0000000..83b6bce
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/cap_freebsd.go
@@ -0,0 +1,195 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build freebsd
+
+package unix
+
+import (
+	errorspkg "errors"
+	"fmt"
+)
+
+// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
+
+const (
+	// This is the version of CapRights this package understands. See C implementation for parallels.
+	capRightsGoVersion = CAP_RIGHTS_VERSION_00
+	capArSizeMin       = CAP_RIGHTS_VERSION_00 + 2
+	capArSizeMax       = capRightsGoVersion + 2
+)
+
+var (
+	bit2idx = []int{
+		-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
+		4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	}
+)
+
+func capidxbit(right uint64) int {
+	return int((right >> 57) & 0x1f)
+}
+
+func rightToIndex(right uint64) (int, error) {
+	idx := capidxbit(right)
+	if idx < 0 || idx >= len(bit2idx) {
+		return -2, fmt.Errorf("index for right 0x%x out of range", right)
+	}
+	return bit2idx[idx], nil
+}
+
+func caprver(right uint64) int {
+	return int(right >> 62)
+}
+
+func capver(rights *CapRights) int {
+	return caprver(rights.Rights[0])
+}
+
+func caparsize(rights *CapRights) int {
+	return capver(rights) + 2
+}
+
+// CapRightsSet sets the permissions in setrights in rights.
+func CapRightsSet(rights *CapRights, setrights []uint64) error {
+	// This is essentially a copy of cap_rights_vset()
+	if capver(rights) != CAP_RIGHTS_VERSION_00 {
+		return fmt.Errorf("bad rights version %d", capver(rights))
+	}
+
+	n := caparsize(rights)
+	if n < capArSizeMin || n > capArSizeMax {
+		return errorspkg.New("bad rights size")
+	}
+
+	for _, right := range setrights {
+		if caprver(right) != CAP_RIGHTS_VERSION_00 {
+			return errorspkg.New("bad right version")
+		}
+		i, err := rightToIndex(right)
+		if err != nil {
+			return err
+		}
+		if i >= n {
+			return errorspkg.New("index overflow")
+		}
+		if capidxbit(rights.Rights[i]) != capidxbit(right) {
+			return errorspkg.New("index mismatch")
+		}
+		rights.Rights[i] |= right
+		if capidxbit(rights.Rights[i]) != capidxbit(right) {
+			return errorspkg.New("index mismatch (after assign)")
+		}
+	}
+
+	return nil
+}
+
+// CapRightsClear clears the permissions in clearrights from rights.
+func CapRightsClear(rights *CapRights, clearrights []uint64) error {
+	// This is essentially a copy of cap_rights_vclear()
+	if capver(rights) != CAP_RIGHTS_VERSION_00 {
+		return fmt.Errorf("bad rights version %d", capver(rights))
+	}
+
+	n := caparsize(rights)
+	if n < capArSizeMin || n > capArSizeMax {
+		return errorspkg.New("bad rights size")
+	}
+
+	for _, right := range clearrights {
+		if caprver(right) != CAP_RIGHTS_VERSION_00 {
+			return errorspkg.New("bad right version")
+		}
+		i, err := rightToIndex(right)
+		if err != nil {
+			return err
+		}
+		if i >= n {
+			return errorspkg.New("index overflow")
+		}
+		if capidxbit(rights.Rights[i]) != capidxbit(right) {
+			return errorspkg.New("index mismatch")
+		}
+		rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
+		if capidxbit(rights.Rights[i]) != capidxbit(right) {
+			return errorspkg.New("index mismatch (after assign)")
+		}
+	}
+
+	return nil
+}
+
+// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
+func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
+	// This is essentially a copy of cap_rights_is_vset()
+	if capver(rights) != CAP_RIGHTS_VERSION_00 {
+		return false, fmt.Errorf("bad rights version %d", capver(rights))
+	}
+
+	n := caparsize(rights)
+	if n < capArSizeMin || n > capArSizeMax {
+		return false, errorspkg.New("bad rights size")
+	}
+
+	for _, right := range setrights {
+		if caprver(right) != CAP_RIGHTS_VERSION_00 {
+			return false, errorspkg.New("bad right version")
+		}
+		i, err := rightToIndex(right)
+		if err != nil {
+			return false, err
+		}
+		if i >= n {
+			return false, errorspkg.New("index overflow")
+		}
+		if capidxbit(rights.Rights[i]) != capidxbit(right) {
+			return false, errorspkg.New("index mismatch")
+		}
+		if (rights.Rights[i] & right) != right {
+			return false, nil
+		}
+	}
+
+	return true, nil
+}
+
+func capright(idx uint64, bit uint64) uint64 {
+	return ((1 << (57 + idx)) | bit)
+}
+
+// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
+// See man cap_rights_init(3) and rights(4).
+func CapRightsInit(rights []uint64) (*CapRights, error) {
+	var r CapRights
+	r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
+	r.Rights[1] = capright(1, 0)
+
+	err := CapRightsSet(&r, rights)
+	if err != nil {
+		return nil, err
+	}
+	return &r, nil
+}
+
+// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
+// The capability rights on fd can never be increased by CapRightsLimit.
+// See man cap_rights_limit(2) and rights(4).
+func CapRightsLimit(fd uintptr, rights *CapRights) error {
+	return capRightsLimit(int(fd), rights)
+}
+
+// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
+// See man cap_rights_get(3) and rights(4).
+func CapRightsGet(fd uintptr) (*CapRights, error) {
+	r, err := CapRightsInit(nil)
+	if err != nil {
+		return nil, err
+	}
+	err = capRightsGet(capRightsGoVersion, int(fd), r)
+	if err != nil {
+		return nil, err
+	}
+	return r, nil
+}
diff --git a/vendor/golang.org/x/sys/unix/dev_linux.go b/vendor/golang.org/x/sys/unix/dev_linux.go
new file mode 100644
index 0000000..c902c39
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/dev_linux.go
@@ -0,0 +1,42 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Functions to access/create device major and minor numbers matching the
+// encoding used by the Linux kernel and glibc.
+//
+// The information below is extracted and adapted from bits/sysmacros.h in the
+// glibc sources:
+//
+// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's
+// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major
+// number and m is a hex digit of the minor number. This is backward compatible
+// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also
+// backward compatible with the Linux kernel, which for some architectures uses
+// 32-bit dev_t, encoded as mmmM MMmm.
+
+package unix
+
+// Major returns the major component of a Linux device number.
+func Major(dev uint64) uint32 {
+	major := uint32((dev & 0x00000000000fff00) >> 8)
+	major |= uint32((dev & 0xfffff00000000000) >> 32)
+	return major
+}
+
+// Minor returns the minor component of a Linux device number.
+func Minor(dev uint64) uint32 {
+	minor := uint32((dev & 0x00000000000000ff) >> 0)
+	minor |= uint32((dev & 0x00000ffffff00000) >> 12)
+	return minor
+}
+
+// Mkdev returns a Linux device number generated from the given major and minor
+// components.
+func Mkdev(major, minor uint32) uint64 {
+	dev := uint64((major & 0x00000fff) << 8)
+	dev |= uint64((major & 0xfffff000) << 32)
+	dev |= uint64((minor & 0x000000ff) << 0)
+	dev |= uint64((minor & 0xffffff00) << 12)
+	return dev
+}
diff --git a/vendor/golang.org/x/sys/unix/errors_freebsd_386.go b/vendor/golang.org/x/sys/unix/errors_freebsd_386.go
new file mode 100644
index 0000000..c56bc8b
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/errors_freebsd_386.go
@@ -0,0 +1,227 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
+// them here for backwards compatibility.
+
+package unix
+
+const (
+	IFF_SMART                         = 0x20
+	IFT_1822                          = 0x2
+	IFT_A12MPPSWITCH                  = 0x82
+	IFT_AAL2                          = 0xbb
+	IFT_AAL5                          = 0x31
+	IFT_ADSL                          = 0x5e
+	IFT_AFLANE8023                    = 0x3b
+	IFT_AFLANE8025                    = 0x3c
+	IFT_ARAP                          = 0x58
+	IFT_ARCNET                        = 0x23
+	IFT_ARCNETPLUS                    = 0x24
+	IFT_ASYNC                         = 0x54
+	IFT_ATM                           = 0x25
+	IFT_ATMDXI                        = 0x69
+	IFT_ATMFUNI                       = 0x6a
+	IFT_ATMIMA                        = 0x6b
+	IFT_ATMLOGICAL                    = 0x50
+	IFT_ATMRADIO                      = 0xbd
+	IFT_ATMSUBINTERFACE               = 0x86
+	IFT_ATMVCIENDPT                   = 0xc2
+	IFT_ATMVIRTUAL                    = 0x95
+	IFT_BGPPOLICYACCOUNTING           = 0xa2
+	IFT_BSC                           = 0x53
+	IFT_CCTEMUL                       = 0x3d
+	IFT_CEPT                          = 0x13
+	IFT_CES                           = 0x85
+	IFT_CHANNEL                       = 0x46
+	IFT_CNR                           = 0x55
+	IFT_COFFEE                        = 0x84
+	IFT_COMPOSITELINK                 = 0x9b
+	IFT_DCN                           = 0x8d
+	IFT_DIGITALPOWERLINE              = 0x8a
+	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
+	IFT_DLSW                          = 0x4a
+	IFT_DOCSCABLEDOWNSTREAM           = 0x80
+	IFT_DOCSCABLEMACLAYER             = 0x7f
+	IFT_DOCSCABLEUPSTREAM             = 0x81
+	IFT_DS0                           = 0x51
+	IFT_DS0BUNDLE                     = 0x52
+	IFT_DS1FDL                        = 0xaa
+	IFT_DS3                           = 0x1e
+	IFT_DTM                           = 0x8c
+	IFT_DVBASILN                      = 0xac
+	IFT_DVBASIOUT                     = 0xad
+	IFT_DVBRCCDOWNSTREAM              = 0x93
+	IFT_DVBRCCMACLAYER                = 0x92
+	IFT_DVBRCCUPSTREAM                = 0x94
+	IFT_ENC                           = 0xf4
+	IFT_EON                           = 0x19
+	IFT_EPLRS                         = 0x57
+	IFT_ESCON                         = 0x49
+	IFT_ETHER                         = 0x6
+	IFT_FAITH                         = 0xf2
+	IFT_FAST                          = 0x7d
+	IFT_FASTETHER                     = 0x3e
+	IFT_FASTETHERFX                   = 0x45
+	IFT_FDDI                          = 0xf
+	IFT_FIBRECHANNEL                  = 0x38
+	IFT_FRAMERELAYINTERCONNECT        = 0x3a
+	IFT_FRAMERELAYMPI                 = 0x5c
+	IFT_FRDLCIENDPT                   = 0xc1
+	IFT_FRELAY                        = 0x20
+	IFT_FRELAYDCE                     = 0x2c
+	IFT_FRF16MFRBUNDLE                = 0xa3
+	IFT_FRFORWARD                     = 0x9e
+	IFT_G703AT2MB                     = 0x43
+	IFT_G703AT64K                     = 0x42
+	IFT_GIF                           = 0xf0
+	IFT_GIGABITETHERNET               = 0x75
+	IFT_GR303IDT                      = 0xb2
+	IFT_GR303RDT                      = 0xb1
+	IFT_H323GATEKEEPER                = 0xa4
+	IFT_H323PROXY                     = 0xa5
+	IFT_HDH1822                       = 0x3
+	IFT_HDLC                          = 0x76
+	IFT_HDSL2                         = 0xa8
+	IFT_HIPERLAN2                     = 0xb7
+	IFT_HIPPI                         = 0x2f
+	IFT_HIPPIINTERFACE                = 0x39
+	IFT_HOSTPAD                       = 0x5a
+	IFT_HSSI                          = 0x2e
+	IFT_HY                            = 0xe
+	IFT_IBM370PARCHAN                 = 0x48
+	IFT_IDSL                          = 0x9a
+	IFT_IEEE80211                     = 0x47
+	IFT_IEEE80212                     = 0x37
+	IFT_IEEE8023ADLAG                 = 0xa1
+	IFT_IFGSN                         = 0x91
+	IFT_IMT                           = 0xbe
+	IFT_INTERLEAVE                    = 0x7c
+	IFT_IP                            = 0x7e
+	IFT_IPFORWARD                     = 0x8e
+	IFT_IPOVERATM                     = 0x72
+	IFT_IPOVERCDLC                    = 0x6d
+	IFT_IPOVERCLAW                    = 0x6e
+	IFT_IPSWITCH                      = 0x4e
+	IFT_IPXIP                         = 0xf9
+	IFT_ISDN                          = 0x3f
+	IFT_ISDNBASIC                     = 0x14
+	IFT_ISDNPRIMARY                   = 0x15
+	IFT_ISDNS                         = 0x4b
+	IFT_ISDNU                         = 0x4c
+	IFT_ISO88022LLC                   = 0x29
+	IFT_ISO88023                      = 0x7
+	IFT_ISO88024                      = 0x8
+	IFT_ISO88025                      = 0x9
+	IFT_ISO88025CRFPINT               = 0x62
+	IFT_ISO88025DTR                   = 0x56
+	IFT_ISO88025FIBER                 = 0x73
+	IFT_ISO88026                      = 0xa
+	IFT_ISUP                          = 0xb3
+	IFT_L3IPXVLAN                     = 0x89
+	IFT_LAPB                          = 0x10
+	IFT_LAPD                          = 0x4d
+	IFT_LAPF                          = 0x77
+	IFT_LOCALTALK                     = 0x2a
+	IFT_LOOP                          = 0x18
+	IFT_MEDIAMAILOVERIP               = 0x8b
+	IFT_MFSIGLINK                     = 0xa7
+	IFT_MIOX25                        = 0x26
+	IFT_MODEM                         = 0x30
+	IFT_MPC                           = 0x71
+	IFT_MPLS                          = 0xa6
+	IFT_MPLSTUNNEL                    = 0x96
+	IFT_MSDSL                         = 0x8f
+	IFT_MVL                           = 0xbf
+	IFT_MYRINET                       = 0x63
+	IFT_NFAS                          = 0xaf
+	IFT_NSIP                          = 0x1b
+	IFT_OPTICALCHANNEL                = 0xc3
+	IFT_OPTICALTRANSPORT              = 0xc4
+	IFT_OTHER                         = 0x1
+	IFT_P10                           = 0xc
+	IFT_P80                           = 0xd
+	IFT_PARA                          = 0x22
+	IFT_PFLOG                         = 0xf6
+	IFT_PFSYNC                        = 0xf7
+	IFT_PLC                           = 0xae
+	IFT_POS                           = 0xab
+	IFT_PPPMULTILINKBUNDLE            = 0x6c
+	IFT_PROPBWAP2MP                   = 0xb8
+	IFT_PROPCNLS                      = 0x59
+	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
+	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
+	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
+	IFT_PROPMUX                       = 0x36
+	IFT_PROPWIRELESSP2P               = 0x9d
+	IFT_PTPSERIAL                     = 0x16
+	IFT_PVC                           = 0xf1
+	IFT_QLLC                          = 0x44
+	IFT_RADIOMAC                      = 0xbc
+	IFT_RADSL                         = 0x5f
+	IFT_REACHDSL                      = 0xc0
+	IFT_RFC1483                       = 0x9f
+	IFT_RS232                         = 0x21
+	IFT_RSRB                          = 0x4f
+	IFT_SDLC                          = 0x11
+	IFT_SDSL                          = 0x60
+	IFT_SHDSL                         = 0xa9
+	IFT_SIP                           = 0x1f
+	IFT_SLIP                          = 0x1c
+	IFT_SMDSDXI                       = 0x2b
+	IFT_SMDSICIP                      = 0x34
+	IFT_SONET                         = 0x27
+	IFT_SONETOVERHEADCHANNEL          = 0xb9
+	IFT_SONETPATH                     = 0x32
+	IFT_SONETVT                       = 0x33
+	IFT_SRP                           = 0x97
+	IFT_SS7SIGLINK                    = 0x9c
+	IFT_STACKTOSTACK                  = 0x6f
+	IFT_STARLAN                       = 0xb
+	IFT_STF                           = 0xd7
+	IFT_T1                            = 0x12
+	IFT_TDLC                          = 0x74
+	IFT_TERMPAD                       = 0x5b
+	IFT_TR008                         = 0xb0
+	IFT_TRANSPHDLC                    = 0x7b
+	IFT_TUNNEL                        = 0x83
+	IFT_ULTRA                         = 0x1d
+	IFT_USB                           = 0xa0
+	IFT_V11                           = 0x40
+	IFT_V35                           = 0x2d
+	IFT_V36                           = 0x41
+	IFT_V37                           = 0x78
+	IFT_VDSL                          = 0x61
+	IFT_VIRTUALIPADDRESS              = 0x70
+	IFT_VOICEEM                       = 0x64
+	IFT_VOICEENCAP                    = 0x67
+	IFT_VOICEFXO                      = 0x65
+	IFT_VOICEFXS                      = 0x66
+	IFT_VOICEOVERATM                  = 0x98
+	IFT_VOICEOVERFRAMERELAY           = 0x99
+	IFT_VOICEOVERIP                   = 0x68
+	IFT_X213                          = 0x5d
+	IFT_X25                           = 0x5
+	IFT_X25DDN                        = 0x4
+	IFT_X25HUNTGROUP                  = 0x7a
+	IFT_X25MLP                        = 0x79
+	IFT_X25PLE                        = 0x28
+	IFT_XETHER                        = 0x1a
+	IPPROTO_MAXID                     = 0x34
+	IPV6_FAITH                        = 0x1d
+	IP_FAITH                          = 0x16
+	MAP_NORESERVE                     = 0x40
+	MAP_RENAME                        = 0x20
+	NET_RT_MAXID                      = 0x6
+	RTF_PRCLONING                     = 0x10000
+	RTM_OLDADD                        = 0x9
+	RTM_OLDDEL                        = 0xa
+	SIOCADDRT                         = 0x8030720a
+	SIOCALIFADDR                      = 0x8118691b
+	SIOCDELRT                         = 0x8030720b
+	SIOCDLIFADDR                      = 0x8118691d
+	SIOCGLIFADDR                      = 0xc118691c
+	SIOCGLIFPHYADDR                   = 0xc118694b
+	SIOCSLIFPHYADDR                   = 0x8118694a
+)
diff --git a/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
new file mode 100644
index 0000000..3e97711
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
@@ -0,0 +1,227 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
+// them here for backwards compatibility.
+
+package unix
+
+const (
+	IFF_SMART                         = 0x20
+	IFT_1822                          = 0x2
+	IFT_A12MPPSWITCH                  = 0x82
+	IFT_AAL2                          = 0xbb
+	IFT_AAL5                          = 0x31
+	IFT_ADSL                          = 0x5e
+	IFT_AFLANE8023                    = 0x3b
+	IFT_AFLANE8025                    = 0x3c
+	IFT_ARAP                          = 0x58
+	IFT_ARCNET                        = 0x23
+	IFT_ARCNETPLUS                    = 0x24
+	IFT_ASYNC                         = 0x54
+	IFT_ATM                           = 0x25
+	IFT_ATMDXI                        = 0x69
+	IFT_ATMFUNI                       = 0x6a
+	IFT_ATMIMA                        = 0x6b
+	IFT_ATMLOGICAL                    = 0x50
+	IFT_ATMRADIO                      = 0xbd
+	IFT_ATMSUBINTERFACE               = 0x86
+	IFT_ATMVCIENDPT                   = 0xc2
+	IFT_ATMVIRTUAL                    = 0x95
+	IFT_BGPPOLICYACCOUNTING           = 0xa2
+	IFT_BSC                           = 0x53
+	IFT_CCTEMUL                       = 0x3d
+	IFT_CEPT                          = 0x13
+	IFT_CES                           = 0x85
+	IFT_CHANNEL                       = 0x46
+	IFT_CNR                           = 0x55
+	IFT_COFFEE                        = 0x84
+	IFT_COMPOSITELINK                 = 0x9b
+	IFT_DCN                           = 0x8d
+	IFT_DIGITALPOWERLINE              = 0x8a
+	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
+	IFT_DLSW                          = 0x4a
+	IFT_DOCSCABLEDOWNSTREAM           = 0x80
+	IFT_DOCSCABLEMACLAYER             = 0x7f
+	IFT_DOCSCABLEUPSTREAM             = 0x81
+	IFT_DS0                           = 0x51
+	IFT_DS0BUNDLE                     = 0x52
+	IFT_DS1FDL                        = 0xaa
+	IFT_DS3                           = 0x1e
+	IFT_DTM                           = 0x8c
+	IFT_DVBASILN                      = 0xac
+	IFT_DVBASIOUT                     = 0xad
+	IFT_DVBRCCDOWNSTREAM              = 0x93
+	IFT_DVBRCCMACLAYER                = 0x92
+	IFT_DVBRCCUPSTREAM                = 0x94
+	IFT_ENC                           = 0xf4
+	IFT_EON                           = 0x19
+	IFT_EPLRS                         = 0x57
+	IFT_ESCON                         = 0x49
+	IFT_ETHER                         = 0x6
+	IFT_FAITH                         = 0xf2
+	IFT_FAST                          = 0x7d
+	IFT_FASTETHER                     = 0x3e
+	IFT_FASTETHERFX                   = 0x45
+	IFT_FDDI                          = 0xf
+	IFT_FIBRECHANNEL                  = 0x38
+	IFT_FRAMERELAYINTERCONNECT        = 0x3a
+	IFT_FRAMERELAYMPI                 = 0x5c
+	IFT_FRDLCIENDPT                   = 0xc1
+	IFT_FRELAY                        = 0x20
+	IFT_FRELAYDCE                     = 0x2c
+	IFT_FRF16MFRBUNDLE                = 0xa3
+	IFT_FRFORWARD                     = 0x9e
+	IFT_G703AT2MB                     = 0x43
+	IFT_G703AT64K                     = 0x42
+	IFT_GIF                           = 0xf0
+	IFT_GIGABITETHERNET               = 0x75
+	IFT_GR303IDT                      = 0xb2
+	IFT_GR303RDT                      = 0xb1
+	IFT_H323GATEKEEPER                = 0xa4
+	IFT_H323PROXY                     = 0xa5
+	IFT_HDH1822                       = 0x3
+	IFT_HDLC                          = 0x76
+	IFT_HDSL2                         = 0xa8
+	IFT_HIPERLAN2                     = 0xb7
+	IFT_HIPPI                         = 0x2f
+	IFT_HIPPIINTERFACE                = 0x39
+	IFT_HOSTPAD                       = 0x5a
+	IFT_HSSI                          = 0x2e
+	IFT_HY                            = 0xe
+	IFT_IBM370PARCHAN                 = 0x48
+	IFT_IDSL                          = 0x9a
+	IFT_IEEE80211                     = 0x47
+	IFT_IEEE80212                     = 0x37
+	IFT_IEEE8023ADLAG                 = 0xa1
+	IFT_IFGSN                         = 0x91
+	IFT_IMT                           = 0xbe
+	IFT_INTERLEAVE                    = 0x7c
+	IFT_IP                            = 0x7e
+	IFT_IPFORWARD                     = 0x8e
+	IFT_IPOVERATM                     = 0x72
+	IFT_IPOVERCDLC                    = 0x6d
+	IFT_IPOVERCLAW                    = 0x6e
+	IFT_IPSWITCH                      = 0x4e
+	IFT_IPXIP                         = 0xf9
+	IFT_ISDN                          = 0x3f
+	IFT_ISDNBASIC                     = 0x14
+	IFT_ISDNPRIMARY                   = 0x15
+	IFT_ISDNS                         = 0x4b
+	IFT_ISDNU                         = 0x4c
+	IFT_ISO88022LLC                   = 0x29
+	IFT_ISO88023                      = 0x7
+	IFT_ISO88024                      = 0x8
+	IFT_ISO88025                      = 0x9
+	IFT_ISO88025CRFPINT               = 0x62
+	IFT_ISO88025DTR                   = 0x56
+	IFT_ISO88025FIBER                 = 0x73
+	IFT_ISO88026                      = 0xa
+	IFT_ISUP                          = 0xb3
+	IFT_L3IPXVLAN                     = 0x89
+	IFT_LAPB                          = 0x10
+	IFT_LAPD                          = 0x4d
+	IFT_LAPF                          = 0x77
+	IFT_LOCALTALK                     = 0x2a
+	IFT_LOOP                          = 0x18
+	IFT_MEDIAMAILOVERIP               = 0x8b
+	IFT_MFSIGLINK                     = 0xa7
+	IFT_MIOX25                        = 0x26
+	IFT_MODEM                         = 0x30
+	IFT_MPC                           = 0x71
+	IFT_MPLS                          = 0xa6
+	IFT_MPLSTUNNEL                    = 0x96
+	IFT_MSDSL                         = 0x8f
+	IFT_MVL                           = 0xbf
+	IFT_MYRINET                       = 0x63
+	IFT_NFAS                          = 0xaf
+	IFT_NSIP                          = 0x1b
+	IFT_OPTICALCHANNEL                = 0xc3
+	IFT_OPTICALTRANSPORT              = 0xc4
+	IFT_OTHER                         = 0x1
+	IFT_P10                           = 0xc
+	IFT_P80                           = 0xd
+	IFT_PARA                          = 0x22
+	IFT_PFLOG                         = 0xf6
+	IFT_PFSYNC                        = 0xf7
+	IFT_PLC                           = 0xae
+	IFT_POS                           = 0xab
+	IFT_PPPMULTILINKBUNDLE            = 0x6c
+	IFT_PROPBWAP2MP                   = 0xb8
+	IFT_PROPCNLS                      = 0x59
+	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
+	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
+	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
+	IFT_PROPMUX                       = 0x36
+	IFT_PROPWIRELESSP2P               = 0x9d
+	IFT_PTPSERIAL                     = 0x16
+	IFT_PVC                           = 0xf1
+	IFT_QLLC                          = 0x44
+	IFT_RADIOMAC                      = 0xbc
+	IFT_RADSL                         = 0x5f
+	IFT_REACHDSL                      = 0xc0
+	IFT_RFC1483                       = 0x9f
+	IFT_RS232                         = 0x21
+	IFT_RSRB                          = 0x4f
+	IFT_SDLC                          = 0x11
+	IFT_SDSL                          = 0x60
+	IFT_SHDSL                         = 0xa9
+	IFT_SIP                           = 0x1f
+	IFT_SLIP                          = 0x1c
+	IFT_SMDSDXI                       = 0x2b
+	IFT_SMDSICIP                      = 0x34
+	IFT_SONET                         = 0x27
+	IFT_SONETOVERHEADCHANNEL          = 0xb9
+	IFT_SONETPATH                     = 0x32
+	IFT_SONETVT                       = 0x33
+	IFT_SRP                           = 0x97
+	IFT_SS7SIGLINK                    = 0x9c
+	IFT_STACKTOSTACK                  = 0x6f
+	IFT_STARLAN                       = 0xb
+	IFT_STF                           = 0xd7
+	IFT_T1                            = 0x12
+	IFT_TDLC                          = 0x74
+	IFT_TERMPAD                       = 0x5b
+	IFT_TR008                         = 0xb0
+	IFT_TRANSPHDLC                    = 0x7b
+	IFT_TUNNEL                        = 0x83
+	IFT_ULTRA                         = 0x1d
+	IFT_USB                           = 0xa0
+	IFT_V11                           = 0x40
+	IFT_V35                           = 0x2d
+	IFT_V36                           = 0x41
+	IFT_V37                           = 0x78
+	IFT_VDSL                          = 0x61
+	IFT_VIRTUALIPADDRESS              = 0x70
+	IFT_VOICEEM                       = 0x64
+	IFT_VOICEENCAP                    = 0x67
+	IFT_VOICEFXO                      = 0x65
+	IFT_VOICEFXS                      = 0x66
+	IFT_VOICEOVERATM                  = 0x98
+	IFT_VOICEOVERFRAMERELAY           = 0x99
+	IFT_VOICEOVERIP                   = 0x68
+	IFT_X213                          = 0x5d
+	IFT_X25                           = 0x5
+	IFT_X25DDN                        = 0x4
+	IFT_X25HUNTGROUP                  = 0x7a
+	IFT_X25MLP                        = 0x79
+	IFT_X25PLE                        = 0x28
+	IFT_XETHER                        = 0x1a
+	IPPROTO_MAXID                     = 0x34
+	IPV6_FAITH                        = 0x1d
+	IP_FAITH                          = 0x16
+	MAP_NORESERVE                     = 0x40
+	MAP_RENAME                        = 0x20
+	NET_RT_MAXID                      = 0x6
+	RTF_PRCLONING                     = 0x10000
+	RTM_OLDADD                        = 0x9
+	RTM_OLDDEL                        = 0xa
+	SIOCADDRT                         = 0x8040720a
+	SIOCALIFADDR                      = 0x8118691b
+	SIOCDELRT                         = 0x8040720b
+	SIOCDLIFADDR                      = 0x8118691d
+	SIOCGLIFADDR                      = 0xc118691c
+	SIOCGLIFPHYADDR                   = 0xc118694b
+	SIOCSLIFPHYADDR                   = 0x8118694a
+)
diff --git a/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go b/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go
new file mode 100644
index 0000000..856dca3
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go
@@ -0,0 +1,226 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+const (
+	IFT_1822                          = 0x2
+	IFT_A12MPPSWITCH                  = 0x82
+	IFT_AAL2                          = 0xbb
+	IFT_AAL5                          = 0x31
+	IFT_ADSL                          = 0x5e
+	IFT_AFLANE8023                    = 0x3b
+	IFT_AFLANE8025                    = 0x3c
+	IFT_ARAP                          = 0x58
+	IFT_ARCNET                        = 0x23
+	IFT_ARCNETPLUS                    = 0x24
+	IFT_ASYNC                         = 0x54
+	IFT_ATM                           = 0x25
+	IFT_ATMDXI                        = 0x69
+	IFT_ATMFUNI                       = 0x6a
+	IFT_ATMIMA                        = 0x6b
+	IFT_ATMLOGICAL                    = 0x50
+	IFT_ATMRADIO                      = 0xbd
+	IFT_ATMSUBINTERFACE               = 0x86
+	IFT_ATMVCIENDPT                   = 0xc2
+	IFT_ATMVIRTUAL                    = 0x95
+	IFT_BGPPOLICYACCOUNTING           = 0xa2
+	IFT_BSC                           = 0x53
+	IFT_CCTEMUL                       = 0x3d
+	IFT_CEPT                          = 0x13
+	IFT_CES                           = 0x85
+	IFT_CHANNEL                       = 0x46
+	IFT_CNR                           = 0x55
+	IFT_COFFEE                        = 0x84
+	IFT_COMPOSITELINK                 = 0x9b
+	IFT_DCN                           = 0x8d
+	IFT_DIGITALPOWERLINE              = 0x8a
+	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
+	IFT_DLSW                          = 0x4a
+	IFT_DOCSCABLEDOWNSTREAM           = 0x80
+	IFT_DOCSCABLEMACLAYER             = 0x7f
+	IFT_DOCSCABLEUPSTREAM             = 0x81
+	IFT_DS0                           = 0x51
+	IFT_DS0BUNDLE                     = 0x52
+	IFT_DS1FDL                        = 0xaa
+	IFT_DS3                           = 0x1e
+	IFT_DTM                           = 0x8c
+	IFT_DVBASILN                      = 0xac
+	IFT_DVBASIOUT                     = 0xad
+	IFT_DVBRCCDOWNSTREAM              = 0x93
+	IFT_DVBRCCMACLAYER                = 0x92
+	IFT_DVBRCCUPSTREAM                = 0x94
+	IFT_ENC                           = 0xf4
+	IFT_EON                           = 0x19
+	IFT_EPLRS                         = 0x57
+	IFT_ESCON                         = 0x49
+	IFT_ETHER                         = 0x6
+	IFT_FAST                          = 0x7d
+	IFT_FASTETHER                     = 0x3e
+	IFT_FASTETHERFX                   = 0x45
+	IFT_FDDI                          = 0xf
+	IFT_FIBRECHANNEL                  = 0x38
+	IFT_FRAMERELAYINTERCONNECT        = 0x3a
+	IFT_FRAMERELAYMPI                 = 0x5c
+	IFT_FRDLCIENDPT                   = 0xc1
+	IFT_FRELAY                        = 0x20
+	IFT_FRELAYDCE                     = 0x2c
+	IFT_FRF16MFRBUNDLE                = 0xa3
+	IFT_FRFORWARD                     = 0x9e
+	IFT_G703AT2MB                     = 0x43
+	IFT_G703AT64K                     = 0x42
+	IFT_GIF                           = 0xf0
+	IFT_GIGABITETHERNET               = 0x75
+	IFT_GR303IDT                      = 0xb2
+	IFT_GR303RDT                      = 0xb1
+	IFT_H323GATEKEEPER                = 0xa4
+	IFT_H323PROXY                     = 0xa5
+	IFT_HDH1822                       = 0x3
+	IFT_HDLC                          = 0x76
+	IFT_HDSL2                         = 0xa8
+	IFT_HIPERLAN2                     = 0xb7
+	IFT_HIPPI                         = 0x2f
+	IFT_HIPPIINTERFACE                = 0x39
+	IFT_HOSTPAD                       = 0x5a
+	IFT_HSSI                          = 0x2e
+	IFT_HY                            = 0xe
+	IFT_IBM370PARCHAN                 = 0x48
+	IFT_IDSL                          = 0x9a
+	IFT_IEEE80211                     = 0x47
+	IFT_IEEE80212                     = 0x37
+	IFT_IEEE8023ADLAG                 = 0xa1
+	IFT_IFGSN                         = 0x91
+	IFT_IMT                           = 0xbe
+	IFT_INTERLEAVE                    = 0x7c
+	IFT_IP                            = 0x7e
+	IFT_IPFORWARD                     = 0x8e
+	IFT_IPOVERATM                     = 0x72
+	IFT_IPOVERCDLC                    = 0x6d
+	IFT_IPOVERCLAW                    = 0x6e
+	IFT_IPSWITCH                      = 0x4e
+	IFT_ISDN                          = 0x3f
+	IFT_ISDNBASIC                     = 0x14
+	IFT_ISDNPRIMARY                   = 0x15
+	IFT_ISDNS                         = 0x4b
+	IFT_ISDNU                         = 0x4c
+	IFT_ISO88022LLC                   = 0x29
+	IFT_ISO88023                      = 0x7
+	IFT_ISO88024                      = 0x8
+	IFT_ISO88025                      = 0x9
+	IFT_ISO88025CRFPINT               = 0x62
+	IFT_ISO88025DTR                   = 0x56
+	IFT_ISO88025FIBER                 = 0x73
+	IFT_ISO88026                      = 0xa
+	IFT_ISUP                          = 0xb3
+	IFT_L3IPXVLAN                     = 0x89
+	IFT_LAPB                          = 0x10
+	IFT_LAPD                          = 0x4d
+	IFT_LAPF                          = 0x77
+	IFT_LOCALTALK                     = 0x2a
+	IFT_LOOP                          = 0x18
+	IFT_MEDIAMAILOVERIP               = 0x8b
+	IFT_MFSIGLINK                     = 0xa7
+	IFT_MIOX25                        = 0x26
+	IFT_MODEM                         = 0x30
+	IFT_MPC                           = 0x71
+	IFT_MPLS                          = 0xa6
+	IFT_MPLSTUNNEL                    = 0x96
+	IFT_MSDSL                         = 0x8f
+	IFT_MVL                           = 0xbf
+	IFT_MYRINET                       = 0x63
+	IFT_NFAS                          = 0xaf
+	IFT_NSIP                          = 0x1b
+	IFT_OPTICALCHANNEL                = 0xc3
+	IFT_OPTICALTRANSPORT              = 0xc4
+	IFT_OTHER                         = 0x1
+	IFT_P10                           = 0xc
+	IFT_P80                           = 0xd
+	IFT_PARA                          = 0x22
+	IFT_PFLOG                         = 0xf6
+	IFT_PFSYNC                        = 0xf7
+	IFT_PLC                           = 0xae
+	IFT_POS                           = 0xab
+	IFT_PPPMULTILINKBUNDLE            = 0x6c
+	IFT_PROPBWAP2MP                   = 0xb8
+	IFT_PROPCNLS                      = 0x59
+	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
+	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
+	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
+	IFT_PROPMUX                       = 0x36
+	IFT_PROPWIRELESSP2P               = 0x9d
+	IFT_PTPSERIAL                     = 0x16
+	IFT_PVC                           = 0xf1
+	IFT_QLLC                          = 0x44
+	IFT_RADIOMAC                      = 0xbc
+	IFT_RADSL                         = 0x5f
+	IFT_REACHDSL                      = 0xc0
+	IFT_RFC1483                       = 0x9f
+	IFT_RS232                         = 0x21
+	IFT_RSRB                          = 0x4f
+	IFT_SDLC                          = 0x11
+	IFT_SDSL                          = 0x60
+	IFT_SHDSL                         = 0xa9
+	IFT_SIP                           = 0x1f
+	IFT_SLIP                          = 0x1c
+	IFT_SMDSDXI                       = 0x2b
+	IFT_SMDSICIP                      = 0x34
+	IFT_SONET                         = 0x27
+	IFT_SONETOVERHEADCHANNEL          = 0xb9
+	IFT_SONETPATH                     = 0x32
+	IFT_SONETVT                       = 0x33
+	IFT_SRP                           = 0x97
+	IFT_SS7SIGLINK                    = 0x9c
+	IFT_STACKTOSTACK                  = 0x6f
+	IFT_STARLAN                       = 0xb
+	IFT_STF                           = 0xd7
+	IFT_T1                            = 0x12
+	IFT_TDLC                          = 0x74
+	IFT_TERMPAD                       = 0x5b
+	IFT_TR008                         = 0xb0
+	IFT_TRANSPHDLC                    = 0x7b
+	IFT_TUNNEL                        = 0x83
+	IFT_ULTRA                         = 0x1d
+	IFT_USB                           = 0xa0
+	IFT_V11                           = 0x40
+	IFT_V35                           = 0x2d
+	IFT_V36                           = 0x41
+	IFT_V37                           = 0x78
+	IFT_VDSL                          = 0x61
+	IFT_VIRTUALIPADDRESS              = 0x70
+	IFT_VOICEEM                       = 0x64
+	IFT_VOICEENCAP                    = 0x67
+	IFT_VOICEFXO                      = 0x65
+	IFT_VOICEFXS                      = 0x66
+	IFT_VOICEOVERATM                  = 0x98
+	IFT_VOICEOVERFRAMERELAY           = 0x99
+	IFT_VOICEOVERIP                   = 0x68
+	IFT_X213                          = 0x5d
+	IFT_X25                           = 0x5
+	IFT_X25DDN                        = 0x4
+	IFT_X25HUNTGROUP                  = 0x7a
+	IFT_X25MLP                        = 0x79
+	IFT_X25PLE                        = 0x28
+	IFT_XETHER                        = 0x1a
+
+	// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
+	IFF_SMART       = 0x20
+	IFT_FAITH       = 0xf2
+	IFT_IPXIP       = 0xf9
+	IPPROTO_MAXID   = 0x34
+	IPV6_FAITH      = 0x1d
+	IP_FAITH        = 0x16
+	MAP_NORESERVE   = 0x40
+	MAP_RENAME      = 0x20
+	NET_RT_MAXID    = 0x6
+	RTF_PRCLONING   = 0x10000
+	RTM_OLDADD      = 0x9
+	RTM_OLDDEL      = 0xa
+	SIOCADDRT       = 0x8030720a
+	SIOCALIFADDR    = 0x8118691b
+	SIOCDELRT       = 0x8030720b
+	SIOCDLIFADDR    = 0x8118691d
+	SIOCGLIFADDR    = 0xc118691c
+	SIOCGLIFPHYADDR = 0xc118694b
+	SIOCSLIFPHYADDR = 0x8118694a
+)
diff --git a/vendor/golang.org/x/sys/unix/file_unix.go b/vendor/golang.org/x/sys/unix/file_unix.go
new file mode 100644
index 0000000..47f6a83
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/file_unix.go
@@ -0,0 +1,27 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"os"
+	"syscall"
+)
+
+// FIXME: unexported function from os
+// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
+func syscallMode(i os.FileMode) (o uint32) {
+	o |= uint32(i.Perm())
+	if i&os.ModeSetuid != 0 {
+		o |= syscall.S_ISUID
+	}
+	if i&os.ModeSetgid != 0 {
+		o |= syscall.S_ISGID
+	}
+	if i&os.ModeSticky != 0 {
+		o |= syscall.S_ISVTX
+	}
+	// No mapping for Go's ModeTemporary (plan9 only).
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/flock.go b/vendor/golang.org/x/sys/unix/flock.go
index ce67a59..2994ce7 100644
--- a/vendor/golang.org/x/sys/unix/flock.go
+++ b/vendor/golang.org/x/sys/unix/flock.go
@@ -1,5 +1,3 @@
-// +build linux darwin freebsd openbsd netbsd dragonfly
-
 // Copyright 2014 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.
diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go
index ccb29c7..c2846b3 100644
--- a/vendor/golang.org/x/sys/unix/syscall_bsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go
@@ -561,13 +561,19 @@
 
 func UtimesNano(path string, ts []Timespec) error {
 	if ts == nil {
+		err := utimensat(AT_FDCWD, path, nil, 0)
+		if err != ENOSYS {
+			return err
+		}
 		return utimes(path, nil)
 	}
-	// TODO: The BSDs can do utimensat with SYS_UTIMENSAT but it
-	// isn't supported by darwin so this uses utimes instead
 	if len(ts) != 2 {
 		return EINVAL
 	}
+	err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
+	if err != ENOSYS {
+		return err
+	}
 	// Not as efficient as it could be because Timespec and
 	// Timeval have different types in the different OSes
 	tv := [2]Timeval{
@@ -577,6 +583,16 @@
 	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
 }
 
+func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
+	if ts == nil {
+		return utimensat(dirfd, path, nil, flags)
+	}
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
+}
+
 //sys	futimes(fd int, timeval *[2]Timeval) (err error)
 
 func Futimes(fd int, tv []Timeval) error {
@@ -594,9 +610,6 @@
 // TODO: wrap
 //	Acct(name nil-string) (err error)
 //	Gethostuuid(uuid *byte, timeout *Timespec) (err error)
-//	Madvise(addr *byte, len int, behav int) (err error)
-//	Mprotect(addr *byte, len int, prot int) (err error)
-//	Msync(addr *byte, len int, flags int) (err error)
 //	Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
 
 var mapper = &mmapper{
@@ -612,3 +625,11 @@
 func Munmap(b []byte) (err error) {
 	return mapper.Munmap(b)
 }
+
+//sys	Madvise(b []byte, behav int) (err error)
+//sys	Mlock(b []byte) (err error)
+//sys	Mlockall(flags int) (err error)
+//sys	Mprotect(b []byte, prot int) (err error)
+//sys	Msync(b []byte, flags int) (err error)
+//sys	Munlock(b []byte) (err error)
+//sys	Munlockall() (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go
index 7d91ac0..ad74a11 100644
--- a/vendor/golang.org/x/sys/unix/syscall_darwin.go
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go
@@ -187,6 +187,11 @@
 	return
 }
 
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) error {
+	// Darwin doesn't support SYS_UTIMENSAT
+	return ENOSYS
+}
+
 /*
  * Wrapped
  */
@@ -195,6 +200,45 @@
 
 func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }
 
+//sys	ioctl(fd int, req uint, arg uintptr) (err error)
+
+// ioctl itself should not be exposed directly, but additional get/set
+// functions for specific types are permissible.
+
+// IoctlSetInt performs an ioctl operation which sets an integer value
+// on fd, using the specified request number.
+func IoctlSetInt(fd int, req uint, value int) error {
+	return ioctl(fd, req, uintptr(value))
+}
+
+func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
+	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
+}
+
+func IoctlSetTermios(fd int, req uint, value *Termios) error {
+	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
+}
+
+// IoctlGetInt performs an ioctl operation which gets an integer value
+// from fd, using the specified request number.
+func IoctlGetInt(fd int, req uint) (int, error) {
+	var value int
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return value, err
+}
+
+func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
+	var value Winsize
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
+func IoctlGetTermios(fd int, req uint) (*Termios, error) {
+	var value Termios
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
 /*
  * Exposed directly
  */
@@ -210,10 +254,13 @@
 //sys	Dup2(from int, to int) (err error)
 //sys	Exchangedata(path1 string, path2 string, options int) (err error)
 //sys	Exit(code int)
+//sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
 //sys	Fchdir(fd int) (err error)
 //sys	Fchflags(fd int, flags int) (err error)
 //sys	Fchmod(fd int, mode uint32) (err error)
+//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
+//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
 //sys	Flock(fd int, how int) (err error)
 //sys	Fpathconf(fd int, name int) (val int, err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
@@ -238,23 +285,23 @@
 //sys	Kqueue() (fd int, err error)
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Link(path string, link string) (err error)
+//sys	Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
 //sys	Listen(s int, backlog int) (err error)
 //sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
 //sys	Mkdir(path string, mode uint32) (err error)
+//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
 //sys	Mkfifo(path string, mode uint32) (err error)
 //sys	Mknod(path string, mode uint32, dev int) (err error)
-//sys	Mlock(b []byte) (err error)
-//sys	Mlockall(flags int) (err error)
-//sys	Mprotect(b []byte, prot int) (err error)
-//sys	Munlock(b []byte) (err error)
-//sys	Munlockall() (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
+//sys	Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error)
 //sys	Pathconf(path string, name int) (val int, err error)
 //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
 //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
 //sys	read(fd int, p []byte) (n int, err error)
 //sys	Readlink(path string, buf []byte) (n int, err error)
+//sys	Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
 //sys	Rename(from string, to string) (err error)
+//sys	Renameat(fromfd int, from string, tofd int, to string) (err error)
 //sys	Revoke(path string) (err error)
 //sys	Rmdir(path string) (err error)
 //sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
@@ -275,11 +322,13 @@
 //sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
 //sys	Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
 //sys	Symlink(path string, link string) (err error)
+//sys	Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
 //sys	Sync() (err error)
 //sys	Truncate(path string, length int64) (err error)
 //sys	Umask(newmask int) (oldmask int)
 //sys	Undelete(path string) (err error)
 //sys	Unlink(path string) (err error)
+//sys	Unlinkat(dirfd int, path string, flags int) (err error)
 //sys	Unmount(path string, flags int) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
 //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
@@ -319,9 +368,6 @@
 // Add_profil
 // Kdebug_trace
 // Sigreturn
-// Mmap
-// Mlock
-// Munlock
 // Atsocket
 // Kqueue_from_portset_np
 // Kqueue_portset
@@ -414,8 +460,6 @@
 // Lio_listio
 // __pthread_cond_wait
 // Iopolicysys
-// Mlockall
-// Munlockall
 // __pthread_kill
 // __pthread_sigmask
 // __sigwait
@@ -469,7 +513,6 @@
 // Sendmsg_nocancel
 // Recvfrom_nocancel
 // Accept_nocancel
-// Msync_nocancel
 // Fcntl_nocancel
 // Select_nocancel
 // Fsync_nocancel
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
index fc1e5a4..c6c99c1 100644
--- a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
@@ -11,8 +11,6 @@
 	"unsafe"
 )
 
-//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
-
 func Getpagesize() int { return 4096 }
 
 func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
index 7e0210f..3a48337 100644
--- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
+++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go
@@ -174,11 +174,6 @@
 //sys	Mkdir(path string, mode uint32) (err error)
 //sys	Mkfifo(path string, mode uint32) (err error)
 //sys	Mknod(path string, mode uint32, dev int) (err error)
-//sys	Mlock(b []byte) (err error)
-//sys	Mlockall(flags int) (err error)
-//sys	Mprotect(b []byte, prot int) (err error)
-//sys	Munlock(b []byte) (err error)
-//sys	Munlockall() (err error)
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
 //sys	Pathconf(path string, name int) (val int, err error)
@@ -218,6 +213,7 @@
 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
 //sys	accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
 
 /*
  * Unimplemented
@@ -252,9 +248,6 @@
 // Add_profil
 // Kdebug_trace
 // Sigreturn
-// Mmap
-// Mlock
-// Munlock
 // Atsocket
 // Kqueue_from_portset_np
 // Kqueue_portset
@@ -347,8 +340,6 @@
 // Lio_listio
 // __pthread_cond_wait
 // Iopolicysys
-// Mlockall
-// Munlockall
 // __pthread_kill
 // __pthread_sigmask
 // __sigwait
@@ -401,7 +392,6 @@
 // Sendmsg_nocancel
 // Recvfrom_nocancel
 // Accept_nocancel
-// Msync_nocancel
 // Fcntl_nocancel
 // Select_nocancel
 // Fsync_nocancel
diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
index 077d1f3..d26e52e 100644
--- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go
@@ -352,11 +352,53 @@
 	return s, e
 }
 
+//sys   ioctl(fd int, req uint, arg uintptr) (err error)
+
+// ioctl itself should not be exposed directly, but additional get/set
+// functions for specific types are permissible.
+
+// IoctlSetInt performs an ioctl operation which sets an integer value
+// on fd, using the specified request number.
+func IoctlSetInt(fd int, req uint, value int) error {
+	return ioctl(fd, req, uintptr(value))
+}
+
+func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
+	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
+}
+
+func IoctlSetTermios(fd int, req uint, value *Termios) error {
+	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
+}
+
+// IoctlGetInt performs an ioctl operation which gets an integer value
+// from fd, using the specified request number.
+func IoctlGetInt(fd int, req uint) (int, error) {
+	var value int
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return value, err
+}
+
+func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
+	var value Winsize
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
+func IoctlGetTermios(fd int, req uint) (*Termios, error) {
+	var value Termios
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
 /*
  * Exposed directly
  */
 //sys	Access(path string, mode uint32) (err error)
 //sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
+//sys	CapEnter() (err error)
+//sys	capRightsGet(version int, fd int, rightsp *CapRights) (err error) = SYS___CAP_RIGHTS_GET
+//sys	capRightsLimit(fd int, rightsp *CapRights) (err error)
 //sys	Chdir(path string) (err error)
 //sys	Chflags(path string, flags int) (err error)
 //sys	Chmod(path string, mode uint32) (err error)
@@ -379,10 +421,13 @@
 //sys	ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error)
 //sys	ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)
 //sys	Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE
+//sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
 //sys	Fchdir(fd int) (err error)
 //sys	Fchflags(fd int, flags int) (err error)
 //sys	Fchmod(fd int, mode uint32) (err error)
+//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
+//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
 //sys	Flock(fd int, how int) (err error)
 //sys	Fpathconf(fd int, name int) (val int, err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error)
@@ -409,24 +454,24 @@
 //sys	Kqueue() (fd int, err error)
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Link(path string, link string) (err error)
+//sys	Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
 //sys	Listen(s int, backlog int) (err error)
 //sys	Lstat(path string, stat *Stat_t) (err error)
 //sys	Mkdir(path string, mode uint32) (err error)
+//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
 //sys	Mkfifo(path string, mode uint32) (err error)
 //sys	Mknod(path string, mode uint32, dev int) (err error)
-//sys	Mlock(b []byte) (err error)
-//sys	Mlockall(flags int) (err error)
-//sys	Mprotect(b []byte, prot int) (err error)
-//sys	Munlock(b []byte) (err error)
-//sys	Munlockall() (err error)
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
+//sys	Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
 //sys	Pathconf(path string, name int) (val int, err error)
 //sys	Pread(fd int, p []byte, offset int64) (n int, err error)
 //sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
 //sys	read(fd int, p []byte) (n int, err error)
 //sys	Readlink(path string, buf []byte) (n int, err error)
+//sys	Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
 //sys	Rename(from string, to string) (err error)
+//sys	Renameat(fromfd int, from string, tofd int, to string) (err error)
 //sys	Revoke(path string) (err error)
 //sys	Rmdir(path string) (err error)
 //sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
@@ -448,11 +493,13 @@
 //sys	Stat(path string, stat *Stat_t) (err error)
 //sys	Statfs(path string, stat *Statfs_t) (err error)
 //sys	Symlink(path string, link string) (err error)
+//sys	Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
 //sys	Sync() (err error)
 //sys	Truncate(path string, length int64) (err error)
 //sys	Umask(newmask int) (oldmask int)
 //sys	Undelete(path string) (err error)
 //sys	Unlink(path string) (err error)
+//sys	Unlinkat(dirfd int, path string, flags int) (err error)
 //sys	Unmount(path string, flags int) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
 //sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
@@ -460,6 +507,7 @@
 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
 //sys	accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
 
 /*
  * Unimplemented
@@ -493,9 +541,6 @@
 // Add_profil
 // Kdebug_trace
 // Sigreturn
-// Mmap
-// Mlock
-// Munlock
 // Atsocket
 // Kqueue_from_portset_np
 // Kqueue_portset
@@ -588,8 +633,6 @@
 // Lio_listio
 // __pthread_cond_wait
 // Iopolicysys
-// Mlockall
-// Munlockall
 // __pthread_kill
 // __pthread_sigmask
 // __sigwait
@@ -642,7 +685,6 @@
 // Sendmsg_nocancel
 // Recvfrom_nocancel
 // Accept_nocancel
-// Msync_nocancel
 // Fcntl_nocancel
 // Select_nocancel
 // Fsync_nocancel
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index cc618f7..2afe62b 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -57,11 +57,15 @@
 
 // IoctlSetInt performs an ioctl operation which sets an integer value
 // on fd, using the specified request number.
-func IoctlSetInt(fd int, req uint, value int) (err error) {
+func IoctlSetInt(fd int, req uint, value int) error {
 	return ioctl(fd, req, uintptr(value))
 }
 
-func IoctlSetTermios(fd int, req uint, value *Termios) (err error) {
+func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
+	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
+}
+
+func IoctlSetTermios(fd int, req uint, value *Termios) error {
 	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 }
 
@@ -73,6 +77,12 @@
 	return value, err
 }
 
+func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
+	var value Winsize
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
+	return &value, err
+}
+
 func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 	var value Termios
 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
@@ -342,10 +352,14 @@
 	return
 }
 
-func Mkfifo(path string, mode uint32) (err error) {
+func Mkfifo(path string, mode uint32) error {
 	return Mknod(path, mode|S_IFIFO, 0)
 }
 
+func Mkfifoat(dirfd int, path string, mode uint32) error {
+	return Mknodat(dirfd, path, mode|S_IFIFO, 0)
+}
+
 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	if sa.Port < 0 || sa.Port > 0xFFFF {
 		return nil, 0, EINVAL
@@ -1265,6 +1279,7 @@
 //sys	Setpriority(which int, who int, prio int) (err error)
 //sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
 //sys	Sync()
+//sys	Syncfs(fd int) (err error)
 //sysnb	Sysinfo(info *Sysinfo_t) (err error)
 //sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
 //sysnb	Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
@@ -1299,8 +1314,9 @@
 //sys	Madvise(b []byte, advice int) (err error)
 //sys	Mprotect(b []byte, prot int) (err error)
 //sys	Mlock(b []byte) (err error)
-//sys	Munlock(b []byte) (err error)
 //sys	Mlockall(flags int) (err error)
+//sys	Msync(b []byte, flags int) (err error)
+//sys	Munlock(b []byte) (err error)
 //sys	Munlockall() (err error)
 
 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
@@ -1368,7 +1384,6 @@
 // ModifyLdt
 // Mount
 // MovePages
-// Mprotect
 // MqGetsetattr
 // MqNotify
 // MqOpen
@@ -1380,7 +1395,6 @@
 // Msgget
 // Msgrcv
 // Msgsnd
-// Msync
 // Newfstatat
 // Nfsservctl
 // Personality
diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
index 01f6a48..e129668 100644
--- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
@@ -170,11 +170,6 @@
 //sys	Mkdir(path string, mode uint32) (err error)
 //sys	Mkfifo(path string, mode uint32) (err error)
 //sys	Mknod(path string, mode uint32, dev int) (err error)
-//sys	Mlock(b []byte) (err error)
-//sys	Mlockall(flags int) (err error)
-//sys	Mprotect(b []byte, prot int) (err error)
-//sys	Munlock(b []byte) (err error)
-//sys	Munlockall() (err error)
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
 //sys	Pathconf(path string, name int) (val int, err error)
@@ -210,6 +205,7 @@
 //sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
 
 /*
  * Unimplemented
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
index c0d2b6c..408e630 100644
--- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go
@@ -149,11 +149,6 @@
 //sys	Mkdir(path string, mode uint32) (err error)
 //sys	Mkfifo(path string, mode uint32) (err error)
 //sys	Mknod(path string, mode uint32, dev int) (err error)
-//sys	Mlock(b []byte) (err error)
-//sys	Mlockall(flags int) (err error)
-//sys	Mprotect(b []byte, prot int) (err error)
-//sys	Munlock(b []byte) (err error)
-//sys	Munlockall() (err error)
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
 //sys	Pathconf(path string, name int) (val int, err error)
@@ -193,6 +188,7 @@
 //sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
 //sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
+//sys	utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
 
 /*
  * Unimplemented
@@ -282,6 +278,5 @@
 // thrsleep
 // thrwakeup
 // unlinkat
-// utimensat
 // vfork
 // writev
diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
new file mode 100644
index 0000000..14ddaf3
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/syscall_openbsd_arm.go
@@ -0,0 +1,44 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build arm,openbsd
+
+package unix
+
+import "syscall"
+
+func Getpagesize() int { return syscall.Getpagesize() }
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = int64(nsec / 1e9)
+	ts.Nsec = int32(nsec % 1e9)
+	return
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	nsec += 999 // round up to microsecond
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	tv.Sec = int64(nsec / 1e9)
+	return
+}
+
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+	k.Ident = uint32(fd)
+	k.Filter = int16(mode)
+	k.Flags = uint16(flags)
+}
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint32(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go
index 4b8ddab..0d4e5c4 100644
--- a/vendor/golang.org/x/sys/unix/syscall_solaris.go
+++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go
@@ -581,6 +581,7 @@
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
 //sys	Fdatasync(fd int) (err error)
+//sys Flock(fd int, how int) (err error)
 //sys	Fpathconf(fd int, name int) (val int, err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error)
 //sys	Fstatvfs(fd int, vfsstat *Statvfs_t) (err error)
diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go
index 8e63888..1c68758 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_386.go
@@ -1,5 +1,5 @@
 // mkerrors.sh -m32
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build 386,darwin
 
@@ -48,6 +48,7 @@
 	AF_UNIX                           = 0x1
 	AF_UNSPEC                         = 0x0
 	AF_UTUN                           = 0x26
+	ALTWERASE                         = 0x200
 	B0                                = 0x0
 	B110                              = 0x6e
 	B115200                           = 0x1c200
@@ -138,9 +139,26 @@
 	BPF_W                             = 0x0
 	BPF_X                             = 0x8
 	BRKINT                            = 0x2
+	BS0                               = 0x0
+	BS1                               = 0x8000
+	BSDLY                             = 0x8000
 	CFLUSH                            = 0xf
 	CLOCAL                            = 0x8000
+	CLOCK_MONOTONIC                   = 0x6
+	CLOCK_MONOTONIC_RAW               = 0x4
+	CLOCK_MONOTONIC_RAW_APPROX        = 0x5
+	CLOCK_PROCESS_CPUTIME_ID          = 0xc
+	CLOCK_REALTIME                    = 0x0
+	CLOCK_THREAD_CPUTIME_ID           = 0x10
+	CLOCK_UPTIME_RAW                  = 0x8
+	CLOCK_UPTIME_RAW_APPROX           = 0x9
+	CR0                               = 0x0
+	CR1                               = 0x1000
+	CR2                               = 0x2000
+	CR3                               = 0x3000
+	CRDLY                             = 0x3000
 	CREAD                             = 0x800
+	CRTSCTS                           = 0x30000
 	CS5                               = 0x0
 	CS6                               = 0x100
 	CS7                               = 0x200
@@ -332,13 +350,14 @@
 	ECHONL                            = 0x10
 	ECHOPRT                           = 0x20
 	EVFILT_AIO                        = -0x3
+	EVFILT_EXCEPT                     = -0xf
 	EVFILT_FS                         = -0x9
 	EVFILT_MACHPORT                   = -0x8
 	EVFILT_PROC                       = -0x5
 	EVFILT_READ                       = -0x1
 	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xe
-	EVFILT_THREADMARKER               = 0xe
+	EVFILT_SYSCOUNT                   = 0xf
+	EVFILT_THREADMARKER               = 0xf
 	EVFILT_TIMER                      = -0x7
 	EVFILT_USER                       = -0xa
 	EVFILT_VM                         = -0xc
@@ -349,6 +368,7 @@
 	EV_DELETE                         = 0x2
 	EV_DISABLE                        = 0x8
 	EV_DISPATCH                       = 0x80
+	EV_DISPATCH2                      = 0x180
 	EV_ENABLE                         = 0x4
 	EV_EOF                            = 0x8000
 	EV_ERROR                          = 0x4000
@@ -359,16 +379,25 @@
 	EV_POLL                           = 0x1000
 	EV_RECEIPT                        = 0x40
 	EV_SYSFLAGS                       = 0xf000
+	EV_UDATA_SPECIFIC                 = 0x100
+	EV_VANISHED                       = 0x200
 	EXTA                              = 0x4b00
 	EXTB                              = 0x9600
 	EXTPROC                           = 0x800
 	FD_CLOEXEC                        = 0x1
 	FD_SETSIZE                        = 0x400
+	FF0                               = 0x0
+	FF1                               = 0x4000
+	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
 	F_ADDFILESIGS                     = 0x3d
+	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
+	F_ADDFILESIGS_RETURN              = 0x61
 	F_ADDSIGS                         = 0x3b
 	F_ALLOCATEALL                     = 0x4
 	F_ALLOCATECONTIG                  = 0x2
+	F_BARRIERFSYNC                    = 0x55
+	F_CHECK_LV                        = 0x62
 	F_CHKCLEAN                        = 0x29
 	F_DUPFD                           = 0x0
 	F_DUPFD_CLOEXEC                   = 0x43
@@ -770,11 +799,13 @@
 	MADV_FREE_REUSABLE                = 0x7
 	MADV_FREE_REUSE                   = 0x8
 	MADV_NORMAL                       = 0x0
+	MADV_PAGEOUT                      = 0xa
 	MADV_RANDOM                       = 0x1
 	MADV_SEQUENTIAL                   = 0x2
 	MADV_WILLNEED                     = 0x3
 	MADV_ZERO_WIRED_PAGES             = 0x6
 	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
 	MAP_COPY                          = 0x2
 	MAP_FILE                          = 0x0
 	MAP_FIXED                         = 0x10
@@ -786,9 +817,43 @@
 	MAP_PRIVATE                       = 0x2
 	MAP_RENAME                        = 0x20
 	MAP_RESERVED0080                  = 0x80
+	MAP_RESILIENT_CODESIGN            = 0x2000
+	MAP_RESILIENT_MEDIA               = 0x4000
 	MAP_SHARED                        = 0x1
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
+	MNT_ASYNC                         = 0x40
+	MNT_AUTOMOUNTED                   = 0x400000
+	MNT_CMDFLAGS                      = 0xf0000
+	MNT_CPROTECT                      = 0x80
+	MNT_DEFWRITE                      = 0x2000000
+	MNT_DONTBROWSE                    = 0x100000
+	MNT_DOVOLFS                       = 0x8000
+	MNT_DWAIT                         = 0x4
+	MNT_EXPORTED                      = 0x100
+	MNT_FORCE                         = 0x80000
+	MNT_IGNORE_OWNERSHIP              = 0x200000
+	MNT_JOURNALED                     = 0x800000
+	MNT_LOCAL                         = 0x1000
+	MNT_MULTILABEL                    = 0x4000000
+	MNT_NOATIME                       = 0x10000000
+	MNT_NOBLOCK                       = 0x20000
+	MNT_NODEV                         = 0x10
+	MNT_NOEXEC                        = 0x4
+	MNT_NOSUID                        = 0x8
+	MNT_NOUSERXATTR                   = 0x1000000
+	MNT_NOWAIT                        = 0x2
+	MNT_QUARANTINE                    = 0x400
+	MNT_QUOTA                         = 0x2000
+	MNT_RDONLY                        = 0x1
+	MNT_RELOAD                        = 0x40000
+	MNT_ROOTFS                        = 0x4000
+	MNT_SYNCHRONOUS                   = 0x2
+	MNT_UNION                         = 0x20
+	MNT_UNKNOWNPERMISSIONS            = 0x200000
+	MNT_UPDATE                        = 0x10000
+	MNT_VISFLAGMASK                   = 0x17f0f5ff
+	MNT_WAIT                          = 0x1
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
 	MSG_DONTWAIT                      = 0x80
@@ -819,7 +884,13 @@
 	NET_RT_MAXID                      = 0xa
 	NET_RT_STAT                       = 0x4
 	NET_RT_TRASH                      = 0x5
+	NL0                               = 0x0
+	NL1                               = 0x100
+	NL2                               = 0x200
+	NL3                               = 0x300
+	NLDLY                             = 0x300
 	NOFLSH                            = 0x80000000
+	NOKERNINFO                        = 0x2000000
 	NOTE_ABSOLUTE                     = 0x8
 	NOTE_ATTRIB                       = 0x8
 	NOTE_BACKGROUND                   = 0x40
@@ -843,11 +914,14 @@
 	NOTE_FFNOP                        = 0x0
 	NOTE_FFOR                         = 0x80000000
 	NOTE_FORK                         = 0x40000000
+	NOTE_FUNLOCK                      = 0x100
 	NOTE_LEEWAY                       = 0x10
 	NOTE_LINK                         = 0x10
 	NOTE_LOWAT                        = 0x1
+	NOTE_MACH_CONTINUOUS_TIME         = 0x80
 	NOTE_NONE                         = 0x80
 	NOTE_NSECONDS                     = 0x4
+	NOTE_OOB                          = 0x2
 	NOTE_PCTRLMASK                    = -0x100000
 	NOTE_PDATAMASK                    = 0xfffff
 	NOTE_REAP                         = 0x10000000
@@ -872,6 +946,7 @@
 	ONOCR                             = 0x20
 	ONOEOT                            = 0x8
 	OPOST                             = 0x1
+	OXTABS                            = 0x4
 	O_ACCMODE                         = 0x3
 	O_ALERT                           = 0x20000000
 	O_APPEND                          = 0x8
@@ -880,6 +955,7 @@
 	O_CREAT                           = 0x200
 	O_DIRECTORY                       = 0x100000
 	O_DP_GETRAWENCRYPTED              = 0x1
+	O_DP_GETRAWUNENCRYPTED            = 0x2
 	O_DSYNC                           = 0x400000
 	O_EVTONLY                         = 0x8000
 	O_EXCL                            = 0x800
@@ -932,7 +1008,10 @@
 	RLIMIT_CPU_USAGE_MONITOR          = 0x2
 	RLIMIT_DATA                       = 0x2
 	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_MEMLOCK                    = 0x6
 	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_NPROC                      = 0x7
+	RLIMIT_RSS                        = 0x5
 	RLIMIT_STACK                      = 0x3
 	RLIM_INFINITY                     = 0x7fffffffffffffff
 	RTAX_AUTHOR                       = 0x6
@@ -1102,6 +1181,8 @@
 	SO_LABEL                          = 0x1010
 	SO_LINGER                         = 0x80
 	SO_LINGER_SEC                     = 0x1080
+	SO_NETSVC_MARKING_LEVEL           = 0x1119
+	SO_NET_SERVICE_TYPE               = 0x1116
 	SO_NKE                            = 0x1021
 	SO_NOADDRERR                      = 0x1023
 	SO_NOSIGPIPE                      = 0x1022
@@ -1157,11 +1238,22 @@
 	S_IXGRP                           = 0x8
 	S_IXOTH                           = 0x1
 	S_IXUSR                           = 0x40
+	TAB0                              = 0x0
+	TAB1                              = 0x400
+	TAB2                              = 0x800
+	TAB3                              = 0x4
+	TABDLY                            = 0xc04
 	TCIFLUSH                          = 0x1
+	TCIOFF                            = 0x3
 	TCIOFLUSH                         = 0x3
+	TCION                             = 0x4
 	TCOFLUSH                          = 0x2
+	TCOOFF                            = 0x1
+	TCOON                             = 0x2
 	TCP_CONNECTIONTIMEOUT             = 0x20
+	TCP_CONNECTION_INFO               = 0x106
 	TCP_ENABLE_ECN                    = 0x104
+	TCP_FASTOPEN                      = 0x105
 	TCP_KEEPALIVE                     = 0x10
 	TCP_KEEPCNT                       = 0x102
 	TCP_KEEPINTVL                     = 0x101
@@ -1261,6 +1353,11 @@
 	VKILL                             = 0x5
 	VLNEXT                            = 0xe
 	VMIN                              = 0x10
+	VM_LOADAVG                        = 0x2
+	VM_MACHFACTOR                     = 0x4
+	VM_MAXID                          = 0x6
+	VM_METER                          = 0x1
+	VM_SWAPUSAGE                      = 0x5
 	VQUIT                             = 0x9
 	VREPRINT                          = 0x6
 	VSTART                            = 0xc
diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go
index 9594f93..48f63d4 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go
@@ -1,5 +1,5 @@
 // mkerrors.sh -m64
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build amd64,darwin
 
@@ -48,6 +48,7 @@
 	AF_UNIX                           = 0x1
 	AF_UNSPEC                         = 0x0
 	AF_UTUN                           = 0x26
+	ALTWERASE                         = 0x200
 	B0                                = 0x0
 	B110                              = 0x6e
 	B115200                           = 0x1c200
@@ -138,9 +139,26 @@
 	BPF_W                             = 0x0
 	BPF_X                             = 0x8
 	BRKINT                            = 0x2
+	BS0                               = 0x0
+	BS1                               = 0x8000
+	BSDLY                             = 0x8000
 	CFLUSH                            = 0xf
 	CLOCAL                            = 0x8000
+	CLOCK_MONOTONIC                   = 0x6
+	CLOCK_MONOTONIC_RAW               = 0x4
+	CLOCK_MONOTONIC_RAW_APPROX        = 0x5
+	CLOCK_PROCESS_CPUTIME_ID          = 0xc
+	CLOCK_REALTIME                    = 0x0
+	CLOCK_THREAD_CPUTIME_ID           = 0x10
+	CLOCK_UPTIME_RAW                  = 0x8
+	CLOCK_UPTIME_RAW_APPROX           = 0x9
+	CR0                               = 0x0
+	CR1                               = 0x1000
+	CR2                               = 0x2000
+	CR3                               = 0x3000
+	CRDLY                             = 0x3000
 	CREAD                             = 0x800
+	CRTSCTS                           = 0x30000
 	CS5                               = 0x0
 	CS6                               = 0x100
 	CS7                               = 0x200
@@ -332,13 +350,14 @@
 	ECHONL                            = 0x10
 	ECHOPRT                           = 0x20
 	EVFILT_AIO                        = -0x3
+	EVFILT_EXCEPT                     = -0xf
 	EVFILT_FS                         = -0x9
 	EVFILT_MACHPORT                   = -0x8
 	EVFILT_PROC                       = -0x5
 	EVFILT_READ                       = -0x1
 	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xe
-	EVFILT_THREADMARKER               = 0xe
+	EVFILT_SYSCOUNT                   = 0xf
+	EVFILT_THREADMARKER               = 0xf
 	EVFILT_TIMER                      = -0x7
 	EVFILT_USER                       = -0xa
 	EVFILT_VM                         = -0xc
@@ -349,6 +368,7 @@
 	EV_DELETE                         = 0x2
 	EV_DISABLE                        = 0x8
 	EV_DISPATCH                       = 0x80
+	EV_DISPATCH2                      = 0x180
 	EV_ENABLE                         = 0x4
 	EV_EOF                            = 0x8000
 	EV_ERROR                          = 0x4000
@@ -359,16 +379,25 @@
 	EV_POLL                           = 0x1000
 	EV_RECEIPT                        = 0x40
 	EV_SYSFLAGS                       = 0xf000
+	EV_UDATA_SPECIFIC                 = 0x100
+	EV_VANISHED                       = 0x200
 	EXTA                              = 0x4b00
 	EXTB                              = 0x9600
 	EXTPROC                           = 0x800
 	FD_CLOEXEC                        = 0x1
 	FD_SETSIZE                        = 0x400
+	FF0                               = 0x0
+	FF1                               = 0x4000
+	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
 	F_ADDFILESIGS                     = 0x3d
+	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
+	F_ADDFILESIGS_RETURN              = 0x61
 	F_ADDSIGS                         = 0x3b
 	F_ALLOCATEALL                     = 0x4
 	F_ALLOCATECONTIG                  = 0x2
+	F_BARRIERFSYNC                    = 0x55
+	F_CHECK_LV                        = 0x62
 	F_CHKCLEAN                        = 0x29
 	F_DUPFD                           = 0x0
 	F_DUPFD_CLOEXEC                   = 0x43
@@ -770,11 +799,13 @@
 	MADV_FREE_REUSABLE                = 0x7
 	MADV_FREE_REUSE                   = 0x8
 	MADV_NORMAL                       = 0x0
+	MADV_PAGEOUT                      = 0xa
 	MADV_RANDOM                       = 0x1
 	MADV_SEQUENTIAL                   = 0x2
 	MADV_WILLNEED                     = 0x3
 	MADV_ZERO_WIRED_PAGES             = 0x6
 	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
 	MAP_COPY                          = 0x2
 	MAP_FILE                          = 0x0
 	MAP_FIXED                         = 0x10
@@ -786,9 +817,43 @@
 	MAP_PRIVATE                       = 0x2
 	MAP_RENAME                        = 0x20
 	MAP_RESERVED0080                  = 0x80
+	MAP_RESILIENT_CODESIGN            = 0x2000
+	MAP_RESILIENT_MEDIA               = 0x4000
 	MAP_SHARED                        = 0x1
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
+	MNT_ASYNC                         = 0x40
+	MNT_AUTOMOUNTED                   = 0x400000
+	MNT_CMDFLAGS                      = 0xf0000
+	MNT_CPROTECT                      = 0x80
+	MNT_DEFWRITE                      = 0x2000000
+	MNT_DONTBROWSE                    = 0x100000
+	MNT_DOVOLFS                       = 0x8000
+	MNT_DWAIT                         = 0x4
+	MNT_EXPORTED                      = 0x100
+	MNT_FORCE                         = 0x80000
+	MNT_IGNORE_OWNERSHIP              = 0x200000
+	MNT_JOURNALED                     = 0x800000
+	MNT_LOCAL                         = 0x1000
+	MNT_MULTILABEL                    = 0x4000000
+	MNT_NOATIME                       = 0x10000000
+	MNT_NOBLOCK                       = 0x20000
+	MNT_NODEV                         = 0x10
+	MNT_NOEXEC                        = 0x4
+	MNT_NOSUID                        = 0x8
+	MNT_NOUSERXATTR                   = 0x1000000
+	MNT_NOWAIT                        = 0x2
+	MNT_QUARANTINE                    = 0x400
+	MNT_QUOTA                         = 0x2000
+	MNT_RDONLY                        = 0x1
+	MNT_RELOAD                        = 0x40000
+	MNT_ROOTFS                        = 0x4000
+	MNT_SYNCHRONOUS                   = 0x2
+	MNT_UNION                         = 0x20
+	MNT_UNKNOWNPERMISSIONS            = 0x200000
+	MNT_UPDATE                        = 0x10000
+	MNT_VISFLAGMASK                   = 0x17f0f5ff
+	MNT_WAIT                          = 0x1
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
 	MSG_DONTWAIT                      = 0x80
@@ -819,7 +884,13 @@
 	NET_RT_MAXID                      = 0xa
 	NET_RT_STAT                       = 0x4
 	NET_RT_TRASH                      = 0x5
+	NL0                               = 0x0
+	NL1                               = 0x100
+	NL2                               = 0x200
+	NL3                               = 0x300
+	NLDLY                             = 0x300
 	NOFLSH                            = 0x80000000
+	NOKERNINFO                        = 0x2000000
 	NOTE_ABSOLUTE                     = 0x8
 	NOTE_ATTRIB                       = 0x8
 	NOTE_BACKGROUND                   = 0x40
@@ -843,11 +914,14 @@
 	NOTE_FFNOP                        = 0x0
 	NOTE_FFOR                         = 0x80000000
 	NOTE_FORK                         = 0x40000000
+	NOTE_FUNLOCK                      = 0x100
 	NOTE_LEEWAY                       = 0x10
 	NOTE_LINK                         = 0x10
 	NOTE_LOWAT                        = 0x1
+	NOTE_MACH_CONTINUOUS_TIME         = 0x80
 	NOTE_NONE                         = 0x80
 	NOTE_NSECONDS                     = 0x4
+	NOTE_OOB                          = 0x2
 	NOTE_PCTRLMASK                    = -0x100000
 	NOTE_PDATAMASK                    = 0xfffff
 	NOTE_REAP                         = 0x10000000
@@ -872,6 +946,7 @@
 	ONOCR                             = 0x20
 	ONOEOT                            = 0x8
 	OPOST                             = 0x1
+	OXTABS                            = 0x4
 	O_ACCMODE                         = 0x3
 	O_ALERT                           = 0x20000000
 	O_APPEND                          = 0x8
@@ -880,6 +955,7 @@
 	O_CREAT                           = 0x200
 	O_DIRECTORY                       = 0x100000
 	O_DP_GETRAWENCRYPTED              = 0x1
+	O_DP_GETRAWUNENCRYPTED            = 0x2
 	O_DSYNC                           = 0x400000
 	O_EVTONLY                         = 0x8000
 	O_EXCL                            = 0x800
@@ -932,7 +1008,10 @@
 	RLIMIT_CPU_USAGE_MONITOR          = 0x2
 	RLIMIT_DATA                       = 0x2
 	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_MEMLOCK                    = 0x6
 	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_NPROC                      = 0x7
+	RLIMIT_RSS                        = 0x5
 	RLIMIT_STACK                      = 0x3
 	RLIM_INFINITY                     = 0x7fffffffffffffff
 	RTAX_AUTHOR                       = 0x6
@@ -1102,6 +1181,8 @@
 	SO_LABEL                          = 0x1010
 	SO_LINGER                         = 0x80
 	SO_LINGER_SEC                     = 0x1080
+	SO_NETSVC_MARKING_LEVEL           = 0x1119
+	SO_NET_SERVICE_TYPE               = 0x1116
 	SO_NKE                            = 0x1021
 	SO_NOADDRERR                      = 0x1023
 	SO_NOSIGPIPE                      = 0x1022
@@ -1157,11 +1238,22 @@
 	S_IXGRP                           = 0x8
 	S_IXOTH                           = 0x1
 	S_IXUSR                           = 0x40
+	TAB0                              = 0x0
+	TAB1                              = 0x400
+	TAB2                              = 0x800
+	TAB3                              = 0x4
+	TABDLY                            = 0xc04
 	TCIFLUSH                          = 0x1
+	TCIOFF                            = 0x3
 	TCIOFLUSH                         = 0x3
+	TCION                             = 0x4
 	TCOFLUSH                          = 0x2
+	TCOOFF                            = 0x1
+	TCOON                             = 0x2
 	TCP_CONNECTIONTIMEOUT             = 0x20
+	TCP_CONNECTION_INFO               = 0x106
 	TCP_ENABLE_ECN                    = 0x104
+	TCP_FASTOPEN                      = 0x105
 	TCP_KEEPALIVE                     = 0x10
 	TCP_KEEPCNT                       = 0x102
 	TCP_KEEPINTVL                     = 0x101
@@ -1261,6 +1353,11 @@
 	VKILL                             = 0x5
 	VLNEXT                            = 0xe
 	VMIN                              = 0x10
+	VM_LOADAVG                        = 0x2
+	VM_MACHFACTOR                     = 0x4
+	VM_MAXID                          = 0x6
+	VM_METER                          = 0x1
+	VM_SWAPUSAGE                      = 0x5
 	VQUIT                             = 0x9
 	VREPRINT                          = 0x6
 	VSTART                            = 0xc
diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go
index a410e88..24cb522 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm.go
@@ -1,11 +1,11 @@
 // mkerrors.sh
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build arm,darwin
 
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- _const.go
 
-// +build arm,darwin
-
 package unix
 
 import "syscall"
@@ -48,6 +48,7 @@
 	AF_UNIX                           = 0x1
 	AF_UNSPEC                         = 0x0
 	AF_UTUN                           = 0x26
+	ALTWERASE                         = 0x200
 	B0                                = 0x0
 	B110                              = 0x6e
 	B115200                           = 0x1c200
@@ -86,6 +87,7 @@
 	BIOCSBLEN                         = 0xc0044266
 	BIOCSDLT                          = 0x80044278
 	BIOCSETF                          = 0x80104267
+	BIOCSETFNR                        = 0x8010427e
 	BIOCSETIF                         = 0x8020426c
 	BIOCSHDRCMPLT                     = 0x80044275
 	BIOCSRSIG                         = 0x80044273
@@ -137,9 +139,26 @@
 	BPF_W                             = 0x0
 	BPF_X                             = 0x8
 	BRKINT                            = 0x2
+	BS0                               = 0x0
+	BS1                               = 0x8000
+	BSDLY                             = 0x8000
 	CFLUSH                            = 0xf
 	CLOCAL                            = 0x8000
+	CLOCK_MONOTONIC                   = 0x6
+	CLOCK_MONOTONIC_RAW               = 0x4
+	CLOCK_MONOTONIC_RAW_APPROX        = 0x5
+	CLOCK_PROCESS_CPUTIME_ID          = 0xc
+	CLOCK_REALTIME                    = 0x0
+	CLOCK_THREAD_CPUTIME_ID           = 0x10
+	CLOCK_UPTIME_RAW                  = 0x8
+	CLOCK_UPTIME_RAW_APPROX           = 0x9
+	CR0                               = 0x0
+	CR1                               = 0x1000
+	CR2                               = 0x2000
+	CR3                               = 0x3000
+	CRDLY                             = 0x3000
 	CREAD                             = 0x800
+	CRTSCTS                           = 0x30000
 	CS5                               = 0x0
 	CS6                               = 0x100
 	CS7                               = 0x200
@@ -152,33 +171,168 @@
 	CSUSP                             = 0x1a
 	CTL_MAXNAME                       = 0xc
 	CTL_NET                           = 0x4
+	DLT_A429                          = 0xb8
+	DLT_A653_ICM                      = 0xb9
+	DLT_AIRONET_HEADER                = 0x78
+	DLT_AOS                           = 0xde
 	DLT_APPLE_IP_OVER_IEEE1394        = 0x8a
 	DLT_ARCNET                        = 0x7
+	DLT_ARCNET_LINUX                  = 0x81
 	DLT_ATM_CLIP                      = 0x13
 	DLT_ATM_RFC1483                   = 0xb
+	DLT_AURORA                        = 0x7e
 	DLT_AX25                          = 0x3
+	DLT_AX25_KISS                     = 0xca
+	DLT_BACNET_MS_TP                  = 0xa5
+	DLT_BLUETOOTH_HCI_H4              = 0xbb
+	DLT_BLUETOOTH_HCI_H4_WITH_PHDR    = 0xc9
+	DLT_CAN20B                        = 0xbe
+	DLT_CAN_SOCKETCAN                 = 0xe3
 	DLT_CHAOS                         = 0x5
 	DLT_CHDLC                         = 0x68
+	DLT_CISCO_IOS                     = 0x76
 	DLT_C_HDLC                        = 0x68
+	DLT_C_HDLC_WITH_DIR               = 0xcd
+	DLT_DBUS                          = 0xe7
+	DLT_DECT                          = 0xdd
+	DLT_DOCSIS                        = 0x8f
+	DLT_DVB_CI                        = 0xeb
+	DLT_ECONET                        = 0x73
 	DLT_EN10MB                        = 0x1
 	DLT_EN3MB                         = 0x2
+	DLT_ENC                           = 0x6d
+	DLT_ERF                           = 0xc5
+	DLT_ERF_ETH                       = 0xaf
+	DLT_ERF_POS                       = 0xb0
+	DLT_FC_2                          = 0xe0
+	DLT_FC_2_WITH_FRAME_DELIMS        = 0xe1
 	DLT_FDDI                          = 0xa
+	DLT_FLEXRAY                       = 0xd2
+	DLT_FRELAY                        = 0x6b
+	DLT_FRELAY_WITH_DIR               = 0xce
+	DLT_GCOM_SERIAL                   = 0xad
+	DLT_GCOM_T1E1                     = 0xac
+	DLT_GPF_F                         = 0xab
+	DLT_GPF_T                         = 0xaa
+	DLT_GPRS_LLC                      = 0xa9
+	DLT_GSMTAP_ABIS                   = 0xda
+	DLT_GSMTAP_UM                     = 0xd9
+	DLT_HHDLC                         = 0x79
+	DLT_IBM_SN                        = 0x92
+	DLT_IBM_SP                        = 0x91
 	DLT_IEEE802                       = 0x6
 	DLT_IEEE802_11                    = 0x69
 	DLT_IEEE802_11_RADIO              = 0x7f
 	DLT_IEEE802_11_RADIO_AVS          = 0xa3
+	DLT_IEEE802_15_4                  = 0xc3
+	DLT_IEEE802_15_4_LINUX            = 0xbf
+	DLT_IEEE802_15_4_NOFCS            = 0xe6
+	DLT_IEEE802_15_4_NONASK_PHY       = 0xd7
+	DLT_IEEE802_16_MAC_CPS            = 0xbc
+	DLT_IEEE802_16_MAC_CPS_RADIO      = 0xc1
+	DLT_IPFILTER                      = 0x74
+	DLT_IPMB                          = 0xc7
+	DLT_IPMB_LINUX                    = 0xd1
+	DLT_IPNET                         = 0xe2
+	DLT_IPOIB                         = 0xf2
+	DLT_IPV4                          = 0xe4
+	DLT_IPV6                          = 0xe5
+	DLT_IP_OVER_FC                    = 0x7a
+	DLT_JUNIPER_ATM1                  = 0x89
+	DLT_JUNIPER_ATM2                  = 0x87
+	DLT_JUNIPER_ATM_CEMIC             = 0xee
+	DLT_JUNIPER_CHDLC                 = 0xb5
+	DLT_JUNIPER_ES                    = 0x84
+	DLT_JUNIPER_ETHER                 = 0xb2
+	DLT_JUNIPER_FIBRECHANNEL          = 0xea
+	DLT_JUNIPER_FRELAY                = 0xb4
+	DLT_JUNIPER_GGSN                  = 0x85
+	DLT_JUNIPER_ISM                   = 0xc2
+	DLT_JUNIPER_MFR                   = 0x86
+	DLT_JUNIPER_MLFR                  = 0x83
+	DLT_JUNIPER_MLPPP                 = 0x82
+	DLT_JUNIPER_MONITOR               = 0xa4
+	DLT_JUNIPER_PIC_PEER              = 0xae
+	DLT_JUNIPER_PPP                   = 0xb3
+	DLT_JUNIPER_PPPOE                 = 0xa7
+	DLT_JUNIPER_PPPOE_ATM             = 0xa8
+	DLT_JUNIPER_SERVICES              = 0x88
+	DLT_JUNIPER_SRX_E2E               = 0xe9
+	DLT_JUNIPER_ST                    = 0xc8
+	DLT_JUNIPER_VP                    = 0xb7
+	DLT_JUNIPER_VS                    = 0xe8
+	DLT_LAPB_WITH_DIR                 = 0xcf
+	DLT_LAPD                          = 0xcb
+	DLT_LIN                           = 0xd4
+	DLT_LINUX_EVDEV                   = 0xd8
+	DLT_LINUX_IRDA                    = 0x90
+	DLT_LINUX_LAPD                    = 0xb1
+	DLT_LINUX_PPP_WITHDIRECTION       = 0xa6
 	DLT_LINUX_SLL                     = 0x71
 	DLT_LOOP                          = 0x6c
+	DLT_LTALK                         = 0x72
+	DLT_MATCHING_MAX                  = 0xf5
+	DLT_MATCHING_MIN                  = 0x68
+	DLT_MFR                           = 0xb6
+	DLT_MOST                          = 0xd3
+	DLT_MPEG_2_TS                     = 0xf3
+	DLT_MPLS                          = 0xdb
+	DLT_MTP2                          = 0x8c
+	DLT_MTP2_WITH_PHDR                = 0x8b
+	DLT_MTP3                          = 0x8d
+	DLT_MUX27010                      = 0xec
+	DLT_NETANALYZER                   = 0xf0
+	DLT_NETANALYZER_TRANSPARENT       = 0xf1
+	DLT_NFC_LLCP                      = 0xf5
+	DLT_NFLOG                         = 0xef
+	DLT_NG40                          = 0xf4
 	DLT_NULL                          = 0x0
+	DLT_PCI_EXP                       = 0x7d
 	DLT_PFLOG                         = 0x75
 	DLT_PFSYNC                        = 0x12
+	DLT_PPI                           = 0xc0
 	DLT_PPP                           = 0x9
 	DLT_PPP_BSDOS                     = 0x10
+	DLT_PPP_ETHER                     = 0x33
+	DLT_PPP_PPPD                      = 0xa6
 	DLT_PPP_SERIAL                    = 0x32
+	DLT_PPP_WITH_DIR                  = 0xcc
+	DLT_PPP_WITH_DIRECTION            = 0xa6
+	DLT_PRISM_HEADER                  = 0x77
 	DLT_PRONET                        = 0x4
+	DLT_RAIF1                         = 0xc6
 	DLT_RAW                           = 0xc
+	DLT_RIO                           = 0x7c
+	DLT_SCCP                          = 0x8e
+	DLT_SITA                          = 0xc4
 	DLT_SLIP                          = 0x8
 	DLT_SLIP_BSDOS                    = 0xf
+	DLT_STANAG_5066_D_PDU             = 0xed
+	DLT_SUNATM                        = 0x7b
+	DLT_SYMANTEC_FIREWALL             = 0x63
+	DLT_TZSP                          = 0x80
+	DLT_USB                           = 0xba
+	DLT_USB_LINUX                     = 0xbd
+	DLT_USB_LINUX_MMAPPED             = 0xdc
+	DLT_USER0                         = 0x93
+	DLT_USER1                         = 0x94
+	DLT_USER10                        = 0x9d
+	DLT_USER11                        = 0x9e
+	DLT_USER12                        = 0x9f
+	DLT_USER13                        = 0xa0
+	DLT_USER14                        = 0xa1
+	DLT_USER15                        = 0xa2
+	DLT_USER2                         = 0x95
+	DLT_USER3                         = 0x96
+	DLT_USER4                         = 0x97
+	DLT_USER5                         = 0x98
+	DLT_USER6                         = 0x99
+	DLT_USER7                         = 0x9a
+	DLT_USER8                         = 0x9b
+	DLT_USER9                         = 0x9c
+	DLT_WIHART                        = 0xdf
+	DLT_X2E_SERIAL                    = 0xd5
+	DLT_X2E_XORAYA                    = 0xd6
 	DT_BLK                            = 0x6
 	DT_CHR                            = 0x2
 	DT_DIR                            = 0x4
@@ -196,13 +350,14 @@
 	ECHONL                            = 0x10
 	ECHOPRT                           = 0x20
 	EVFILT_AIO                        = -0x3
+	EVFILT_EXCEPT                     = -0xf
 	EVFILT_FS                         = -0x9
 	EVFILT_MACHPORT                   = -0x8
 	EVFILT_PROC                       = -0x5
 	EVFILT_READ                       = -0x1
 	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xe
-	EVFILT_THREADMARKER               = 0xe
+	EVFILT_SYSCOUNT                   = 0xf
+	EVFILT_THREADMARKER               = 0xf
 	EVFILT_TIMER                      = -0x7
 	EVFILT_USER                       = -0xa
 	EVFILT_VM                         = -0xc
@@ -213,6 +368,7 @@
 	EV_DELETE                         = 0x2
 	EV_DISABLE                        = 0x8
 	EV_DISPATCH                       = 0x80
+	EV_DISPATCH2                      = 0x180
 	EV_ENABLE                         = 0x4
 	EV_EOF                            = 0x8000
 	EV_ERROR                          = 0x4000
@@ -223,16 +379,25 @@
 	EV_POLL                           = 0x1000
 	EV_RECEIPT                        = 0x40
 	EV_SYSFLAGS                       = 0xf000
+	EV_UDATA_SPECIFIC                 = 0x100
+	EV_VANISHED                       = 0x200
 	EXTA                              = 0x4b00
 	EXTB                              = 0x9600
 	EXTPROC                           = 0x800
 	FD_CLOEXEC                        = 0x1
 	FD_SETSIZE                        = 0x400
+	FF0                               = 0x0
+	FF1                               = 0x4000
+	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
 	F_ADDFILESIGS                     = 0x3d
+	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
+	F_ADDFILESIGS_RETURN              = 0x61
 	F_ADDSIGS                         = 0x3b
 	F_ALLOCATEALL                     = 0x4
 	F_ALLOCATECONTIG                  = 0x2
+	F_BARRIERFSYNC                    = 0x55
+	F_CHECK_LV                        = 0x62
 	F_CHKCLEAN                        = 0x29
 	F_DUPFD                           = 0x0
 	F_DUPFD_CLOEXEC                   = 0x43
@@ -347,6 +512,7 @@
 	IFT_PDP                           = 0xff
 	IFT_PFLOG                         = 0xf5
 	IFT_PFSYNC                        = 0xf6
+	IFT_PKTAP                         = 0xfe
 	IFT_PPP                           = 0x17
 	IFT_PROPMUX                       = 0x36
 	IFT_PROPVIRTUAL                   = 0x35
@@ -515,7 +681,7 @@
 	IPV6_FAITH                        = 0x1d
 	IPV6_FLOWINFO_MASK                = 0xffffff0f
 	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FRAGTTL                      = 0x78
+	IPV6_FRAGTTL                      = 0x3c
 	IPV6_FW_ADD                       = 0x1e
 	IPV6_FW_DEL                       = 0x1f
 	IPV6_FW_FLUSH                     = 0x20
@@ -633,11 +799,13 @@
 	MADV_FREE_REUSABLE                = 0x7
 	MADV_FREE_REUSE                   = 0x8
 	MADV_NORMAL                       = 0x0
+	MADV_PAGEOUT                      = 0xa
 	MADV_RANDOM                       = 0x1
 	MADV_SEQUENTIAL                   = 0x2
 	MADV_WILLNEED                     = 0x3
 	MADV_ZERO_WIRED_PAGES             = 0x6
 	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
 	MAP_COPY                          = 0x2
 	MAP_FILE                          = 0x0
 	MAP_FIXED                         = 0x10
@@ -649,9 +817,43 @@
 	MAP_PRIVATE                       = 0x2
 	MAP_RENAME                        = 0x20
 	MAP_RESERVED0080                  = 0x80
+	MAP_RESILIENT_CODESIGN            = 0x2000
+	MAP_RESILIENT_MEDIA               = 0x4000
 	MAP_SHARED                        = 0x1
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
+	MNT_ASYNC                         = 0x40
+	MNT_AUTOMOUNTED                   = 0x400000
+	MNT_CMDFLAGS                      = 0xf0000
+	MNT_CPROTECT                      = 0x80
+	MNT_DEFWRITE                      = 0x2000000
+	MNT_DONTBROWSE                    = 0x100000
+	MNT_DOVOLFS                       = 0x8000
+	MNT_DWAIT                         = 0x4
+	MNT_EXPORTED                      = 0x100
+	MNT_FORCE                         = 0x80000
+	MNT_IGNORE_OWNERSHIP              = 0x200000
+	MNT_JOURNALED                     = 0x800000
+	MNT_LOCAL                         = 0x1000
+	MNT_MULTILABEL                    = 0x4000000
+	MNT_NOATIME                       = 0x10000000
+	MNT_NOBLOCK                       = 0x20000
+	MNT_NODEV                         = 0x10
+	MNT_NOEXEC                        = 0x4
+	MNT_NOSUID                        = 0x8
+	MNT_NOUSERXATTR                   = 0x1000000
+	MNT_NOWAIT                        = 0x2
+	MNT_QUARANTINE                    = 0x400
+	MNT_QUOTA                         = 0x2000
+	MNT_RDONLY                        = 0x1
+	MNT_RELOAD                        = 0x40000
+	MNT_ROOTFS                        = 0x4000
+	MNT_SYNCHRONOUS                   = 0x2
+	MNT_UNION                         = 0x20
+	MNT_UNKNOWNPERMISSIONS            = 0x200000
+	MNT_UPDATE                        = 0x10000
+	MNT_VISFLAGMASK                   = 0x17f0f5ff
+	MNT_WAIT                          = 0x1
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
 	MSG_DONTWAIT                      = 0x80
@@ -682,7 +884,13 @@
 	NET_RT_MAXID                      = 0xa
 	NET_RT_STAT                       = 0x4
 	NET_RT_TRASH                      = 0x5
+	NL0                               = 0x0
+	NL1                               = 0x100
+	NL2                               = 0x200
+	NL3                               = 0x300
+	NLDLY                             = 0x300
 	NOFLSH                            = 0x80000000
+	NOKERNINFO                        = 0x2000000
 	NOTE_ABSOLUTE                     = 0x8
 	NOTE_ATTRIB                       = 0x8
 	NOTE_BACKGROUND                   = 0x40
@@ -706,11 +914,14 @@
 	NOTE_FFNOP                        = 0x0
 	NOTE_FFOR                         = 0x80000000
 	NOTE_FORK                         = 0x40000000
+	NOTE_FUNLOCK                      = 0x100
 	NOTE_LEEWAY                       = 0x10
 	NOTE_LINK                         = 0x10
 	NOTE_LOWAT                        = 0x1
+	NOTE_MACH_CONTINUOUS_TIME         = 0x80
 	NOTE_NONE                         = 0x80
 	NOTE_NSECONDS                     = 0x4
+	NOTE_OOB                          = 0x2
 	NOTE_PCTRLMASK                    = -0x100000
 	NOTE_PDATAMASK                    = 0xfffff
 	NOTE_REAP                         = 0x10000000
@@ -735,6 +946,7 @@
 	ONOCR                             = 0x20
 	ONOEOT                            = 0x8
 	OPOST                             = 0x1
+	OXTABS                            = 0x4
 	O_ACCMODE                         = 0x3
 	O_ALERT                           = 0x20000000
 	O_APPEND                          = 0x8
@@ -743,6 +955,7 @@
 	O_CREAT                           = 0x200
 	O_DIRECTORY                       = 0x100000
 	O_DP_GETRAWENCRYPTED              = 0x1
+	O_DP_GETRAWUNENCRYPTED            = 0x2
 	O_DSYNC                           = 0x400000
 	O_EVTONLY                         = 0x8000
 	O_EXCL                            = 0x800
@@ -795,7 +1008,10 @@
 	RLIMIT_CPU_USAGE_MONITOR          = 0x2
 	RLIMIT_DATA                       = 0x2
 	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_MEMLOCK                    = 0x6
 	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_NPROC                      = 0x7
+	RLIMIT_RSS                        = 0x5
 	RLIMIT_STACK                      = 0x3
 	RLIM_INFINITY                     = 0x7fffffffffffffff
 	RTAX_AUTHOR                       = 0x6
@@ -830,6 +1046,7 @@
 	RTF_LOCAL                         = 0x200000
 	RTF_MODIFIED                      = 0x20
 	RTF_MULTICAST                     = 0x800000
+	RTF_NOIFREF                       = 0x2000
 	RTF_PINNED                        = 0x100000
 	RTF_PRCLONING                     = 0x10000
 	RTF_PROTO1                        = 0x8000
@@ -964,6 +1181,8 @@
 	SO_LABEL                          = 0x1010
 	SO_LINGER                         = 0x80
 	SO_LINGER_SEC                     = 0x1080
+	SO_NETSVC_MARKING_LEVEL           = 0x1119
+	SO_NET_SERVICE_TYPE               = 0x1116
 	SO_NKE                            = 0x1021
 	SO_NOADDRERR                      = 0x1023
 	SO_NOSIGPIPE                      = 0x1022
@@ -1019,11 +1238,22 @@
 	S_IXGRP                           = 0x8
 	S_IXOTH                           = 0x1
 	S_IXUSR                           = 0x40
+	TAB0                              = 0x0
+	TAB1                              = 0x400
+	TAB2                              = 0x800
+	TAB3                              = 0x4
+	TABDLY                            = 0xc04
 	TCIFLUSH                          = 0x1
+	TCIOFF                            = 0x3
 	TCIOFLUSH                         = 0x3
+	TCION                             = 0x4
 	TCOFLUSH                          = 0x2
+	TCOOFF                            = 0x1
+	TCOON                             = 0x2
 	TCP_CONNECTIONTIMEOUT             = 0x20
+	TCP_CONNECTION_INFO               = 0x106
 	TCP_ENABLE_ECN                    = 0x104
+	TCP_FASTOPEN                      = 0x105
 	TCP_KEEPALIVE                     = 0x10
 	TCP_KEEPCNT                       = 0x102
 	TCP_KEEPINTVL                     = 0x101
@@ -1123,6 +1353,11 @@
 	VKILL                             = 0x5
 	VLNEXT                            = 0xe
 	VMIN                              = 0x10
+	VM_LOADAVG                        = 0x2
+	VM_MACHFACTOR                     = 0x4
+	VM_MAXID                          = 0x6
+	VM_METER                          = 0x1
+	VM_SWAPUSAGE                      = 0x5
 	VQUIT                             = 0x9
 	VREPRINT                          = 0x6
 	VSTART                            = 0xc
@@ -1291,3 +1526,148 @@
 	SIGXCPU   = syscall.Signal(0x18)
 	SIGXFSZ   = syscall.Signal(0x19)
 )
+
+// Error table
+var errors = [...]string{
+	1:   "operation not permitted",
+	2:   "no such file or directory",
+	3:   "no such process",
+	4:   "interrupted system call",
+	5:   "input/output error",
+	6:   "device not configured",
+	7:   "argument list too long",
+	8:   "exec format error",
+	9:   "bad file descriptor",
+	10:  "no child processes",
+	11:  "resource deadlock avoided",
+	12:  "cannot allocate memory",
+	13:  "permission denied",
+	14:  "bad address",
+	15:  "block device required",
+	16:  "resource busy",
+	17:  "file exists",
+	18:  "cross-device link",
+	19:  "operation not supported by device",
+	20:  "not a directory",
+	21:  "is a directory",
+	22:  "invalid argument",
+	23:  "too many open files in system",
+	24:  "too many open files",
+	25:  "inappropriate ioctl for device",
+	26:  "text file busy",
+	27:  "file too large",
+	28:  "no space left on device",
+	29:  "illegal seek",
+	30:  "read-only file system",
+	31:  "too many links",
+	32:  "broken pipe",
+	33:  "numerical argument out of domain",
+	34:  "result too large",
+	35:  "resource temporarily unavailable",
+	36:  "operation now in progress",
+	37:  "operation already in progress",
+	38:  "socket operation on non-socket",
+	39:  "destination address required",
+	40:  "message too long",
+	41:  "protocol wrong type for socket",
+	42:  "protocol not available",
+	43:  "protocol not supported",
+	44:  "socket type not supported",
+	45:  "operation not supported",
+	46:  "protocol family not supported",
+	47:  "address family not supported by protocol family",
+	48:  "address already in use",
+	49:  "can't assign requested address",
+	50:  "network is down",
+	51:  "network is unreachable",
+	52:  "network dropped connection on reset",
+	53:  "software caused connection abort",
+	54:  "connection reset by peer",
+	55:  "no buffer space available",
+	56:  "socket is already connected",
+	57:  "socket is not connected",
+	58:  "can't send after socket shutdown",
+	59:  "too many references: can't splice",
+	60:  "operation timed out",
+	61:  "connection refused",
+	62:  "too many levels of symbolic links",
+	63:  "file name too long",
+	64:  "host is down",
+	65:  "no route to host",
+	66:  "directory not empty",
+	67:  "too many processes",
+	68:  "too many users",
+	69:  "disc quota exceeded",
+	70:  "stale NFS file handle",
+	71:  "too many levels of remote in path",
+	72:  "RPC struct is bad",
+	73:  "RPC version wrong",
+	74:  "RPC prog. not avail",
+	75:  "program version wrong",
+	76:  "bad procedure for program",
+	77:  "no locks available",
+	78:  "function not implemented",
+	79:  "inappropriate file type or format",
+	80:  "authentication error",
+	81:  "need authenticator",
+	82:  "device power is off",
+	83:  "device error",
+	84:  "value too large to be stored in data type",
+	85:  "bad executable (or shared library)",
+	86:  "bad CPU type in executable",
+	87:  "shared library version mismatch",
+	88:  "malformed Mach-o file",
+	89:  "operation canceled",
+	90:  "identifier removed",
+	91:  "no message of desired type",
+	92:  "illegal byte sequence",
+	93:  "attribute not found",
+	94:  "bad message",
+	95:  "EMULTIHOP (Reserved)",
+	96:  "no message available on STREAM",
+	97:  "ENOLINK (Reserved)",
+	98:  "no STREAM resources",
+	99:  "not a STREAM",
+	100: "protocol error",
+	101: "STREAM ioctl timeout",
+	102: "operation not supported on socket",
+	103: "policy not found",
+	104: "state not recoverable",
+	105: "previous owner died",
+	106: "interface output queue is full",
+}
+
+// Signal table
+var signals = [...]string{
+	1:  "hangup",
+	2:  "interrupt",
+	3:  "quit",
+	4:  "illegal instruction",
+	5:  "trace/BPT trap",
+	6:  "abort trap",
+	7:  "EMT trap",
+	8:  "floating point exception",
+	9:  "killed",
+	10: "bus error",
+	11: "segmentation fault",
+	12: "bad system call",
+	13: "broken pipe",
+	14: "alarm clock",
+	15: "terminated",
+	16: "urgent I/O condition",
+	17: "suspended (signal)",
+	18: "suspended",
+	19: "continued",
+	20: "child exited",
+	21: "stopped (tty input)",
+	22: "stopped (tty output)",
+	23: "I/O possible",
+	24: "cputime limit exceeded",
+	25: "filesize limit exceeded",
+	26: "virtual timer expired",
+	27: "profiling timer expired",
+	28: "window size changes",
+	29: "information request",
+	30: "user defined signal 1",
+	31: "user defined signal 2",
+}
diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go
index 3189c6b..cc8cc5b 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go
@@ -1,5 +1,5 @@
 // mkerrors.sh -m64
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build arm64,darwin
 
@@ -48,6 +48,7 @@
 	AF_UNIX                           = 0x1
 	AF_UNSPEC                         = 0x0
 	AF_UTUN                           = 0x26
+	ALTWERASE                         = 0x200
 	B0                                = 0x0
 	B110                              = 0x6e
 	B115200                           = 0x1c200
@@ -138,9 +139,26 @@
 	BPF_W                             = 0x0
 	BPF_X                             = 0x8
 	BRKINT                            = 0x2
+	BS0                               = 0x0
+	BS1                               = 0x8000
+	BSDLY                             = 0x8000
 	CFLUSH                            = 0xf
 	CLOCAL                            = 0x8000
+	CLOCK_MONOTONIC                   = 0x6
+	CLOCK_MONOTONIC_RAW               = 0x4
+	CLOCK_MONOTONIC_RAW_APPROX        = 0x5
+	CLOCK_PROCESS_CPUTIME_ID          = 0xc
+	CLOCK_REALTIME                    = 0x0
+	CLOCK_THREAD_CPUTIME_ID           = 0x10
+	CLOCK_UPTIME_RAW                  = 0x8
+	CLOCK_UPTIME_RAW_APPROX           = 0x9
+	CR0                               = 0x0
+	CR1                               = 0x1000
+	CR2                               = 0x2000
+	CR3                               = 0x3000
+	CRDLY                             = 0x3000
 	CREAD                             = 0x800
+	CRTSCTS                           = 0x30000
 	CS5                               = 0x0
 	CS6                               = 0x100
 	CS7                               = 0x200
@@ -332,13 +350,14 @@
 	ECHONL                            = 0x10
 	ECHOPRT                           = 0x20
 	EVFILT_AIO                        = -0x3
+	EVFILT_EXCEPT                     = -0xf
 	EVFILT_FS                         = -0x9
 	EVFILT_MACHPORT                   = -0x8
 	EVFILT_PROC                       = -0x5
 	EVFILT_READ                       = -0x1
 	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xe
-	EVFILT_THREADMARKER               = 0xe
+	EVFILT_SYSCOUNT                   = 0xf
+	EVFILT_THREADMARKER               = 0xf
 	EVFILT_TIMER                      = -0x7
 	EVFILT_USER                       = -0xa
 	EVFILT_VM                         = -0xc
@@ -349,6 +368,7 @@
 	EV_DELETE                         = 0x2
 	EV_DISABLE                        = 0x8
 	EV_DISPATCH                       = 0x80
+	EV_DISPATCH2                      = 0x180
 	EV_ENABLE                         = 0x4
 	EV_EOF                            = 0x8000
 	EV_ERROR                          = 0x4000
@@ -359,16 +379,25 @@
 	EV_POLL                           = 0x1000
 	EV_RECEIPT                        = 0x40
 	EV_SYSFLAGS                       = 0xf000
+	EV_UDATA_SPECIFIC                 = 0x100
+	EV_VANISHED                       = 0x200
 	EXTA                              = 0x4b00
 	EXTB                              = 0x9600
 	EXTPROC                           = 0x800
 	FD_CLOEXEC                        = 0x1
 	FD_SETSIZE                        = 0x400
+	FF0                               = 0x0
+	FF1                               = 0x4000
+	FFDLY                             = 0x4000
 	FLUSHO                            = 0x800000
 	F_ADDFILESIGS                     = 0x3d
+	F_ADDFILESIGS_FOR_DYLD_SIM        = 0x53
+	F_ADDFILESIGS_RETURN              = 0x61
 	F_ADDSIGS                         = 0x3b
 	F_ALLOCATEALL                     = 0x4
 	F_ALLOCATECONTIG                  = 0x2
+	F_BARRIERFSYNC                    = 0x55
+	F_CHECK_LV                        = 0x62
 	F_CHKCLEAN                        = 0x29
 	F_DUPFD                           = 0x0
 	F_DUPFD_CLOEXEC                   = 0x43
@@ -770,11 +799,13 @@
 	MADV_FREE_REUSABLE                = 0x7
 	MADV_FREE_REUSE                   = 0x8
 	MADV_NORMAL                       = 0x0
+	MADV_PAGEOUT                      = 0xa
 	MADV_RANDOM                       = 0x1
 	MADV_SEQUENTIAL                   = 0x2
 	MADV_WILLNEED                     = 0x3
 	MADV_ZERO_WIRED_PAGES             = 0x6
 	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
 	MAP_COPY                          = 0x2
 	MAP_FILE                          = 0x0
 	MAP_FIXED                         = 0x10
@@ -786,9 +817,43 @@
 	MAP_PRIVATE                       = 0x2
 	MAP_RENAME                        = 0x20
 	MAP_RESERVED0080                  = 0x80
+	MAP_RESILIENT_CODESIGN            = 0x2000
+	MAP_RESILIENT_MEDIA               = 0x4000
 	MAP_SHARED                        = 0x1
 	MCL_CURRENT                       = 0x1
 	MCL_FUTURE                        = 0x2
+	MNT_ASYNC                         = 0x40
+	MNT_AUTOMOUNTED                   = 0x400000
+	MNT_CMDFLAGS                      = 0xf0000
+	MNT_CPROTECT                      = 0x80
+	MNT_DEFWRITE                      = 0x2000000
+	MNT_DONTBROWSE                    = 0x100000
+	MNT_DOVOLFS                       = 0x8000
+	MNT_DWAIT                         = 0x4
+	MNT_EXPORTED                      = 0x100
+	MNT_FORCE                         = 0x80000
+	MNT_IGNORE_OWNERSHIP              = 0x200000
+	MNT_JOURNALED                     = 0x800000
+	MNT_LOCAL                         = 0x1000
+	MNT_MULTILABEL                    = 0x4000000
+	MNT_NOATIME                       = 0x10000000
+	MNT_NOBLOCK                       = 0x20000
+	MNT_NODEV                         = 0x10
+	MNT_NOEXEC                        = 0x4
+	MNT_NOSUID                        = 0x8
+	MNT_NOUSERXATTR                   = 0x1000000
+	MNT_NOWAIT                        = 0x2
+	MNT_QUARANTINE                    = 0x400
+	MNT_QUOTA                         = 0x2000
+	MNT_RDONLY                        = 0x1
+	MNT_RELOAD                        = 0x40000
+	MNT_ROOTFS                        = 0x4000
+	MNT_SYNCHRONOUS                   = 0x2
+	MNT_UNION                         = 0x20
+	MNT_UNKNOWNPERMISSIONS            = 0x200000
+	MNT_UPDATE                        = 0x10000
+	MNT_VISFLAGMASK                   = 0x17f0f5ff
+	MNT_WAIT                          = 0x1
 	MSG_CTRUNC                        = 0x20
 	MSG_DONTROUTE                     = 0x4
 	MSG_DONTWAIT                      = 0x80
@@ -819,7 +884,13 @@
 	NET_RT_MAXID                      = 0xa
 	NET_RT_STAT                       = 0x4
 	NET_RT_TRASH                      = 0x5
+	NL0                               = 0x0
+	NL1                               = 0x100
+	NL2                               = 0x200
+	NL3                               = 0x300
+	NLDLY                             = 0x300
 	NOFLSH                            = 0x80000000
+	NOKERNINFO                        = 0x2000000
 	NOTE_ABSOLUTE                     = 0x8
 	NOTE_ATTRIB                       = 0x8
 	NOTE_BACKGROUND                   = 0x40
@@ -843,11 +914,14 @@
 	NOTE_FFNOP                        = 0x0
 	NOTE_FFOR                         = 0x80000000
 	NOTE_FORK                         = 0x40000000
+	NOTE_FUNLOCK                      = 0x100
 	NOTE_LEEWAY                       = 0x10
 	NOTE_LINK                         = 0x10
 	NOTE_LOWAT                        = 0x1
+	NOTE_MACH_CONTINUOUS_TIME         = 0x80
 	NOTE_NONE                         = 0x80
 	NOTE_NSECONDS                     = 0x4
+	NOTE_OOB                          = 0x2
 	NOTE_PCTRLMASK                    = -0x100000
 	NOTE_PDATAMASK                    = 0xfffff
 	NOTE_REAP                         = 0x10000000
@@ -872,6 +946,7 @@
 	ONOCR                             = 0x20
 	ONOEOT                            = 0x8
 	OPOST                             = 0x1
+	OXTABS                            = 0x4
 	O_ACCMODE                         = 0x3
 	O_ALERT                           = 0x20000000
 	O_APPEND                          = 0x8
@@ -880,6 +955,7 @@
 	O_CREAT                           = 0x200
 	O_DIRECTORY                       = 0x100000
 	O_DP_GETRAWENCRYPTED              = 0x1
+	O_DP_GETRAWUNENCRYPTED            = 0x2
 	O_DSYNC                           = 0x400000
 	O_EVTONLY                         = 0x8000
 	O_EXCL                            = 0x800
@@ -932,7 +1008,10 @@
 	RLIMIT_CPU_USAGE_MONITOR          = 0x2
 	RLIMIT_DATA                       = 0x2
 	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_MEMLOCK                    = 0x6
 	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_NPROC                      = 0x7
+	RLIMIT_RSS                        = 0x5
 	RLIMIT_STACK                      = 0x3
 	RLIM_INFINITY                     = 0x7fffffffffffffff
 	RTAX_AUTHOR                       = 0x6
@@ -1102,6 +1181,8 @@
 	SO_LABEL                          = 0x1010
 	SO_LINGER                         = 0x80
 	SO_LINGER_SEC                     = 0x1080
+	SO_NETSVC_MARKING_LEVEL           = 0x1119
+	SO_NET_SERVICE_TYPE               = 0x1116
 	SO_NKE                            = 0x1021
 	SO_NOADDRERR                      = 0x1023
 	SO_NOSIGPIPE                      = 0x1022
@@ -1157,11 +1238,22 @@
 	S_IXGRP                           = 0x8
 	S_IXOTH                           = 0x1
 	S_IXUSR                           = 0x40
+	TAB0                              = 0x0
+	TAB1                              = 0x400
+	TAB2                              = 0x800
+	TAB3                              = 0x4
+	TABDLY                            = 0xc04
 	TCIFLUSH                          = 0x1
+	TCIOFF                            = 0x3
 	TCIOFLUSH                         = 0x3
+	TCION                             = 0x4
 	TCOFLUSH                          = 0x2
+	TCOOFF                            = 0x1
+	TCOON                             = 0x2
 	TCP_CONNECTIONTIMEOUT             = 0x20
+	TCP_CONNECTION_INFO               = 0x106
 	TCP_ENABLE_ECN                    = 0x104
+	TCP_FASTOPEN                      = 0x105
 	TCP_KEEPALIVE                     = 0x10
 	TCP_KEEPCNT                       = 0x102
 	TCP_KEEPINTVL                     = 0x101
@@ -1261,6 +1353,11 @@
 	VKILL                             = 0x5
 	VLNEXT                            = 0xe
 	VMIN                              = 0x10
+	VM_LOADAVG                        = 0x2
+	VM_MACHFACTOR                     = 0x4
+	VM_MAXID                          = 0x6
+	VM_METER                          = 0x1
+	VM_SWAPUSAGE                      = 0x5
 	VQUIT                             = 0x9
 	VREPRINT                          = 0x6
 	VSTART                            = 0xc
diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
index 7b95751..1d3eec4 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
@@ -1,5 +1,5 @@
 // mkerrors.sh -m32
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build 386,freebsd
 
@@ -11,1456 +11,1419 @@
 import "syscall"
 
 const (
-	AF_APPLETALK                      = 0x10
-	AF_ARP                            = 0x23
-	AF_ATM                            = 0x1e
-	AF_BLUETOOTH                      = 0x24
-	AF_CCITT                          = 0xa
-	AF_CHAOS                          = 0x5
-	AF_CNT                            = 0x15
-	AF_COIP                           = 0x14
-	AF_DATAKIT                        = 0x9
-	AF_DECnet                         = 0xc
-	AF_DLI                            = 0xd
-	AF_E164                           = 0x1a
-	AF_ECMA                           = 0x8
-	AF_HYLINK                         = 0xf
-	AF_IEEE80211                      = 0x25
-	AF_IMPLINK                        = 0x3
-	AF_INET                           = 0x2
-	AF_INET6                          = 0x1c
-	AF_INET6_SDP                      = 0x2a
-	AF_INET_SDP                       = 0x28
-	AF_IPX                            = 0x17
-	AF_ISDN                           = 0x1a
-	AF_ISO                            = 0x7
-	AF_LAT                            = 0xe
-	AF_LINK                           = 0x12
-	AF_LOCAL                          = 0x1
-	AF_MAX                            = 0x2a
-	AF_NATM                           = 0x1d
-	AF_NETBIOS                        = 0x6
-	AF_NETGRAPH                       = 0x20
-	AF_OSI                            = 0x7
-	AF_PUP                            = 0x4
-	AF_ROUTE                          = 0x11
-	AF_SCLUSTER                       = 0x22
-	AF_SIP                            = 0x18
-	AF_SLOW                           = 0x21
-	AF_SNA                            = 0xb
-	AF_UNIX                           = 0x1
-	AF_UNSPEC                         = 0x0
-	AF_VENDOR00                       = 0x27
-	AF_VENDOR01                       = 0x29
-	AF_VENDOR02                       = 0x2b
-	AF_VENDOR03                       = 0x2d
-	AF_VENDOR04                       = 0x2f
-	AF_VENDOR05                       = 0x31
-	AF_VENDOR06                       = 0x33
-	AF_VENDOR07                       = 0x35
-	AF_VENDOR08                       = 0x37
-	AF_VENDOR09                       = 0x39
-	AF_VENDOR10                       = 0x3b
-	AF_VENDOR11                       = 0x3d
-	AF_VENDOR12                       = 0x3f
-	AF_VENDOR13                       = 0x41
-	AF_VENDOR14                       = 0x43
-	AF_VENDOR15                       = 0x45
-	AF_VENDOR16                       = 0x47
-	AF_VENDOR17                       = 0x49
-	AF_VENDOR18                       = 0x4b
-	AF_VENDOR19                       = 0x4d
-	AF_VENDOR20                       = 0x4f
-	AF_VENDOR21                       = 0x51
-	AF_VENDOR22                       = 0x53
-	AF_VENDOR23                       = 0x55
-	AF_VENDOR24                       = 0x57
-	AF_VENDOR25                       = 0x59
-	AF_VENDOR26                       = 0x5b
-	AF_VENDOR27                       = 0x5d
-	AF_VENDOR28                       = 0x5f
-	AF_VENDOR29                       = 0x61
-	AF_VENDOR30                       = 0x63
-	AF_VENDOR31                       = 0x65
-	AF_VENDOR32                       = 0x67
-	AF_VENDOR33                       = 0x69
-	AF_VENDOR34                       = 0x6b
-	AF_VENDOR35                       = 0x6d
-	AF_VENDOR36                       = 0x6f
-	AF_VENDOR37                       = 0x71
-	AF_VENDOR38                       = 0x73
-	AF_VENDOR39                       = 0x75
-	AF_VENDOR40                       = 0x77
-	AF_VENDOR41                       = 0x79
-	AF_VENDOR42                       = 0x7b
-	AF_VENDOR43                       = 0x7d
-	AF_VENDOR44                       = 0x7f
-	AF_VENDOR45                       = 0x81
-	AF_VENDOR46                       = 0x83
-	AF_VENDOR47                       = 0x85
-	B0                                = 0x0
-	B110                              = 0x6e
-	B115200                           = 0x1c200
-	B1200                             = 0x4b0
-	B134                              = 0x86
-	B14400                            = 0x3840
-	B150                              = 0x96
-	B1800                             = 0x708
-	B19200                            = 0x4b00
-	B200                              = 0xc8
-	B230400                           = 0x38400
-	B2400                             = 0x960
-	B28800                            = 0x7080
-	B300                              = 0x12c
-	B38400                            = 0x9600
-	B460800                           = 0x70800
-	B4800                             = 0x12c0
-	B50                               = 0x32
-	B57600                            = 0xe100
-	B600                              = 0x258
-	B7200                             = 0x1c20
-	B75                               = 0x4b
-	B76800                            = 0x12c00
-	B921600                           = 0xe1000
-	B9600                             = 0x2580
-	BIOCFEEDBACK                      = 0x8004427c
-	BIOCFLUSH                         = 0x20004268
-	BIOCGBLEN                         = 0x40044266
-	BIOCGDIRECTION                    = 0x40044276
-	BIOCGDLT                          = 0x4004426a
-	BIOCGDLTLIST                      = 0xc0084279
-	BIOCGETBUFMODE                    = 0x4004427d
-	BIOCGETIF                         = 0x4020426b
-	BIOCGETZMAX                       = 0x4004427f
-	BIOCGHDRCMPLT                     = 0x40044274
-	BIOCGRSIG                         = 0x40044272
-	BIOCGRTIMEOUT                     = 0x4008426e
-	BIOCGSEESENT                      = 0x40044276
-	BIOCGSTATS                        = 0x4008426f
-	BIOCGTSTAMP                       = 0x40044283
-	BIOCIMMEDIATE                     = 0x80044270
-	BIOCLOCK                          = 0x2000427a
-	BIOCPROMISC                       = 0x20004269
-	BIOCROTZBUF                       = 0x400c4280
-	BIOCSBLEN                         = 0xc0044266
-	BIOCSDIRECTION                    = 0x80044277
-	BIOCSDLT                          = 0x80044278
-	BIOCSETBUFMODE                    = 0x8004427e
-	BIOCSETF                          = 0x80084267
-	BIOCSETFNR                        = 0x80084282
-	BIOCSETIF                         = 0x8020426c
-	BIOCSETWF                         = 0x8008427b
-	BIOCSETZBUF                       = 0x800c4281
-	BIOCSHDRCMPLT                     = 0x80044275
-	BIOCSRSIG                         = 0x80044273
-	BIOCSRTIMEOUT                     = 0x8008426d
-	BIOCSSEESENT                      = 0x80044277
-	BIOCSTSTAMP                       = 0x80044284
-	BIOCVERSION                       = 0x40044271
-	BPF_A                             = 0x10
-	BPF_ABS                           = 0x20
-	BPF_ADD                           = 0x0
-	BPF_ALIGNMENT                     = 0x4
-	BPF_ALU                           = 0x4
-	BPF_AND                           = 0x50
-	BPF_B                             = 0x10
-	BPF_BUFMODE_BUFFER                = 0x1
-	BPF_BUFMODE_ZBUF                  = 0x2
-	BPF_DIV                           = 0x30
-	BPF_H                             = 0x8
-	BPF_IMM                           = 0x0
-	BPF_IND                           = 0x40
-	BPF_JA                            = 0x0
-	BPF_JEQ                           = 0x10
-	BPF_JGE                           = 0x30
-	BPF_JGT                           = 0x20
-	BPF_JMP                           = 0x5
-	BPF_JSET                          = 0x40
-	BPF_K                             = 0x0
-	BPF_LD                            = 0x0
-	BPF_LDX                           = 0x1
-	BPF_LEN                           = 0x80
-	BPF_LSH                           = 0x60
-	BPF_MAJOR_VERSION                 = 0x1
-	BPF_MAXBUFSIZE                    = 0x80000
-	BPF_MAXINSNS                      = 0x200
-	BPF_MEM                           = 0x60
-	BPF_MEMWORDS                      = 0x10
-	BPF_MINBUFSIZE                    = 0x20
-	BPF_MINOR_VERSION                 = 0x1
-	BPF_MISC                          = 0x7
-	BPF_MSH                           = 0xa0
-	BPF_MUL                           = 0x20
-	BPF_NEG                           = 0x80
-	BPF_OR                            = 0x40
-	BPF_RELEASE                       = 0x30bb6
-	BPF_RET                           = 0x6
-	BPF_RSH                           = 0x70
-	BPF_ST                            = 0x2
-	BPF_STX                           = 0x3
-	BPF_SUB                           = 0x10
-	BPF_TAX                           = 0x0
-	BPF_TXA                           = 0x80
-	BPF_T_BINTIME                     = 0x2
-	BPF_T_BINTIME_FAST                = 0x102
-	BPF_T_BINTIME_MONOTONIC           = 0x202
-	BPF_T_BINTIME_MONOTONIC_FAST      = 0x302
-	BPF_T_FAST                        = 0x100
-	BPF_T_FLAG_MASK                   = 0x300
-	BPF_T_FORMAT_MASK                 = 0x3
-	BPF_T_MICROTIME                   = 0x0
-	BPF_T_MICROTIME_FAST              = 0x100
-	BPF_T_MICROTIME_MONOTONIC         = 0x200
-	BPF_T_MICROTIME_MONOTONIC_FAST    = 0x300
-	BPF_T_MONOTONIC                   = 0x200
-	BPF_T_MONOTONIC_FAST              = 0x300
-	BPF_T_NANOTIME                    = 0x1
-	BPF_T_NANOTIME_FAST               = 0x101
-	BPF_T_NANOTIME_MONOTONIC          = 0x201
-	BPF_T_NANOTIME_MONOTONIC_FAST     = 0x301
-	BPF_T_NONE                        = 0x3
-	BPF_T_NORMAL                      = 0x0
-	BPF_W                             = 0x0
-	BPF_X                             = 0x8
-	BRKINT                            = 0x2
-	CFLUSH                            = 0xf
-	CLOCAL                            = 0x8000
-	CLOCK_MONOTONIC                   = 0x4
-	CLOCK_MONOTONIC_FAST              = 0xc
-	CLOCK_MONOTONIC_PRECISE           = 0xb
-	CLOCK_PROCESS_CPUTIME_ID          = 0xf
-	CLOCK_PROF                        = 0x2
-	CLOCK_REALTIME                    = 0x0
-	CLOCK_REALTIME_FAST               = 0xa
-	CLOCK_REALTIME_PRECISE            = 0x9
-	CLOCK_SECOND                      = 0xd
-	CLOCK_THREAD_CPUTIME_ID           = 0xe
-	CLOCK_UPTIME                      = 0x5
-	CLOCK_UPTIME_FAST                 = 0x8
-	CLOCK_UPTIME_PRECISE              = 0x7
-	CLOCK_VIRTUAL                     = 0x1
-	CREAD                             = 0x800
-	CS5                               = 0x0
-	CS6                               = 0x100
-	CS7                               = 0x200
-	CS8                               = 0x300
-	CSIZE                             = 0x300
-	CSTART                            = 0x11
-	CSTATUS                           = 0x14
-	CSTOP                             = 0x13
-	CSTOPB                            = 0x400
-	CSUSP                             = 0x1a
-	CTL_MAXNAME                       = 0x18
-	CTL_NET                           = 0x4
-	DLT_A429                          = 0xb8
-	DLT_A653_ICM                      = 0xb9
-	DLT_AIRONET_HEADER                = 0x78
-	DLT_AOS                           = 0xde
-	DLT_APPLE_IP_OVER_IEEE1394        = 0x8a
-	DLT_ARCNET                        = 0x7
-	DLT_ARCNET_LINUX                  = 0x81
-	DLT_ATM_CLIP                      = 0x13
-	DLT_ATM_RFC1483                   = 0xb
-	DLT_AURORA                        = 0x7e
-	DLT_AX25                          = 0x3
-	DLT_AX25_KISS                     = 0xca
-	DLT_BACNET_MS_TP                  = 0xa5
-	DLT_BLUETOOTH_HCI_H4              = 0xbb
-	DLT_BLUETOOTH_HCI_H4_WITH_PHDR    = 0xc9
-	DLT_CAN20B                        = 0xbe
-	DLT_CAN_SOCKETCAN                 = 0xe3
-	DLT_CHAOS                         = 0x5
-	DLT_CHDLC                         = 0x68
-	DLT_CISCO_IOS                     = 0x76
-	DLT_C_HDLC                        = 0x68
-	DLT_C_HDLC_WITH_DIR               = 0xcd
-	DLT_DBUS                          = 0xe7
-	DLT_DECT                          = 0xdd
-	DLT_DOCSIS                        = 0x8f
-	DLT_DVB_CI                        = 0xeb
-	DLT_ECONET                        = 0x73
-	DLT_EN10MB                        = 0x1
-	DLT_EN3MB                         = 0x2
-	DLT_ENC                           = 0x6d
-	DLT_ERF                           = 0xc5
-	DLT_ERF_ETH                       = 0xaf
-	DLT_ERF_POS                       = 0xb0
-	DLT_FC_2                          = 0xe0
-	DLT_FC_2_WITH_FRAME_DELIMS        = 0xe1
-	DLT_FDDI                          = 0xa
-	DLT_FLEXRAY                       = 0xd2
-	DLT_FRELAY                        = 0x6b
-	DLT_FRELAY_WITH_DIR               = 0xce
-	DLT_GCOM_SERIAL                   = 0xad
-	DLT_GCOM_T1E1                     = 0xac
-	DLT_GPF_F                         = 0xab
-	DLT_GPF_T                         = 0xaa
-	DLT_GPRS_LLC                      = 0xa9
-	DLT_GSMTAP_ABIS                   = 0xda
-	DLT_GSMTAP_UM                     = 0xd9
-	DLT_HHDLC                         = 0x79
-	DLT_IBM_SN                        = 0x92
-	DLT_IBM_SP                        = 0x91
-	DLT_IEEE802                       = 0x6
-	DLT_IEEE802_11                    = 0x69
-	DLT_IEEE802_11_RADIO              = 0x7f
-	DLT_IEEE802_11_RADIO_AVS          = 0xa3
-	DLT_IEEE802_15_4                  = 0xc3
-	DLT_IEEE802_15_4_LINUX            = 0xbf
-	DLT_IEEE802_15_4_NOFCS            = 0xe6
-	DLT_IEEE802_15_4_NONASK_PHY       = 0xd7
-	DLT_IEEE802_16_MAC_CPS            = 0xbc
-	DLT_IEEE802_16_MAC_CPS_RADIO      = 0xc1
-	DLT_IPFILTER                      = 0x74
-	DLT_IPMB                          = 0xc7
-	DLT_IPMB_LINUX                    = 0xd1
-	DLT_IPNET                         = 0xe2
-	DLT_IPOIB                         = 0xf2
-	DLT_IPV4                          = 0xe4
-	DLT_IPV6                          = 0xe5
-	DLT_IP_OVER_FC                    = 0x7a
-	DLT_JUNIPER_ATM1                  = 0x89
-	DLT_JUNIPER_ATM2                  = 0x87
-	DLT_JUNIPER_ATM_CEMIC             = 0xee
-	DLT_JUNIPER_CHDLC                 = 0xb5
-	DLT_JUNIPER_ES                    = 0x84
-	DLT_JUNIPER_ETHER                 = 0xb2
-	DLT_JUNIPER_FIBRECHANNEL          = 0xea
-	DLT_JUNIPER_FRELAY                = 0xb4
-	DLT_JUNIPER_GGSN                  = 0x85
-	DLT_JUNIPER_ISM                   = 0xc2
-	DLT_JUNIPER_MFR                   = 0x86
-	DLT_JUNIPER_MLFR                  = 0x83
-	DLT_JUNIPER_MLPPP                 = 0x82
-	DLT_JUNIPER_MONITOR               = 0xa4
-	DLT_JUNIPER_PIC_PEER              = 0xae
-	DLT_JUNIPER_PPP                   = 0xb3
-	DLT_JUNIPER_PPPOE                 = 0xa7
-	DLT_JUNIPER_PPPOE_ATM             = 0xa8
-	DLT_JUNIPER_SERVICES              = 0x88
-	DLT_JUNIPER_SRX_E2E               = 0xe9
-	DLT_JUNIPER_ST                    = 0xc8
-	DLT_JUNIPER_VP                    = 0xb7
-	DLT_JUNIPER_VS                    = 0xe8
-	DLT_LAPB_WITH_DIR                 = 0xcf
-	DLT_LAPD                          = 0xcb
-	DLT_LIN                           = 0xd4
-	DLT_LINUX_EVDEV                   = 0xd8
-	DLT_LINUX_IRDA                    = 0x90
-	DLT_LINUX_LAPD                    = 0xb1
-	DLT_LINUX_PPP_WITHDIRECTION       = 0xa6
-	DLT_LINUX_SLL                     = 0x71
-	DLT_LOOP                          = 0x6c
-	DLT_LTALK                         = 0x72
-	DLT_MATCHING_MAX                  = 0xf6
-	DLT_MATCHING_MIN                  = 0x68
-	DLT_MFR                           = 0xb6
-	DLT_MOST                          = 0xd3
-	DLT_MPEG_2_TS                     = 0xf3
-	DLT_MPLS                          = 0xdb
-	DLT_MTP2                          = 0x8c
-	DLT_MTP2_WITH_PHDR                = 0x8b
-	DLT_MTP3                          = 0x8d
-	DLT_MUX27010                      = 0xec
-	DLT_NETANALYZER                   = 0xf0
-	DLT_NETANALYZER_TRANSPARENT       = 0xf1
-	DLT_NFC_LLCP                      = 0xf5
-	DLT_NFLOG                         = 0xef
-	DLT_NG40                          = 0xf4
-	DLT_NULL                          = 0x0
-	DLT_PCI_EXP                       = 0x7d
-	DLT_PFLOG                         = 0x75
-	DLT_PFSYNC                        = 0x79
-	DLT_PPI                           = 0xc0
-	DLT_PPP                           = 0x9
-	DLT_PPP_BSDOS                     = 0x10
-	DLT_PPP_ETHER                     = 0x33
-	DLT_PPP_PPPD                      = 0xa6
-	DLT_PPP_SERIAL                    = 0x32
-	DLT_PPP_WITH_DIR                  = 0xcc
-	DLT_PPP_WITH_DIRECTION            = 0xa6
-	DLT_PRISM_HEADER                  = 0x77
-	DLT_PRONET                        = 0x4
-	DLT_RAIF1                         = 0xc6
-	DLT_RAW                           = 0xc
-	DLT_RIO                           = 0x7c
-	DLT_SCCP                          = 0x8e
-	DLT_SITA                          = 0xc4
-	DLT_SLIP                          = 0x8
-	DLT_SLIP_BSDOS                    = 0xf
-	DLT_STANAG_5066_D_PDU             = 0xed
-	DLT_SUNATM                        = 0x7b
-	DLT_SYMANTEC_FIREWALL             = 0x63
-	DLT_TZSP                          = 0x80
-	DLT_USB                           = 0xba
-	DLT_USB_LINUX                     = 0xbd
-	DLT_USB_LINUX_MMAPPED             = 0xdc
-	DLT_USER0                         = 0x93
-	DLT_USER1                         = 0x94
-	DLT_USER10                        = 0x9d
-	DLT_USER11                        = 0x9e
-	DLT_USER12                        = 0x9f
-	DLT_USER13                        = 0xa0
-	DLT_USER14                        = 0xa1
-	DLT_USER15                        = 0xa2
-	DLT_USER2                         = 0x95
-	DLT_USER3                         = 0x96
-	DLT_USER4                         = 0x97
-	DLT_USER5                         = 0x98
-	DLT_USER6                         = 0x99
-	DLT_USER7                         = 0x9a
-	DLT_USER8                         = 0x9b
-	DLT_USER9                         = 0x9c
-	DLT_WIHART                        = 0xdf
-	DLT_X2E_SERIAL                    = 0xd5
-	DLT_X2E_XORAYA                    = 0xd6
-	DT_BLK                            = 0x6
-	DT_CHR                            = 0x2
-	DT_DIR                            = 0x4
-	DT_FIFO                           = 0x1
-	DT_LNK                            = 0xa
-	DT_REG                            = 0x8
-	DT_SOCK                           = 0xc
-	DT_UNKNOWN                        = 0x0
-	DT_WHT                            = 0xe
-	ECHO                              = 0x8
-	ECHOCTL                           = 0x40
-	ECHOE                             = 0x2
-	ECHOK                             = 0x4
-	ECHOKE                            = 0x1
-	ECHONL                            = 0x10
-	ECHOPRT                           = 0x20
-	EVFILT_AIO                        = -0x3
-	EVFILT_FS                         = -0x9
-	EVFILT_LIO                        = -0xa
-	EVFILT_PROC                       = -0x5
-	EVFILT_READ                       = -0x1
-	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xb
-	EVFILT_TIMER                      = -0x7
-	EVFILT_USER                       = -0xb
-	EVFILT_VNODE                      = -0x4
-	EVFILT_WRITE                      = -0x2
-	EV_ADD                            = 0x1
-	EV_CLEAR                          = 0x20
-	EV_DELETE                         = 0x2
-	EV_DISABLE                        = 0x8
-	EV_DISPATCH                       = 0x80
-	EV_DROP                           = 0x1000
-	EV_ENABLE                         = 0x4
-	EV_EOF                            = 0x8000
-	EV_ERROR                          = 0x4000
-	EV_FLAG1                          = 0x2000
-	EV_ONESHOT                        = 0x10
-	EV_RECEIPT                        = 0x40
-	EV_SYSFLAGS                       = 0xf000
-	EXTA                              = 0x4b00
-	EXTATTR_NAMESPACE_EMPTY           = 0x0
-	EXTATTR_NAMESPACE_SYSTEM          = 0x2
-	EXTATTR_NAMESPACE_USER            = 0x1
-	EXTB                              = 0x9600
-	EXTPROC                           = 0x800
-	FD_CLOEXEC                        = 0x1
-	FD_SETSIZE                        = 0x400
-	FLUSHO                            = 0x800000
-	F_CANCEL                          = 0x5
-	F_DUP2FD                          = 0xa
-	F_DUP2FD_CLOEXEC                  = 0x12
-	F_DUPFD                           = 0x0
-	F_DUPFD_CLOEXEC                   = 0x11
-	F_GETFD                           = 0x1
-	F_GETFL                           = 0x3
-	F_GETLK                           = 0xb
-	F_GETOWN                          = 0x5
-	F_OGETLK                          = 0x7
-	F_OK                              = 0x0
-	F_OSETLK                          = 0x8
-	F_OSETLKW                         = 0x9
-	F_RDAHEAD                         = 0x10
-	F_RDLCK                           = 0x1
-	F_READAHEAD                       = 0xf
-	F_SETFD                           = 0x2
-	F_SETFL                           = 0x4
-	F_SETLK                           = 0xc
-	F_SETLKW                          = 0xd
-	F_SETLK_REMOTE                    = 0xe
-	F_SETOWN                          = 0x6
-	F_UNLCK                           = 0x2
-	F_UNLCKSYS                        = 0x4
-	F_WRLCK                           = 0x3
-	HUPCL                             = 0x4000
-	ICANON                            = 0x100
-	ICMP6_FILTER                      = 0x12
-	ICRNL                             = 0x100
-	IEXTEN                            = 0x400
-	IFAN_ARRIVAL                      = 0x0
-	IFAN_DEPARTURE                    = 0x1
-	IFF_ALLMULTI                      = 0x200
-	IFF_ALTPHYS                       = 0x4000
-	IFF_BROADCAST                     = 0x2
-	IFF_CANTCHANGE                    = 0x218f72
-	IFF_CANTCONFIG                    = 0x10000
-	IFF_DEBUG                         = 0x4
-	IFF_DRV_OACTIVE                   = 0x400
-	IFF_DRV_RUNNING                   = 0x40
-	IFF_DYING                         = 0x200000
-	IFF_LINK0                         = 0x1000
-	IFF_LINK1                         = 0x2000
-	IFF_LINK2                         = 0x4000
-	IFF_LOOPBACK                      = 0x8
-	IFF_MONITOR                       = 0x40000
-	IFF_MULTICAST                     = 0x8000
-	IFF_NOARP                         = 0x80
-	IFF_OACTIVE                       = 0x400
-	IFF_POINTOPOINT                   = 0x10
-	IFF_PPROMISC                      = 0x20000
-	IFF_PROMISC                       = 0x100
-	IFF_RENAMING                      = 0x400000
-	IFF_RUNNING                       = 0x40
-	IFF_SIMPLEX                       = 0x800
-	IFF_SMART                         = 0x20
-	IFF_STATICARP                     = 0x80000
-	IFF_UP                            = 0x1
-	IFNAMSIZ                          = 0x10
-	IFT_1822                          = 0x2
-	IFT_A12MPPSWITCH                  = 0x82
-	IFT_AAL2                          = 0xbb
-	IFT_AAL5                          = 0x31
-	IFT_ADSL                          = 0x5e
-	IFT_AFLANE8023                    = 0x3b
-	IFT_AFLANE8025                    = 0x3c
-	IFT_ARAP                          = 0x58
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ASYNC                         = 0x54
-	IFT_ATM                           = 0x25
-	IFT_ATMDXI                        = 0x69
-	IFT_ATMFUNI                       = 0x6a
-	IFT_ATMIMA                        = 0x6b
-	IFT_ATMLOGICAL                    = 0x50
-	IFT_ATMRADIO                      = 0xbd
-	IFT_ATMSUBINTERFACE               = 0x86
-	IFT_ATMVCIENDPT                   = 0xc2
-	IFT_ATMVIRTUAL                    = 0x95
-	IFT_BGPPOLICYACCOUNTING           = 0xa2
-	IFT_BRIDGE                        = 0xd1
-	IFT_BSC                           = 0x53
-	IFT_CARP                          = 0xf8
-	IFT_CCTEMUL                       = 0x3d
-	IFT_CEPT                          = 0x13
-	IFT_CES                           = 0x85
-	IFT_CHANNEL                       = 0x46
-	IFT_CNR                           = 0x55
-	IFT_COFFEE                        = 0x84
-	IFT_COMPOSITELINK                 = 0x9b
-	IFT_DCN                           = 0x8d
-	IFT_DIGITALPOWERLINE              = 0x8a
-	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
-	IFT_DLSW                          = 0x4a
-	IFT_DOCSCABLEDOWNSTREAM           = 0x80
-	IFT_DOCSCABLEMACLAYER             = 0x7f
-	IFT_DOCSCABLEUPSTREAM             = 0x81
-	IFT_DS0                           = 0x51
-	IFT_DS0BUNDLE                     = 0x52
-	IFT_DS1FDL                        = 0xaa
-	IFT_DS3                           = 0x1e
-	IFT_DTM                           = 0x8c
-	IFT_DVBASILN                      = 0xac
-	IFT_DVBASIOUT                     = 0xad
-	IFT_DVBRCCDOWNSTREAM              = 0x93
-	IFT_DVBRCCMACLAYER                = 0x92
-	IFT_DVBRCCUPSTREAM                = 0x94
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_EPLRS                         = 0x57
-	IFT_ESCON                         = 0x49
-	IFT_ETHER                         = 0x6
-	IFT_FAITH                         = 0xf2
-	IFT_FAST                          = 0x7d
-	IFT_FASTETHER                     = 0x3e
-	IFT_FASTETHERFX                   = 0x45
-	IFT_FDDI                          = 0xf
-	IFT_FIBRECHANNEL                  = 0x38
-	IFT_FRAMERELAYINTERCONNECT        = 0x3a
-	IFT_FRAMERELAYMPI                 = 0x5c
-	IFT_FRDLCIENDPT                   = 0xc1
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_FRF16MFRBUNDLE                = 0xa3
-	IFT_FRFORWARD                     = 0x9e
-	IFT_G703AT2MB                     = 0x43
-	IFT_G703AT64K                     = 0x42
-	IFT_GIF                           = 0xf0
-	IFT_GIGABITETHERNET               = 0x75
-	IFT_GR303IDT                      = 0xb2
-	IFT_GR303RDT                      = 0xb1
-	IFT_H323GATEKEEPER                = 0xa4
-	IFT_H323PROXY                     = 0xa5
-	IFT_HDH1822                       = 0x3
-	IFT_HDLC                          = 0x76
-	IFT_HDSL2                         = 0xa8
-	IFT_HIPERLAN2                     = 0xb7
-	IFT_HIPPI                         = 0x2f
-	IFT_HIPPIINTERFACE                = 0x39
-	IFT_HOSTPAD                       = 0x5a
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IBM370PARCHAN                 = 0x48
-	IFT_IDSL                          = 0x9a
-	IFT_IEEE1394                      = 0x90
-	IFT_IEEE80211                     = 0x47
-	IFT_IEEE80212                     = 0x37
-	IFT_IEEE8023ADLAG                 = 0xa1
-	IFT_IFGSN                         = 0x91
-	IFT_IMT                           = 0xbe
-	IFT_INFINIBAND                    = 0xc7
-	IFT_INTERLEAVE                    = 0x7c
-	IFT_IP                            = 0x7e
-	IFT_IPFORWARD                     = 0x8e
-	IFT_IPOVERATM                     = 0x72
-	IFT_IPOVERCDLC                    = 0x6d
-	IFT_IPOVERCLAW                    = 0x6e
-	IFT_IPSWITCH                      = 0x4e
-	IFT_IPXIP                         = 0xf9
-	IFT_ISDN                          = 0x3f
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISDNS                         = 0x4b
-	IFT_ISDNU                         = 0x4c
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88025CRFPINT               = 0x62
-	IFT_ISO88025DTR                   = 0x56
-	IFT_ISO88025FIBER                 = 0x73
-	IFT_ISO88026                      = 0xa
-	IFT_ISUP                          = 0xb3
-	IFT_L2VLAN                        = 0x87
-	IFT_L3IPVLAN                      = 0x88
-	IFT_L3IPXVLAN                     = 0x89
-	IFT_LAPB                          = 0x10
-	IFT_LAPD                          = 0x4d
-	IFT_LAPF                          = 0x77
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MEDIAMAILOVERIP               = 0x8b
-	IFT_MFSIGLINK                     = 0xa7
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_MPC                           = 0x71
-	IFT_MPLS                          = 0xa6
-	IFT_MPLSTUNNEL                    = 0x96
-	IFT_MSDSL                         = 0x8f
-	IFT_MVL                           = 0xbf
-	IFT_MYRINET                       = 0x63
-	IFT_NFAS                          = 0xaf
-	IFT_NSIP                          = 0x1b
-	IFT_OPTICALCHANNEL                = 0xc3
-	IFT_OPTICALTRANSPORT              = 0xc4
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PFLOG                         = 0xf6
-	IFT_PFSYNC                        = 0xf7
-	IFT_PLC                           = 0xae
-	IFT_POS                           = 0xab
-	IFT_PPP                           = 0x17
-	IFT_PPPMULTILINKBUNDLE            = 0x6c
-	IFT_PROPBWAP2MP                   = 0xb8
-	IFT_PROPCNLS                      = 0x59
-	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
-	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
-	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPVIRTUAL                   = 0x35
-	IFT_PROPWIRELESSP2P               = 0x9d
-	IFT_PTPSERIAL                     = 0x16
-	IFT_PVC                           = 0xf1
-	IFT_QLLC                          = 0x44
-	IFT_RADIOMAC                      = 0xbc
-	IFT_RADSL                         = 0x5f
-	IFT_REACHDSL                      = 0xc0
-	IFT_RFC1483                       = 0x9f
-	IFT_RS232                         = 0x21
-	IFT_RSRB                          = 0x4f
-	IFT_SDLC                          = 0x11
-	IFT_SDSL                          = 0x60
-	IFT_SHDSL                         = 0xa9
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETOVERHEADCHANNEL          = 0xb9
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_SRP                           = 0x97
-	IFT_SS7SIGLINK                    = 0x9c
-	IFT_STACKTOSTACK                  = 0x6f
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0xd7
-	IFT_T1                            = 0x12
-	IFT_TDLC                          = 0x74
-	IFT_TERMPAD                       = 0x5b
-	IFT_TR008                         = 0xb0
-	IFT_TRANSPHDLC                    = 0x7b
-	IFT_TUNNEL                        = 0x83
-	IFT_ULTRA                         = 0x1d
-	IFT_USB                           = 0xa0
-	IFT_V11                           = 0x40
-	IFT_V35                           = 0x2d
-	IFT_V36                           = 0x41
-	IFT_V37                           = 0x78
-	IFT_VDSL                          = 0x61
-	IFT_VIRTUALIPADDRESS              = 0x70
-	IFT_VOICEEM                       = 0x64
-	IFT_VOICEENCAP                    = 0x67
-	IFT_VOICEFXO                      = 0x65
-	IFT_VOICEFXS                      = 0x66
-	IFT_VOICEOVERATM                  = 0x98
-	IFT_VOICEOVERFRAMERELAY           = 0x99
-	IFT_VOICEOVERIP                   = 0x68
-	IFT_X213                          = 0x5d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25HUNTGROUP                  = 0x7a
-	IFT_X25MLP                        = 0x79
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-	IGNBRK                            = 0x1
-	IGNCR                             = 0x80
-	IGNPAR                            = 0x4
-	IMAXBEL                           = 0x2000
-	INLCR                             = 0x40
-	INPCK                             = 0x10
-	IN_CLASSA_HOST                    = 0xffffff
-	IN_CLASSA_MAX                     = 0x80
-	IN_CLASSA_NET                     = 0xff000000
-	IN_CLASSA_NSHIFT                  = 0x18
-	IN_CLASSB_HOST                    = 0xffff
-	IN_CLASSB_MAX                     = 0x10000
-	IN_CLASSB_NET                     = 0xffff0000
-	IN_CLASSB_NSHIFT                  = 0x10
-	IN_CLASSC_HOST                    = 0xff
-	IN_CLASSC_NET                     = 0xffffff00
-	IN_CLASSC_NSHIFT                  = 0x8
-	IN_CLASSD_HOST                    = 0xfffffff
-	IN_CLASSD_NET                     = 0xf0000000
-	IN_CLASSD_NSHIFT                  = 0x1c
-	IN_LOOPBACKNET                    = 0x7f
-	IN_RFC3021_MASK                   = 0xfffffffe
-	IPPROTO_3PC                       = 0x22
-	IPPROTO_ADFS                      = 0x44
-	IPPROTO_AH                        = 0x33
-	IPPROTO_AHIP                      = 0x3d
-	IPPROTO_APES                      = 0x63
-	IPPROTO_ARGUS                     = 0xd
-	IPPROTO_AX25                      = 0x5d
-	IPPROTO_BHA                       = 0x31
-	IPPROTO_BLT                       = 0x1e
-	IPPROTO_BRSATMON                  = 0x4c
-	IPPROTO_CARP                      = 0x70
-	IPPROTO_CFTP                      = 0x3e
-	IPPROTO_CHAOS                     = 0x10
-	IPPROTO_CMTP                      = 0x26
-	IPPROTO_CPHB                      = 0x49
-	IPPROTO_CPNX                      = 0x48
-	IPPROTO_DDP                       = 0x25
-	IPPROTO_DGP                       = 0x56
-	IPPROTO_DIVERT                    = 0x102
-	IPPROTO_DONE                      = 0x101
-	IPPROTO_DSTOPTS                   = 0x3c
-	IPPROTO_EGP                       = 0x8
-	IPPROTO_EMCON                     = 0xe
-	IPPROTO_ENCAP                     = 0x62
-	IPPROTO_EON                       = 0x50
-	IPPROTO_ESP                       = 0x32
-	IPPROTO_ETHERIP                   = 0x61
-	IPPROTO_FRAGMENT                  = 0x2c
-	IPPROTO_GGP                       = 0x3
-	IPPROTO_GMTP                      = 0x64
-	IPPROTO_GRE                       = 0x2f
-	IPPROTO_HELLO                     = 0x3f
-	IPPROTO_HIP                       = 0x8b
-	IPPROTO_HMP                       = 0x14
-	IPPROTO_HOPOPTS                   = 0x0
-	IPPROTO_ICMP                      = 0x1
-	IPPROTO_ICMPV6                    = 0x3a
-	IPPROTO_IDP                       = 0x16
-	IPPROTO_IDPR                      = 0x23
-	IPPROTO_IDRP                      = 0x2d
-	IPPROTO_IGMP                      = 0x2
-	IPPROTO_IGP                       = 0x55
-	IPPROTO_IGRP                      = 0x58
-	IPPROTO_IL                        = 0x28
-	IPPROTO_INLSP                     = 0x34
-	IPPROTO_INP                       = 0x20
-	IPPROTO_IP                        = 0x0
-	IPPROTO_IPCOMP                    = 0x6c
-	IPPROTO_IPCV                      = 0x47
-	IPPROTO_IPEIP                     = 0x5e
-	IPPROTO_IPIP                      = 0x4
-	IPPROTO_IPPC                      = 0x43
-	IPPROTO_IPV4                      = 0x4
-	IPPROTO_IPV6                      = 0x29
-	IPPROTO_IRTP                      = 0x1c
-	IPPROTO_KRYPTOLAN                 = 0x41
-	IPPROTO_LARP                      = 0x5b
-	IPPROTO_LEAF1                     = 0x19
-	IPPROTO_LEAF2                     = 0x1a
-	IPPROTO_MAX                       = 0x100
-	IPPROTO_MAXID                     = 0x34
-	IPPROTO_MEAS                      = 0x13
-	IPPROTO_MH                        = 0x87
-	IPPROTO_MHRP                      = 0x30
-	IPPROTO_MICP                      = 0x5f
-	IPPROTO_MOBILE                    = 0x37
-	IPPROTO_MPLS                      = 0x89
-	IPPROTO_MTP                       = 0x5c
-	IPPROTO_MUX                       = 0x12
-	IPPROTO_ND                        = 0x4d
-	IPPROTO_NHRP                      = 0x36
-	IPPROTO_NONE                      = 0x3b
-	IPPROTO_NSP                       = 0x1f
-	IPPROTO_NVPII                     = 0xb
-	IPPROTO_OLD_DIVERT                = 0xfe
-	IPPROTO_OSPFIGP                   = 0x59
-	IPPROTO_PFSYNC                    = 0xf0
-	IPPROTO_PGM                       = 0x71
-	IPPROTO_PIGP                      = 0x9
-	IPPROTO_PIM                       = 0x67
-	IPPROTO_PRM                       = 0x15
-	IPPROTO_PUP                       = 0xc
-	IPPROTO_PVP                       = 0x4b
-	IPPROTO_RAW                       = 0xff
-	IPPROTO_RCCMON                    = 0xa
-	IPPROTO_RDP                       = 0x1b
-	IPPROTO_RESERVED_253              = 0xfd
-	IPPROTO_RESERVED_254              = 0xfe
-	IPPROTO_ROUTING                   = 0x2b
-	IPPROTO_RSVP                      = 0x2e
-	IPPROTO_RVD                       = 0x42
-	IPPROTO_SATEXPAK                  = 0x40
-	IPPROTO_SATMON                    = 0x45
-	IPPROTO_SCCSP                     = 0x60
-	IPPROTO_SCTP                      = 0x84
-	IPPROTO_SDRP                      = 0x2a
-	IPPROTO_SEND                      = 0x103
-	IPPROTO_SEP                       = 0x21
-	IPPROTO_SHIM6                     = 0x8c
-	IPPROTO_SKIP                      = 0x39
-	IPPROTO_SPACER                    = 0x7fff
-	IPPROTO_SRPC                      = 0x5a
-	IPPROTO_ST                        = 0x7
-	IPPROTO_SVMTP                     = 0x52
-	IPPROTO_SWIPE                     = 0x35
-	IPPROTO_TCF                       = 0x57
-	IPPROTO_TCP                       = 0x6
-	IPPROTO_TLSP                      = 0x38
-	IPPROTO_TP                        = 0x1d
-	IPPROTO_TPXX                      = 0x27
-	IPPROTO_TRUNK1                    = 0x17
-	IPPROTO_TRUNK2                    = 0x18
-	IPPROTO_TTP                       = 0x54
-	IPPROTO_UDP                       = 0x11
-	IPPROTO_UDPLITE                   = 0x88
-	IPPROTO_VINES                     = 0x53
-	IPPROTO_VISA                      = 0x46
-	IPPROTO_VMTP                      = 0x51
-	IPPROTO_WBEXPAK                   = 0x4f
-	IPPROTO_WBMON                     = 0x4e
-	IPPROTO_WSN                       = 0x4a
-	IPPROTO_XNET                      = 0xf
-	IPPROTO_XTP                       = 0x24
-	IPV6_AUTOFLOWLABEL                = 0x3b
-	IPV6_BINDANY                      = 0x40
-	IPV6_BINDV6ONLY                   = 0x1b
-	IPV6_CHECKSUM                     = 0x1a
-	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
-	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
-	IPV6_DEFHLIM                      = 0x40
-	IPV6_DONTFRAG                     = 0x3e
-	IPV6_DSTOPTS                      = 0x32
-	IPV6_FAITH                        = 0x1d
-	IPV6_FLOWINFO_MASK                = 0xffffff0f
-	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FRAGTTL                      = 0x78
-	IPV6_FW_ADD                       = 0x1e
-	IPV6_FW_DEL                       = 0x1f
-	IPV6_FW_FLUSH                     = 0x20
-	IPV6_FW_GET                       = 0x22
-	IPV6_FW_ZERO                      = 0x21
-	IPV6_HLIMDEC                      = 0x1
-	IPV6_HOPLIMIT                     = 0x2f
-	IPV6_HOPOPTS                      = 0x31
-	IPV6_IPSEC_POLICY                 = 0x1c
-	IPV6_JOIN_GROUP                   = 0xc
-	IPV6_LEAVE_GROUP                  = 0xd
-	IPV6_MAXHLIM                      = 0xff
-	IPV6_MAXOPTHDR                    = 0x800
-	IPV6_MAXPACKET                    = 0xffff
-	IPV6_MAX_GROUP_SRC_FILTER         = 0x200
-	IPV6_MAX_MEMBERSHIPS              = 0xfff
-	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
-	IPV6_MIN_MEMBERSHIPS              = 0x1f
-	IPV6_MMTU                         = 0x500
-	IPV6_MSFILTER                     = 0x4a
-	IPV6_MULTICAST_HOPS               = 0xa
-	IPV6_MULTICAST_IF                 = 0x9
-	IPV6_MULTICAST_LOOP               = 0xb
-	IPV6_NEXTHOP                      = 0x30
-	IPV6_PATHMTU                      = 0x2c
-	IPV6_PKTINFO                      = 0x2e
-	IPV6_PORTRANGE                    = 0xe
-	IPV6_PORTRANGE_DEFAULT            = 0x0
-	IPV6_PORTRANGE_HIGH               = 0x1
-	IPV6_PORTRANGE_LOW                = 0x2
-	IPV6_PREFER_TEMPADDR              = 0x3f
-	IPV6_RECVDSTOPTS                  = 0x28
-	IPV6_RECVHOPLIMIT                 = 0x25
-	IPV6_RECVHOPOPTS                  = 0x27
-	IPV6_RECVPATHMTU                  = 0x2b
-	IPV6_RECVPKTINFO                  = 0x24
-	IPV6_RECVRTHDR                    = 0x26
-	IPV6_RECVTCLASS                   = 0x39
-	IPV6_RTHDR                        = 0x33
-	IPV6_RTHDRDSTOPTS                 = 0x23
-	IPV6_RTHDR_LOOSE                  = 0x0
-	IPV6_RTHDR_STRICT                 = 0x1
-	IPV6_RTHDR_TYPE_0                 = 0x0
-	IPV6_SOCKOPT_RESERVED1            = 0x3
-	IPV6_TCLASS                       = 0x3d
-	IPV6_UNICAST_HOPS                 = 0x4
-	IPV6_USE_MIN_MTU                  = 0x2a
-	IPV6_V6ONLY                       = 0x1b
-	IPV6_VERSION                      = 0x60
-	IPV6_VERSION_MASK                 = 0xf0
-	IP_ADD_MEMBERSHIP                 = 0xc
-	IP_ADD_SOURCE_MEMBERSHIP          = 0x46
-	IP_BINDANY                        = 0x18
-	IP_BLOCK_SOURCE                   = 0x48
-	IP_DEFAULT_MULTICAST_LOOP         = 0x1
-	IP_DEFAULT_MULTICAST_TTL          = 0x1
-	IP_DF                             = 0x4000
-	IP_DONTFRAG                       = 0x43
-	IP_DROP_MEMBERSHIP                = 0xd
-	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
-	IP_DUMMYNET3                      = 0x31
-	IP_DUMMYNET_CONFIGURE             = 0x3c
-	IP_DUMMYNET_DEL                   = 0x3d
-	IP_DUMMYNET_FLUSH                 = 0x3e
-	IP_DUMMYNET_GET                   = 0x40
-	IP_FAITH                          = 0x16
-	IP_FW3                            = 0x30
-	IP_FW_ADD                         = 0x32
-	IP_FW_DEL                         = 0x33
-	IP_FW_FLUSH                       = 0x34
-	IP_FW_GET                         = 0x36
-	IP_FW_NAT_CFG                     = 0x38
-	IP_FW_NAT_DEL                     = 0x39
-	IP_FW_NAT_GET_CONFIG              = 0x3a
-	IP_FW_NAT_GET_LOG                 = 0x3b
-	IP_FW_RESETLOG                    = 0x37
-	IP_FW_TABLE_ADD                   = 0x28
-	IP_FW_TABLE_DEL                   = 0x29
-	IP_FW_TABLE_FLUSH                 = 0x2a
-	IP_FW_TABLE_GETSIZE               = 0x2b
-	IP_FW_TABLE_LIST                  = 0x2c
-	IP_FW_ZERO                        = 0x35
-	IP_HDRINCL                        = 0x2
-	IP_IPSEC_POLICY                   = 0x15
-	IP_MAXPACKET                      = 0xffff
-	IP_MAX_GROUP_SRC_FILTER           = 0x200
-	IP_MAX_MEMBERSHIPS                = 0xfff
-	IP_MAX_SOCK_MUTE_FILTER           = 0x80
-	IP_MAX_SOCK_SRC_FILTER            = 0x80
-	IP_MAX_SOURCE_FILTER              = 0x400
-	IP_MF                             = 0x2000
-	IP_MINTTL                         = 0x42
-	IP_MIN_MEMBERSHIPS                = 0x1f
-	IP_MSFILTER                       = 0x4a
-	IP_MSS                            = 0x240
-	IP_MULTICAST_IF                   = 0x9
-	IP_MULTICAST_LOOP                 = 0xb
-	IP_MULTICAST_TTL                  = 0xa
-	IP_MULTICAST_VIF                  = 0xe
-	IP_OFFMASK                        = 0x1fff
-	IP_ONESBCAST                      = 0x17
-	IP_OPTIONS                        = 0x1
-	IP_PORTRANGE                      = 0x13
-	IP_PORTRANGE_DEFAULT              = 0x0
-	IP_PORTRANGE_HIGH                 = 0x1
-	IP_PORTRANGE_LOW                  = 0x2
-	IP_RECVDSTADDR                    = 0x7
-	IP_RECVIF                         = 0x14
-	IP_RECVOPTS                       = 0x5
-	IP_RECVRETOPTS                    = 0x6
-	IP_RECVTOS                        = 0x44
-	IP_RECVTTL                        = 0x41
-	IP_RETOPTS                        = 0x8
-	IP_RF                             = 0x8000
-	IP_RSVP_OFF                       = 0x10
-	IP_RSVP_ON                        = 0xf
-	IP_RSVP_VIF_OFF                   = 0x12
-	IP_RSVP_VIF_ON                    = 0x11
-	IP_SENDSRCADDR                    = 0x7
-	IP_TOS                            = 0x3
-	IP_TTL                            = 0x4
-	IP_UNBLOCK_SOURCE                 = 0x49
-	ISIG                              = 0x80
-	ISTRIP                            = 0x20
-	IXANY                             = 0x800
-	IXOFF                             = 0x400
-	IXON                              = 0x200
-	LOCK_EX                           = 0x2
-	LOCK_NB                           = 0x4
-	LOCK_SH                           = 0x1
-	LOCK_UN                           = 0x8
-	MADV_AUTOSYNC                     = 0x7
-	MADV_CORE                         = 0x9
-	MADV_DONTNEED                     = 0x4
-	MADV_FREE                         = 0x5
-	MADV_NOCORE                       = 0x8
-	MADV_NORMAL                       = 0x0
-	MADV_NOSYNC                       = 0x6
-	MADV_PROTECT                      = 0xa
-	MADV_RANDOM                       = 0x1
-	MADV_SEQUENTIAL                   = 0x2
-	MADV_WILLNEED                     = 0x3
-	MAP_ALIGNED_SUPER                 = 0x1000000
-	MAP_ALIGNMENT_MASK                = -0x1000000
-	MAP_ALIGNMENT_SHIFT               = 0x18
-	MAP_ANON                          = 0x1000
-	MAP_ANONYMOUS                     = 0x1000
-	MAP_COPY                          = 0x2
-	MAP_EXCL                          = 0x4000
-	MAP_FILE                          = 0x0
-	MAP_FIXED                         = 0x10
-	MAP_HASSEMAPHORE                  = 0x200
-	MAP_NOCORE                        = 0x20000
-	MAP_NORESERVE                     = 0x40
-	MAP_NOSYNC                        = 0x800
-	MAP_PREFAULT_READ                 = 0x40000
-	MAP_PRIVATE                       = 0x2
-	MAP_RENAME                        = 0x20
-	MAP_RESERVED0080                  = 0x80
-	MAP_RESERVED0100                  = 0x100
-	MAP_SHARED                        = 0x1
-	MAP_STACK                         = 0x400
-	MCL_CURRENT                       = 0x1
-	MCL_FUTURE                        = 0x2
-	MSG_CMSG_CLOEXEC                  = 0x40000
-	MSG_COMPAT                        = 0x8000
-	MSG_CTRUNC                        = 0x20
-	MSG_DONTROUTE                     = 0x4
-	MSG_DONTWAIT                      = 0x80
-	MSG_EOF                           = 0x100
-	MSG_EOR                           = 0x8
-	MSG_NBIO                          = 0x4000
-	MSG_NOSIGNAL                      = 0x20000
-	MSG_NOTIFICATION                  = 0x2000
-	MSG_OOB                           = 0x1
-	MSG_PEEK                          = 0x2
-	MSG_TRUNC                         = 0x10
-	MSG_WAITALL                       = 0x40
-	MS_ASYNC                          = 0x1
-	MS_INVALIDATE                     = 0x2
-	MS_SYNC                           = 0x0
-	NAME_MAX                          = 0xff
-	NET_RT_DUMP                       = 0x1
-	NET_RT_FLAGS                      = 0x2
-	NET_RT_IFLIST                     = 0x3
-	NET_RT_IFLISTL                    = 0x5
-	NET_RT_IFMALIST                   = 0x4
-	NET_RT_MAXID                      = 0x6
-	NOFLSH                            = 0x80000000
-	NOTE_ATTRIB                       = 0x8
-	NOTE_CHILD                        = 0x4
-	NOTE_DELETE                       = 0x1
-	NOTE_EXEC                         = 0x20000000
-	NOTE_EXIT                         = 0x80000000
-	NOTE_EXTEND                       = 0x4
-	NOTE_FFAND                        = 0x40000000
-	NOTE_FFCOPY                       = 0xc0000000
-	NOTE_FFCTRLMASK                   = 0xc0000000
-	NOTE_FFLAGSMASK                   = 0xffffff
-	NOTE_FFNOP                        = 0x0
-	NOTE_FFOR                         = 0x80000000
-	NOTE_FORK                         = 0x40000000
-	NOTE_LINK                         = 0x10
-	NOTE_LOWAT                        = 0x1
-	NOTE_PCTRLMASK                    = 0xf0000000
-	NOTE_PDATAMASK                    = 0xfffff
-	NOTE_RENAME                       = 0x20
-	NOTE_REVOKE                       = 0x40
-	NOTE_TRACK                        = 0x1
-	NOTE_TRACKERR                     = 0x2
-	NOTE_TRIGGER                      = 0x1000000
-	NOTE_WRITE                        = 0x2
-	OCRNL                             = 0x10
-	ONLCR                             = 0x2
-	ONLRET                            = 0x40
-	ONOCR                             = 0x20
-	ONOEOT                            = 0x8
-	OPOST                             = 0x1
-	O_ACCMODE                         = 0x3
-	O_APPEND                          = 0x8
-	O_ASYNC                           = 0x40
-	O_CLOEXEC                         = 0x100000
-	O_CREAT                           = 0x200
-	O_DIRECT                          = 0x10000
-	O_DIRECTORY                       = 0x20000
-	O_EXCL                            = 0x800
-	O_EXEC                            = 0x40000
-	O_EXLOCK                          = 0x20
-	O_FSYNC                           = 0x80
-	O_NDELAY                          = 0x4
-	O_NOCTTY                          = 0x8000
-	O_NOFOLLOW                        = 0x100
-	O_NONBLOCK                        = 0x4
-	O_RDONLY                          = 0x0
-	O_RDWR                            = 0x2
-	O_SHLOCK                          = 0x10
-	O_SYNC                            = 0x80
-	O_TRUNC                           = 0x400
-	O_TTY_INIT                        = 0x80000
-	O_WRONLY                          = 0x1
-	PARENB                            = 0x1000
-	PARMRK                            = 0x8
-	PARODD                            = 0x2000
-	PENDIN                            = 0x20000000
-	PRIO_PGRP                         = 0x1
-	PRIO_PROCESS                      = 0x0
-	PRIO_USER                         = 0x2
-	PROT_EXEC                         = 0x4
-	PROT_NONE                         = 0x0
-	PROT_READ                         = 0x1
-	PROT_WRITE                        = 0x2
-	RLIMIT_AS                         = 0xa
-	RLIMIT_CORE                       = 0x4
-	RLIMIT_CPU                        = 0x0
-	RLIMIT_DATA                       = 0x2
-	RLIMIT_FSIZE                      = 0x1
-	RLIMIT_NOFILE                     = 0x8
-	RLIMIT_STACK                      = 0x3
-	RLIM_INFINITY                     = 0x7fffffffffffffff
-	RTAX_AUTHOR                       = 0x6
-	RTAX_BRD                          = 0x7
-	RTAX_DST                          = 0x0
-	RTAX_GATEWAY                      = 0x1
-	RTAX_GENMASK                      = 0x3
-	RTAX_IFA                          = 0x5
-	RTAX_IFP                          = 0x4
-	RTAX_MAX                          = 0x8
-	RTAX_NETMASK                      = 0x2
-	RTA_AUTHOR                        = 0x40
-	RTA_BRD                           = 0x80
-	RTA_DST                           = 0x1
-	RTA_GATEWAY                       = 0x2
-	RTA_GENMASK                       = 0x8
-	RTA_IFA                           = 0x20
-	RTA_IFP                           = 0x10
-	RTA_NETMASK                       = 0x4
-	RTF_BLACKHOLE                     = 0x1000
-	RTF_BROADCAST                     = 0x400000
-	RTF_DONE                          = 0x40
-	RTF_DYNAMIC                       = 0x10
-	RTF_FMASK                         = 0x1004d808
-	RTF_GATEWAY                       = 0x2
-	RTF_GWFLAG_COMPAT                 = 0x80000000
-	RTF_HOST                          = 0x4
-	RTF_LLDATA                        = 0x400
-	RTF_LLINFO                        = 0x400
-	RTF_LOCAL                         = 0x200000
-	RTF_MODIFIED                      = 0x20
-	RTF_MULTICAST                     = 0x800000
-	RTF_PINNED                        = 0x100000
-	RTF_PRCLONING                     = 0x10000
-	RTF_PROTO1                        = 0x8000
-	RTF_PROTO2                        = 0x4000
-	RTF_PROTO3                        = 0x40000
-	RTF_REJECT                        = 0x8
-	RTF_RNH_LOCKED                    = 0x40000000
-	RTF_STATIC                        = 0x800
-	RTF_STICKY                        = 0x10000000
-	RTF_UP                            = 0x1
-	RTF_XRESOLVE                      = 0x200
-	RTM_ADD                           = 0x1
-	RTM_CHANGE                        = 0x3
-	RTM_DELADDR                       = 0xd
-	RTM_DELETE                        = 0x2
-	RTM_DELMADDR                      = 0x10
-	RTM_GET                           = 0x4
-	RTM_IEEE80211                     = 0x12
-	RTM_IFANNOUNCE                    = 0x11
-	RTM_IFINFO                        = 0xe
-	RTM_LOCK                          = 0x8
-	RTM_LOSING                        = 0x5
-	RTM_MISS                          = 0x7
-	RTM_NEWADDR                       = 0xc
-	RTM_NEWMADDR                      = 0xf
-	RTM_OLDADD                        = 0x9
-	RTM_OLDDEL                        = 0xa
-	RTM_REDIRECT                      = 0x6
-	RTM_RESOLVE                       = 0xb
-	RTM_RTTUNIT                       = 0xf4240
-	RTM_VERSION                       = 0x5
-	RTV_EXPIRE                        = 0x4
-	RTV_HOPCOUNT                      = 0x2
-	RTV_MTU                           = 0x1
-	RTV_RPIPE                         = 0x8
-	RTV_RTT                           = 0x40
-	RTV_RTTVAR                        = 0x80
-	RTV_SPIPE                         = 0x10
-	RTV_SSTHRESH                      = 0x20
-	RTV_WEIGHT                        = 0x100
-	RT_ALL_FIBS                       = -0x1
-	RT_CACHING_CONTEXT                = 0x1
-	RT_DEFAULT_FIB                    = 0x0
-	RT_NORTREF                        = 0x2
-	RUSAGE_CHILDREN                   = -0x1
-	RUSAGE_SELF                       = 0x0
-	RUSAGE_THREAD                     = 0x1
-	SCM_BINTIME                       = 0x4
-	SCM_CREDS                         = 0x3
-	SCM_RIGHTS                        = 0x1
-	SCM_TIMESTAMP                     = 0x2
-	SHUT_RD                           = 0x0
-	SHUT_RDWR                         = 0x2
-	SHUT_WR                           = 0x1
-	SIOCADDMULTI                      = 0x80206931
-	SIOCADDRT                         = 0x8030720a
-	SIOCAIFADDR                       = 0x8040691a
-	SIOCAIFGROUP                      = 0x80246987
-	SIOCALIFADDR                      = 0x8118691b
-	SIOCATMARK                        = 0x40047307
-	SIOCDELMULTI                      = 0x80206932
-	SIOCDELRT                         = 0x8030720b
-	SIOCDIFADDR                       = 0x80206919
-	SIOCDIFGROUP                      = 0x80246989
-	SIOCDIFPHYADDR                    = 0x80206949
-	SIOCDLIFADDR                      = 0x8118691d
-	SIOCGDRVSPEC                      = 0xc01c697b
-	SIOCGETSGCNT                      = 0xc0147210
-	SIOCGETVIFCNT                     = 0xc014720f
-	SIOCGHIWAT                        = 0x40047301
-	SIOCGIFADDR                       = 0xc0206921
-	SIOCGIFBRDADDR                    = 0xc0206923
-	SIOCGIFCAP                        = 0xc020691f
-	SIOCGIFCONF                       = 0xc0086924
-	SIOCGIFDESCR                      = 0xc020692a
-	SIOCGIFDSTADDR                    = 0xc0206922
-	SIOCGIFFIB                        = 0xc020695c
-	SIOCGIFFLAGS                      = 0xc0206911
-	SIOCGIFGENERIC                    = 0xc020693a
-	SIOCGIFGMEMB                      = 0xc024698a
-	SIOCGIFGROUP                      = 0xc0246988
-	SIOCGIFINDEX                      = 0xc0206920
-	SIOCGIFMAC                        = 0xc0206926
-	SIOCGIFMEDIA                      = 0xc0286938
-	SIOCGIFMETRIC                     = 0xc0206917
-	SIOCGIFMTU                        = 0xc0206933
-	SIOCGIFNETMASK                    = 0xc0206925
-	SIOCGIFPDSTADDR                   = 0xc0206948
-	SIOCGIFPHYS                       = 0xc0206935
-	SIOCGIFPSRCADDR                   = 0xc0206947
-	SIOCGIFSTATUS                     = 0xc331693b
-	SIOCGLIFADDR                      = 0xc118691c
-	SIOCGLIFPHYADDR                   = 0xc118694b
-	SIOCGLOWAT                        = 0x40047303
-	SIOCGPGRP                         = 0x40047309
-	SIOCGPRIVATE_0                    = 0xc0206950
-	SIOCGPRIVATE_1                    = 0xc0206951
-	SIOCIFCREATE                      = 0xc020697a
-	SIOCIFCREATE2                     = 0xc020697c
-	SIOCIFDESTROY                     = 0x80206979
-	SIOCIFGCLONERS                    = 0xc00c6978
-	SIOCSDRVSPEC                      = 0x801c697b
-	SIOCSHIWAT                        = 0x80047300
-	SIOCSIFADDR                       = 0x8020690c
-	SIOCSIFBRDADDR                    = 0x80206913
-	SIOCSIFCAP                        = 0x8020691e
-	SIOCSIFDESCR                      = 0x80206929
-	SIOCSIFDSTADDR                    = 0x8020690e
-	SIOCSIFFIB                        = 0x8020695d
-	SIOCSIFFLAGS                      = 0x80206910
-	SIOCSIFGENERIC                    = 0x80206939
-	SIOCSIFLLADDR                     = 0x8020693c
-	SIOCSIFMAC                        = 0x80206927
-	SIOCSIFMEDIA                      = 0xc0206937
-	SIOCSIFMETRIC                     = 0x80206918
-	SIOCSIFMTU                        = 0x80206934
-	SIOCSIFNAME                       = 0x80206928
-	SIOCSIFNETMASK                    = 0x80206916
-	SIOCSIFPHYADDR                    = 0x80406946
-	SIOCSIFPHYS                       = 0x80206936
-	SIOCSIFRVNET                      = 0xc020695b
-	SIOCSIFVNET                       = 0xc020695a
-	SIOCSLIFPHYADDR                   = 0x8118694a
-	SIOCSLOWAT                        = 0x80047302
-	SIOCSPGRP                         = 0x80047308
-	SOCK_CLOEXEC                      = 0x10000000
-	SOCK_DGRAM                        = 0x2
-	SOCK_MAXADDRLEN                   = 0xff
-	SOCK_NONBLOCK                     = 0x20000000
-	SOCK_RAW                          = 0x3
-	SOCK_RDM                          = 0x4
-	SOCK_SEQPACKET                    = 0x5
-	SOCK_STREAM                       = 0x1
-	SOL_SOCKET                        = 0xffff
-	SOMAXCONN                         = 0x80
-	SO_ACCEPTCONN                     = 0x2
-	SO_ACCEPTFILTER                   = 0x1000
-	SO_BINTIME                        = 0x2000
-	SO_BROADCAST                      = 0x20
-	SO_DEBUG                          = 0x1
-	SO_DONTROUTE                      = 0x10
-	SO_ERROR                          = 0x1007
-	SO_KEEPALIVE                      = 0x8
-	SO_LABEL                          = 0x1009
-	SO_LINGER                         = 0x80
-	SO_LISTENINCQLEN                  = 0x1013
-	SO_LISTENQLEN                     = 0x1012
-	SO_LISTENQLIMIT                   = 0x1011
-	SO_NOSIGPIPE                      = 0x800
-	SO_NO_DDP                         = 0x8000
-	SO_NO_OFFLOAD                     = 0x4000
-	SO_OOBINLINE                      = 0x100
-	SO_PEERLABEL                      = 0x1010
-	SO_PROTOCOL                       = 0x1016
-	SO_PROTOTYPE                      = 0x1016
-	SO_RCVBUF                         = 0x1002
-	SO_RCVLOWAT                       = 0x1004
-	SO_RCVTIMEO                       = 0x1006
-	SO_REUSEADDR                      = 0x4
-	SO_REUSEPORT                      = 0x200
-	SO_SETFIB                         = 0x1014
-	SO_SNDBUF                         = 0x1001
-	SO_SNDLOWAT                       = 0x1003
-	SO_SNDTIMEO                       = 0x1005
-	SO_TIMESTAMP                      = 0x400
-	SO_TYPE                           = 0x1008
-	SO_USELOOPBACK                    = 0x40
-	SO_USER_COOKIE                    = 0x1015
-	SO_VENDOR                         = 0x80000000
-	TCIFLUSH                          = 0x1
-	TCIOFLUSH                         = 0x3
-	TCOFLUSH                          = 0x2
-	TCP_CA_NAME_MAX                   = 0x10
-	TCP_CONGESTION                    = 0x40
-	TCP_INFO                          = 0x20
-	TCP_KEEPCNT                       = 0x400
-	TCP_KEEPIDLE                      = 0x100
-	TCP_KEEPINIT                      = 0x80
-	TCP_KEEPINTVL                     = 0x200
-	TCP_MAXBURST                      = 0x4
-	TCP_MAXHLEN                       = 0x3c
-	TCP_MAXOLEN                       = 0x28
-	TCP_MAXSEG                        = 0x2
-	TCP_MAXWIN                        = 0xffff
-	TCP_MAX_SACK                      = 0x4
-	TCP_MAX_WINSHIFT                  = 0xe
-	TCP_MD5SIG                        = 0x10
-	TCP_MINMSS                        = 0xd8
-	TCP_MSS                           = 0x218
-	TCP_NODELAY                       = 0x1
-	TCP_NOOPT                         = 0x8
-	TCP_NOPUSH                        = 0x4
-	TCP_VENDOR                        = 0x80000000
-	TCSAFLUSH                         = 0x2
-	TIOCCBRK                          = 0x2000747a
-	TIOCCDTR                          = 0x20007478
-	TIOCCONS                          = 0x80047462
-	TIOCDRAIN                         = 0x2000745e
-	TIOCEXCL                          = 0x2000740d
-	TIOCEXT                           = 0x80047460
-	TIOCFLUSH                         = 0x80047410
-	TIOCGDRAINWAIT                    = 0x40047456
-	TIOCGETA                          = 0x402c7413
-	TIOCGETD                          = 0x4004741a
-	TIOCGPGRP                         = 0x40047477
-	TIOCGPTN                          = 0x4004740f
-	TIOCGSID                          = 0x40047463
-	TIOCGWINSZ                        = 0x40087468
-	TIOCMBIC                          = 0x8004746b
-	TIOCMBIS                          = 0x8004746c
-	TIOCMGDTRWAIT                     = 0x4004745a
-	TIOCMGET                          = 0x4004746a
-	TIOCMSDTRWAIT                     = 0x8004745b
-	TIOCMSET                          = 0x8004746d
-	TIOCM_CAR                         = 0x40
-	TIOCM_CD                          = 0x40
-	TIOCM_CTS                         = 0x20
-	TIOCM_DCD                         = 0x40
-	TIOCM_DSR                         = 0x100
-	TIOCM_DTR                         = 0x2
-	TIOCM_LE                          = 0x1
-	TIOCM_RI                          = 0x80
-	TIOCM_RNG                         = 0x80
-	TIOCM_RTS                         = 0x4
-	TIOCM_SR                          = 0x10
-	TIOCM_ST                          = 0x8
-	TIOCNOTTY                         = 0x20007471
-	TIOCNXCL                          = 0x2000740e
-	TIOCOUTQ                          = 0x40047473
-	TIOCPKT                           = 0x80047470
-	TIOCPKT_DATA                      = 0x0
-	TIOCPKT_DOSTOP                    = 0x20
-	TIOCPKT_FLUSHREAD                 = 0x1
-	TIOCPKT_FLUSHWRITE                = 0x2
-	TIOCPKT_IOCTL                     = 0x40
-	TIOCPKT_NOSTOP                    = 0x10
-	TIOCPKT_START                     = 0x8
-	TIOCPKT_STOP                      = 0x4
-	TIOCPTMASTER                      = 0x2000741c
-	TIOCSBRK                          = 0x2000747b
-	TIOCSCTTY                         = 0x20007461
-	TIOCSDRAINWAIT                    = 0x80047457
-	TIOCSDTR                          = 0x20007479
-	TIOCSETA                          = 0x802c7414
-	TIOCSETAF                         = 0x802c7416
-	TIOCSETAW                         = 0x802c7415
-	TIOCSETD                          = 0x8004741b
-	TIOCSIG                           = 0x2004745f
-	TIOCSPGRP                         = 0x80047476
-	TIOCSTART                         = 0x2000746e
-	TIOCSTAT                          = 0x20007465
-	TIOCSTI                           = 0x80017472
-	TIOCSTOP                          = 0x2000746f
-	TIOCSWINSZ                        = 0x80087467
-	TIOCTIMESTAMP                     = 0x40087459
-	TIOCUCNTL                         = 0x80047466
-	TOSTOP                            = 0x400000
-	VDISCARD                          = 0xf
-	VDSUSP                            = 0xb
-	VEOF                              = 0x0
-	VEOL                              = 0x1
-	VEOL2                             = 0x2
-	VERASE                            = 0x3
-	VERASE2                           = 0x7
-	VINTR                             = 0x8
-	VKILL                             = 0x5
-	VLNEXT                            = 0xe
-	VMIN                              = 0x10
-	VQUIT                             = 0x9
-	VREPRINT                          = 0x6
-	VSTART                            = 0xc
-	VSTATUS                           = 0x12
-	VSTOP                             = 0xd
-	VSUSP                             = 0xa
-	VTIME                             = 0x11
-	VWERASE                           = 0x4
-	WCONTINUED                        = 0x4
-	WCOREFLAG                         = 0x80
-	WEXITED                           = 0x10
-	WLINUXCLONE                       = 0x80000000
-	WNOHANG                           = 0x1
-	WNOWAIT                           = 0x8
-	WSTOPPED                          = 0x2
-	WTRAPPED                          = 0x20
-	WUNTRACED                         = 0x2
+	AF_APPLETALK                   = 0x10
+	AF_ARP                         = 0x23
+	AF_ATM                         = 0x1e
+	AF_BLUETOOTH                   = 0x24
+	AF_CCITT                       = 0xa
+	AF_CHAOS                       = 0x5
+	AF_CNT                         = 0x15
+	AF_COIP                        = 0x14
+	AF_DATAKIT                     = 0x9
+	AF_DECnet                      = 0xc
+	AF_DLI                         = 0xd
+	AF_E164                        = 0x1a
+	AF_ECMA                        = 0x8
+	AF_HYLINK                      = 0xf
+	AF_IEEE80211                   = 0x25
+	AF_IMPLINK                     = 0x3
+	AF_INET                        = 0x2
+	AF_INET6                       = 0x1c
+	AF_INET6_SDP                   = 0x2a
+	AF_INET_SDP                    = 0x28
+	AF_IPX                         = 0x17
+	AF_ISDN                        = 0x1a
+	AF_ISO                         = 0x7
+	AF_LAT                         = 0xe
+	AF_LINK                        = 0x12
+	AF_LOCAL                       = 0x1
+	AF_MAX                         = 0x2a
+	AF_NATM                        = 0x1d
+	AF_NETBIOS                     = 0x6
+	AF_NETGRAPH                    = 0x20
+	AF_OSI                         = 0x7
+	AF_PUP                         = 0x4
+	AF_ROUTE                       = 0x11
+	AF_SCLUSTER                    = 0x22
+	AF_SIP                         = 0x18
+	AF_SLOW                        = 0x21
+	AF_SNA                         = 0xb
+	AF_UNIX                        = 0x1
+	AF_UNSPEC                      = 0x0
+	AF_VENDOR00                    = 0x27
+	AF_VENDOR01                    = 0x29
+	AF_VENDOR02                    = 0x2b
+	AF_VENDOR03                    = 0x2d
+	AF_VENDOR04                    = 0x2f
+	AF_VENDOR05                    = 0x31
+	AF_VENDOR06                    = 0x33
+	AF_VENDOR07                    = 0x35
+	AF_VENDOR08                    = 0x37
+	AF_VENDOR09                    = 0x39
+	AF_VENDOR10                    = 0x3b
+	AF_VENDOR11                    = 0x3d
+	AF_VENDOR12                    = 0x3f
+	AF_VENDOR13                    = 0x41
+	AF_VENDOR14                    = 0x43
+	AF_VENDOR15                    = 0x45
+	AF_VENDOR16                    = 0x47
+	AF_VENDOR17                    = 0x49
+	AF_VENDOR18                    = 0x4b
+	AF_VENDOR19                    = 0x4d
+	AF_VENDOR20                    = 0x4f
+	AF_VENDOR21                    = 0x51
+	AF_VENDOR22                    = 0x53
+	AF_VENDOR23                    = 0x55
+	AF_VENDOR24                    = 0x57
+	AF_VENDOR25                    = 0x59
+	AF_VENDOR26                    = 0x5b
+	AF_VENDOR27                    = 0x5d
+	AF_VENDOR28                    = 0x5f
+	AF_VENDOR29                    = 0x61
+	AF_VENDOR30                    = 0x63
+	AF_VENDOR31                    = 0x65
+	AF_VENDOR32                    = 0x67
+	AF_VENDOR33                    = 0x69
+	AF_VENDOR34                    = 0x6b
+	AF_VENDOR35                    = 0x6d
+	AF_VENDOR36                    = 0x6f
+	AF_VENDOR37                    = 0x71
+	AF_VENDOR38                    = 0x73
+	AF_VENDOR39                    = 0x75
+	AF_VENDOR40                    = 0x77
+	AF_VENDOR41                    = 0x79
+	AF_VENDOR42                    = 0x7b
+	AF_VENDOR43                    = 0x7d
+	AF_VENDOR44                    = 0x7f
+	AF_VENDOR45                    = 0x81
+	AF_VENDOR46                    = 0x83
+	AF_VENDOR47                    = 0x85
+	ALTWERASE                      = 0x200
+	B0                             = 0x0
+	B110                           = 0x6e
+	B115200                        = 0x1c200
+	B1200                          = 0x4b0
+	B134                           = 0x86
+	B14400                         = 0x3840
+	B150                           = 0x96
+	B1800                          = 0x708
+	B19200                         = 0x4b00
+	B200                           = 0xc8
+	B230400                        = 0x38400
+	B2400                          = 0x960
+	B28800                         = 0x7080
+	B300                           = 0x12c
+	B38400                         = 0x9600
+	B460800                        = 0x70800
+	B4800                          = 0x12c0
+	B50                            = 0x32
+	B57600                         = 0xe100
+	B600                           = 0x258
+	B7200                          = 0x1c20
+	B75                            = 0x4b
+	B76800                         = 0x12c00
+	B921600                        = 0xe1000
+	B9600                          = 0x2580
+	BIOCFEEDBACK                   = 0x8004427c
+	BIOCFLUSH                      = 0x20004268
+	BIOCGBLEN                      = 0x40044266
+	BIOCGDIRECTION                 = 0x40044276
+	BIOCGDLT                       = 0x4004426a
+	BIOCGDLTLIST                   = 0xc0084279
+	BIOCGETBUFMODE                 = 0x4004427d
+	BIOCGETIF                      = 0x4020426b
+	BIOCGETZMAX                    = 0x4004427f
+	BIOCGHDRCMPLT                  = 0x40044274
+	BIOCGRSIG                      = 0x40044272
+	BIOCGRTIMEOUT                  = 0x4008426e
+	BIOCGSEESENT                   = 0x40044276
+	BIOCGSTATS                     = 0x4008426f
+	BIOCGTSTAMP                    = 0x40044283
+	BIOCIMMEDIATE                  = 0x80044270
+	BIOCLOCK                       = 0x2000427a
+	BIOCPROMISC                    = 0x20004269
+	BIOCROTZBUF                    = 0x400c4280
+	BIOCSBLEN                      = 0xc0044266
+	BIOCSDIRECTION                 = 0x80044277
+	BIOCSDLT                       = 0x80044278
+	BIOCSETBUFMODE                 = 0x8004427e
+	BIOCSETF                       = 0x80084267
+	BIOCSETFNR                     = 0x80084282
+	BIOCSETIF                      = 0x8020426c
+	BIOCSETWF                      = 0x8008427b
+	BIOCSETZBUF                    = 0x800c4281
+	BIOCSHDRCMPLT                  = 0x80044275
+	BIOCSRSIG                      = 0x80044273
+	BIOCSRTIMEOUT                  = 0x8008426d
+	BIOCSSEESENT                   = 0x80044277
+	BIOCSTSTAMP                    = 0x80044284
+	BIOCVERSION                    = 0x40044271
+	BPF_A                          = 0x10
+	BPF_ABS                        = 0x20
+	BPF_ADD                        = 0x0
+	BPF_ALIGNMENT                  = 0x4
+	BPF_ALU                        = 0x4
+	BPF_AND                        = 0x50
+	BPF_B                          = 0x10
+	BPF_BUFMODE_BUFFER             = 0x1
+	BPF_BUFMODE_ZBUF               = 0x2
+	BPF_DIV                        = 0x30
+	BPF_H                          = 0x8
+	BPF_IMM                        = 0x0
+	BPF_IND                        = 0x40
+	BPF_JA                         = 0x0
+	BPF_JEQ                        = 0x10
+	BPF_JGE                        = 0x30
+	BPF_JGT                        = 0x20
+	BPF_JMP                        = 0x5
+	BPF_JSET                       = 0x40
+	BPF_K                          = 0x0
+	BPF_LD                         = 0x0
+	BPF_LDX                        = 0x1
+	BPF_LEN                        = 0x80
+	BPF_LSH                        = 0x60
+	BPF_MAJOR_VERSION              = 0x1
+	BPF_MAXBUFSIZE                 = 0x80000
+	BPF_MAXINSNS                   = 0x200
+	BPF_MEM                        = 0x60
+	BPF_MEMWORDS                   = 0x10
+	BPF_MINBUFSIZE                 = 0x20
+	BPF_MINOR_VERSION              = 0x1
+	BPF_MISC                       = 0x7
+	BPF_MOD                        = 0x90
+	BPF_MSH                        = 0xa0
+	BPF_MUL                        = 0x20
+	BPF_NEG                        = 0x80
+	BPF_OR                         = 0x40
+	BPF_RELEASE                    = 0x30bb6
+	BPF_RET                        = 0x6
+	BPF_RSH                        = 0x70
+	BPF_ST                         = 0x2
+	BPF_STX                        = 0x3
+	BPF_SUB                        = 0x10
+	BPF_TAX                        = 0x0
+	BPF_TXA                        = 0x80
+	BPF_T_BINTIME                  = 0x2
+	BPF_T_BINTIME_FAST             = 0x102
+	BPF_T_BINTIME_MONOTONIC        = 0x202
+	BPF_T_BINTIME_MONOTONIC_FAST   = 0x302
+	BPF_T_FAST                     = 0x100
+	BPF_T_FLAG_MASK                = 0x300
+	BPF_T_FORMAT_MASK              = 0x3
+	BPF_T_MICROTIME                = 0x0
+	BPF_T_MICROTIME_FAST           = 0x100
+	BPF_T_MICROTIME_MONOTONIC      = 0x200
+	BPF_T_MICROTIME_MONOTONIC_FAST = 0x300
+	BPF_T_MONOTONIC                = 0x200
+	BPF_T_MONOTONIC_FAST           = 0x300
+	BPF_T_NANOTIME                 = 0x1
+	BPF_T_NANOTIME_FAST            = 0x101
+	BPF_T_NANOTIME_MONOTONIC       = 0x201
+	BPF_T_NANOTIME_MONOTONIC_FAST  = 0x301
+	BPF_T_NONE                     = 0x3
+	BPF_T_NORMAL                   = 0x0
+	BPF_W                          = 0x0
+	BPF_X                          = 0x8
+	BPF_XOR                        = 0xa0
+	BRKINT                         = 0x2
+	CAP_ACCEPT                     = 0x200000020000000
+	CAP_ACL_CHECK                  = 0x400000000010000
+	CAP_ACL_DELETE                 = 0x400000000020000
+	CAP_ACL_GET                    = 0x400000000040000
+	CAP_ACL_SET                    = 0x400000000080000
+	CAP_ALL0                       = 0x20007ffffffffff
+	CAP_ALL1                       = 0x4000000001fffff
+	CAP_BIND                       = 0x200000040000000
+	CAP_BINDAT                     = 0x200008000000400
+	CAP_CHFLAGSAT                  = 0x200000000001400
+	CAP_CONNECT                    = 0x200000080000000
+	CAP_CONNECTAT                  = 0x200010000000400
+	CAP_CREATE                     = 0x200000000000040
+	CAP_EVENT                      = 0x400000000000020
+	CAP_EXTATTR_DELETE             = 0x400000000001000
+	CAP_EXTATTR_GET                = 0x400000000002000
+	CAP_EXTATTR_LIST               = 0x400000000004000
+	CAP_EXTATTR_SET                = 0x400000000008000
+	CAP_FCHDIR                     = 0x200000000000800
+	CAP_FCHFLAGS                   = 0x200000000001000
+	CAP_FCHMOD                     = 0x200000000002000
+	CAP_FCHMODAT                   = 0x200000000002400
+	CAP_FCHOWN                     = 0x200000000004000
+	CAP_FCHOWNAT                   = 0x200000000004400
+	CAP_FCNTL                      = 0x200000000008000
+	CAP_FCNTL_ALL                  = 0x78
+	CAP_FCNTL_GETFL                = 0x8
+	CAP_FCNTL_GETOWN               = 0x20
+	CAP_FCNTL_SETFL                = 0x10
+	CAP_FCNTL_SETOWN               = 0x40
+	CAP_FEXECVE                    = 0x200000000000080
+	CAP_FLOCK                      = 0x200000000010000
+	CAP_FPATHCONF                  = 0x200000000020000
+	CAP_FSCK                       = 0x200000000040000
+	CAP_FSTAT                      = 0x200000000080000
+	CAP_FSTATAT                    = 0x200000000080400
+	CAP_FSTATFS                    = 0x200000000100000
+	CAP_FSYNC                      = 0x200000000000100
+	CAP_FTRUNCATE                  = 0x200000000000200
+	CAP_FUTIMES                    = 0x200000000200000
+	CAP_FUTIMESAT                  = 0x200000000200400
+	CAP_GETPEERNAME                = 0x200000100000000
+	CAP_GETSOCKNAME                = 0x200000200000000
+	CAP_GETSOCKOPT                 = 0x200000400000000
+	CAP_IOCTL                      = 0x400000000000080
+	CAP_IOCTLS_ALL                 = 0x7fffffff
+	CAP_KQUEUE                     = 0x400000000100040
+	CAP_KQUEUE_CHANGE              = 0x400000000100000
+	CAP_KQUEUE_EVENT               = 0x400000000000040
+	CAP_LINKAT_SOURCE              = 0x200020000000400
+	CAP_LINKAT_TARGET              = 0x200000000400400
+	CAP_LISTEN                     = 0x200000800000000
+	CAP_LOOKUP                     = 0x200000000000400
+	CAP_MAC_GET                    = 0x400000000000001
+	CAP_MAC_SET                    = 0x400000000000002
+	CAP_MKDIRAT                    = 0x200000000800400
+	CAP_MKFIFOAT                   = 0x200000001000400
+	CAP_MKNODAT                    = 0x200000002000400
+	CAP_MMAP                       = 0x200000000000010
+	CAP_MMAP_R                     = 0x20000000000001d
+	CAP_MMAP_RW                    = 0x20000000000001f
+	CAP_MMAP_RWX                   = 0x20000000000003f
+	CAP_MMAP_RX                    = 0x20000000000003d
+	CAP_MMAP_W                     = 0x20000000000001e
+	CAP_MMAP_WX                    = 0x20000000000003e
+	CAP_MMAP_X                     = 0x20000000000003c
+	CAP_PDGETPID                   = 0x400000000000200
+	CAP_PDKILL                     = 0x400000000000800
+	CAP_PDWAIT                     = 0x400000000000400
+	CAP_PEELOFF                    = 0x200001000000000
+	CAP_POLL_EVENT                 = 0x400000000000020
+	CAP_PREAD                      = 0x20000000000000d
+	CAP_PWRITE                     = 0x20000000000000e
+	CAP_READ                       = 0x200000000000001
+	CAP_RECV                       = 0x200000000000001
+	CAP_RENAMEAT_SOURCE            = 0x200000004000400
+	CAP_RENAMEAT_TARGET            = 0x200040000000400
+	CAP_RIGHTS_VERSION             = 0x0
+	CAP_RIGHTS_VERSION_00          = 0x0
+	CAP_SEEK                       = 0x20000000000000c
+	CAP_SEEK_TELL                  = 0x200000000000004
+	CAP_SEM_GETVALUE               = 0x400000000000004
+	CAP_SEM_POST                   = 0x400000000000008
+	CAP_SEM_WAIT                   = 0x400000000000010
+	CAP_SEND                       = 0x200000000000002
+	CAP_SETSOCKOPT                 = 0x200002000000000
+	CAP_SHUTDOWN                   = 0x200004000000000
+	CAP_SOCK_CLIENT                = 0x200007780000003
+	CAP_SOCK_SERVER                = 0x200007f60000003
+	CAP_SYMLINKAT                  = 0x200000008000400
+	CAP_TTYHOOK                    = 0x400000000000100
+	CAP_UNLINKAT                   = 0x200000010000400
+	CAP_UNUSED0_44                 = 0x200080000000000
+	CAP_UNUSED0_57                 = 0x300000000000000
+	CAP_UNUSED1_22                 = 0x400000000200000
+	CAP_UNUSED1_57                 = 0x500000000000000
+	CAP_WRITE                      = 0x200000000000002
+	CFLUSH                         = 0xf
+	CLOCAL                         = 0x8000
+	CLOCK_MONOTONIC                = 0x4
+	CLOCK_MONOTONIC_FAST           = 0xc
+	CLOCK_MONOTONIC_PRECISE        = 0xb
+	CLOCK_PROCESS_CPUTIME_ID       = 0xf
+	CLOCK_PROF                     = 0x2
+	CLOCK_REALTIME                 = 0x0
+	CLOCK_REALTIME_FAST            = 0xa
+	CLOCK_REALTIME_PRECISE         = 0x9
+	CLOCK_SECOND                   = 0xd
+	CLOCK_THREAD_CPUTIME_ID        = 0xe
+	CLOCK_UPTIME                   = 0x5
+	CLOCK_UPTIME_FAST              = 0x8
+	CLOCK_UPTIME_PRECISE           = 0x7
+	CLOCK_VIRTUAL                  = 0x1
+	CREAD                          = 0x800
+	CRTSCTS                        = 0x30000
+	CS5                            = 0x0
+	CS6                            = 0x100
+	CS7                            = 0x200
+	CS8                            = 0x300
+	CSIZE                          = 0x300
+	CSTART                         = 0x11
+	CSTATUS                        = 0x14
+	CSTOP                          = 0x13
+	CSTOPB                         = 0x400
+	CSUSP                          = 0x1a
+	CTL_MAXNAME                    = 0x18
+	CTL_NET                        = 0x4
+	DLT_A429                       = 0xb8
+	DLT_A653_ICM                   = 0xb9
+	DLT_AIRONET_HEADER             = 0x78
+	DLT_AOS                        = 0xde
+	DLT_APPLE_IP_OVER_IEEE1394     = 0x8a
+	DLT_ARCNET                     = 0x7
+	DLT_ARCNET_LINUX               = 0x81
+	DLT_ATM_CLIP                   = 0x13
+	DLT_ATM_RFC1483                = 0xb
+	DLT_AURORA                     = 0x7e
+	DLT_AX25                       = 0x3
+	DLT_AX25_KISS                  = 0xca
+	DLT_BACNET_MS_TP               = 0xa5
+	DLT_BLUETOOTH_BREDR_BB         = 0xff
+	DLT_BLUETOOTH_HCI_H4           = 0xbb
+	DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9
+	DLT_BLUETOOTH_LE_LL            = 0xfb
+	DLT_BLUETOOTH_LE_LL_WITH_PHDR  = 0x100
+	DLT_BLUETOOTH_LINUX_MONITOR    = 0xfe
+	DLT_CAN20B                     = 0xbe
+	DLT_CAN_SOCKETCAN              = 0xe3
+	DLT_CHAOS                      = 0x5
+	DLT_CHDLC                      = 0x68
+	DLT_CISCO_IOS                  = 0x76
+	DLT_C_HDLC                     = 0x68
+	DLT_C_HDLC_WITH_DIR            = 0xcd
+	DLT_DBUS                       = 0xe7
+	DLT_DECT                       = 0xdd
+	DLT_DOCSIS                     = 0x8f
+	DLT_DVB_CI                     = 0xeb
+	DLT_ECONET                     = 0x73
+	DLT_EN10MB                     = 0x1
+	DLT_EN3MB                      = 0x2
+	DLT_ENC                        = 0x6d
+	DLT_EPON                       = 0x103
+	DLT_ERF                        = 0xc5
+	DLT_ERF_ETH                    = 0xaf
+	DLT_ERF_POS                    = 0xb0
+	DLT_FC_2                       = 0xe0
+	DLT_FC_2_WITH_FRAME_DELIMS     = 0xe1
+	DLT_FDDI                       = 0xa
+	DLT_FLEXRAY                    = 0xd2
+	DLT_FRELAY                     = 0x6b
+	DLT_FRELAY_WITH_DIR            = 0xce
+	DLT_GCOM_SERIAL                = 0xad
+	DLT_GCOM_T1E1                  = 0xac
+	DLT_GPF_F                      = 0xab
+	DLT_GPF_T                      = 0xaa
+	DLT_GPRS_LLC                   = 0xa9
+	DLT_GSMTAP_ABIS                = 0xda
+	DLT_GSMTAP_UM                  = 0xd9
+	DLT_HHDLC                      = 0x79
+	DLT_IBM_SN                     = 0x92
+	DLT_IBM_SP                     = 0x91
+	DLT_IEEE802                    = 0x6
+	DLT_IEEE802_11                 = 0x69
+	DLT_IEEE802_11_RADIO           = 0x7f
+	DLT_IEEE802_11_RADIO_AVS       = 0xa3
+	DLT_IEEE802_15_4               = 0xc3
+	DLT_IEEE802_15_4_LINUX         = 0xbf
+	DLT_IEEE802_15_4_NOFCS         = 0xe6
+	DLT_IEEE802_15_4_NONASK_PHY    = 0xd7
+	DLT_IEEE802_16_MAC_CPS         = 0xbc
+	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
+	DLT_INFINIBAND                 = 0xf7
+	DLT_IPFILTER                   = 0x74
+	DLT_IPMB                       = 0xc7
+	DLT_IPMB_LINUX                 = 0xd1
+	DLT_IPMI_HPM_2                 = 0x104
+	DLT_IPNET                      = 0xe2
+	DLT_IPOIB                      = 0xf2
+	DLT_IPV4                       = 0xe4
+	DLT_IPV6                       = 0xe5
+	DLT_IP_OVER_FC                 = 0x7a
+	DLT_JUNIPER_ATM1               = 0x89
+	DLT_JUNIPER_ATM2               = 0x87
+	DLT_JUNIPER_ATM_CEMIC          = 0xee
+	DLT_JUNIPER_CHDLC              = 0xb5
+	DLT_JUNIPER_ES                 = 0x84
+	DLT_JUNIPER_ETHER              = 0xb2
+	DLT_JUNIPER_FIBRECHANNEL       = 0xea
+	DLT_JUNIPER_FRELAY             = 0xb4
+	DLT_JUNIPER_GGSN               = 0x85
+	DLT_JUNIPER_ISM                = 0xc2
+	DLT_JUNIPER_MFR                = 0x86
+	DLT_JUNIPER_MLFR               = 0x83
+	DLT_JUNIPER_MLPPP              = 0x82
+	DLT_JUNIPER_MONITOR            = 0xa4
+	DLT_JUNIPER_PIC_PEER           = 0xae
+	DLT_JUNIPER_PPP                = 0xb3
+	DLT_JUNIPER_PPPOE              = 0xa7
+	DLT_JUNIPER_PPPOE_ATM          = 0xa8
+	DLT_JUNIPER_SERVICES           = 0x88
+	DLT_JUNIPER_SRX_E2E            = 0xe9
+	DLT_JUNIPER_ST                 = 0xc8
+	DLT_JUNIPER_VP                 = 0xb7
+	DLT_JUNIPER_VS                 = 0xe8
+	DLT_LAPB_WITH_DIR              = 0xcf
+	DLT_LAPD                       = 0xcb
+	DLT_LIN                        = 0xd4
+	DLT_LINUX_EVDEV                = 0xd8
+	DLT_LINUX_IRDA                 = 0x90
+	DLT_LINUX_LAPD                 = 0xb1
+	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
+	DLT_LINUX_SLL                  = 0x71
+	DLT_LOOP                       = 0x6c
+	DLT_LTALK                      = 0x72
+	DLT_MATCHING_MAX               = 0x104
+	DLT_MATCHING_MIN               = 0x68
+	DLT_MFR                        = 0xb6
+	DLT_MOST                       = 0xd3
+	DLT_MPEG_2_TS                  = 0xf3
+	DLT_MPLS                       = 0xdb
+	DLT_MTP2                       = 0x8c
+	DLT_MTP2_WITH_PHDR             = 0x8b
+	DLT_MTP3                       = 0x8d
+	DLT_MUX27010                   = 0xec
+	DLT_NETANALYZER                = 0xf0
+	DLT_NETANALYZER_TRANSPARENT    = 0xf1
+	DLT_NETLINK                    = 0xfd
+	DLT_NFC_LLCP                   = 0xf5
+	DLT_NFLOG                      = 0xef
+	DLT_NG40                       = 0xf4
+	DLT_NULL                       = 0x0
+	DLT_PCI_EXP                    = 0x7d
+	DLT_PFLOG                      = 0x75
+	DLT_PFSYNC                     = 0x79
+	DLT_PKTAP                      = 0x102
+	DLT_PPI                        = 0xc0
+	DLT_PPP                        = 0x9
+	DLT_PPP_BSDOS                  = 0x10
+	DLT_PPP_ETHER                  = 0x33
+	DLT_PPP_PPPD                   = 0xa6
+	DLT_PPP_SERIAL                 = 0x32
+	DLT_PPP_WITH_DIR               = 0xcc
+	DLT_PPP_WITH_DIRECTION         = 0xa6
+	DLT_PRISM_HEADER               = 0x77
+	DLT_PROFIBUS_DL                = 0x101
+	DLT_PRONET                     = 0x4
+	DLT_RAIF1                      = 0xc6
+	DLT_RAW                        = 0xc
+	DLT_RIO                        = 0x7c
+	DLT_RTAC_SERIAL                = 0xfa
+	DLT_SCCP                       = 0x8e
+	DLT_SCTP                       = 0xf8
+	DLT_SITA                       = 0xc4
+	DLT_SLIP                       = 0x8
+	DLT_SLIP_BSDOS                 = 0xf
+	DLT_STANAG_5066_D_PDU          = 0xed
+	DLT_SUNATM                     = 0x7b
+	DLT_SYMANTEC_FIREWALL          = 0x63
+	DLT_TZSP                       = 0x80
+	DLT_USB                        = 0xba
+	DLT_USBPCAP                    = 0xf9
+	DLT_USB_LINUX                  = 0xbd
+	DLT_USB_LINUX_MMAPPED          = 0xdc
+	DLT_USER0                      = 0x93
+	DLT_USER1                      = 0x94
+	DLT_USER10                     = 0x9d
+	DLT_USER11                     = 0x9e
+	DLT_USER12                     = 0x9f
+	DLT_USER13                     = 0xa0
+	DLT_USER14                     = 0xa1
+	DLT_USER15                     = 0xa2
+	DLT_USER2                      = 0x95
+	DLT_USER3                      = 0x96
+	DLT_USER4                      = 0x97
+	DLT_USER5                      = 0x98
+	DLT_USER6                      = 0x99
+	DLT_USER7                      = 0x9a
+	DLT_USER8                      = 0x9b
+	DLT_USER9                      = 0x9c
+	DLT_WIHART                     = 0xdf
+	DLT_WIRESHARK_UPPER_PDU        = 0xfc
+	DLT_X2E_SERIAL                 = 0xd5
+	DLT_X2E_XORAYA                 = 0xd6
+	DT_BLK                         = 0x6
+	DT_CHR                         = 0x2
+	DT_DIR                         = 0x4
+	DT_FIFO                        = 0x1
+	DT_LNK                         = 0xa
+	DT_REG                         = 0x8
+	DT_SOCK                        = 0xc
+	DT_UNKNOWN                     = 0x0
+	DT_WHT                         = 0xe
+	ECHO                           = 0x8
+	ECHOCTL                        = 0x40
+	ECHOE                          = 0x2
+	ECHOK                          = 0x4
+	ECHOKE                         = 0x1
+	ECHONL                         = 0x10
+	ECHOPRT                        = 0x20
+	EVFILT_AIO                     = -0x3
+	EVFILT_FS                      = -0x9
+	EVFILT_LIO                     = -0xa
+	EVFILT_PROC                    = -0x5
+	EVFILT_PROCDESC                = -0x8
+	EVFILT_READ                    = -0x1
+	EVFILT_SENDFILE                = -0xc
+	EVFILT_SIGNAL                  = -0x6
+	EVFILT_SYSCOUNT                = 0xc
+	EVFILT_TIMER                   = -0x7
+	EVFILT_USER                    = -0xb
+	EVFILT_VNODE                   = -0x4
+	EVFILT_WRITE                   = -0x2
+	EV_ADD                         = 0x1
+	EV_CLEAR                       = 0x20
+	EV_DELETE                      = 0x2
+	EV_DISABLE                     = 0x8
+	EV_DISPATCH                    = 0x80
+	EV_DROP                        = 0x1000
+	EV_ENABLE                      = 0x4
+	EV_EOF                         = 0x8000
+	EV_ERROR                       = 0x4000
+	EV_FLAG1                       = 0x2000
+	EV_FLAG2                       = 0x4000
+	EV_FORCEONESHOT                = 0x100
+	EV_ONESHOT                     = 0x10
+	EV_RECEIPT                     = 0x40
+	EV_SYSFLAGS                    = 0xf000
+	EXTA                           = 0x4b00
+	EXTATTR_NAMESPACE_EMPTY        = 0x0
+	EXTATTR_NAMESPACE_SYSTEM       = 0x2
+	EXTATTR_NAMESPACE_USER         = 0x1
+	EXTB                           = 0x9600
+	EXTPROC                        = 0x800
+	FD_CLOEXEC                     = 0x1
+	FD_SETSIZE                     = 0x400
+	FLUSHO                         = 0x800000
+	F_CANCEL                       = 0x5
+	F_DUP2FD                       = 0xa
+	F_DUP2FD_CLOEXEC               = 0x12
+	F_DUPFD                        = 0x0
+	F_DUPFD_CLOEXEC                = 0x11
+	F_GETFD                        = 0x1
+	F_GETFL                        = 0x3
+	F_GETLK                        = 0xb
+	F_GETOWN                       = 0x5
+	F_OGETLK                       = 0x7
+	F_OK                           = 0x0
+	F_OSETLK                       = 0x8
+	F_OSETLKW                      = 0x9
+	F_RDAHEAD                      = 0x10
+	F_RDLCK                        = 0x1
+	F_READAHEAD                    = 0xf
+	F_SETFD                        = 0x2
+	F_SETFL                        = 0x4
+	F_SETLK                        = 0xc
+	F_SETLKW                       = 0xd
+	F_SETLK_REMOTE                 = 0xe
+	F_SETOWN                       = 0x6
+	F_UNLCK                        = 0x2
+	F_UNLCKSYS                     = 0x4
+	F_WRLCK                        = 0x3
+	HUPCL                          = 0x4000
+	ICANON                         = 0x100
+	ICMP6_FILTER                   = 0x12
+	ICRNL                          = 0x100
+	IEXTEN                         = 0x400
+	IFAN_ARRIVAL                   = 0x0
+	IFAN_DEPARTURE                 = 0x1
+	IFF_ALLMULTI                   = 0x200
+	IFF_ALTPHYS                    = 0x4000
+	IFF_BROADCAST                  = 0x2
+	IFF_CANTCHANGE                 = 0x218f52
+	IFF_CANTCONFIG                 = 0x10000
+	IFF_DEBUG                      = 0x4
+	IFF_DRV_OACTIVE                = 0x400
+	IFF_DRV_RUNNING                = 0x40
+	IFF_DYING                      = 0x200000
+	IFF_LINK0                      = 0x1000
+	IFF_LINK1                      = 0x2000
+	IFF_LINK2                      = 0x4000
+	IFF_LOOPBACK                   = 0x8
+	IFF_MONITOR                    = 0x40000
+	IFF_MULTICAST                  = 0x8000
+	IFF_NOARP                      = 0x80
+	IFF_OACTIVE                    = 0x400
+	IFF_POINTOPOINT                = 0x10
+	IFF_PPROMISC                   = 0x20000
+	IFF_PROMISC                    = 0x100
+	IFF_RENAMING                   = 0x400000
+	IFF_RUNNING                    = 0x40
+	IFF_SIMPLEX                    = 0x800
+	IFF_STATICARP                  = 0x80000
+	IFF_UP                         = 0x1
+	IFNAMSIZ                       = 0x10
+	IFT_BRIDGE                     = 0xd1
+	IFT_CARP                       = 0xf8
+	IFT_IEEE1394                   = 0x90
+	IFT_INFINIBAND                 = 0xc7
+	IFT_L2VLAN                     = 0x87
+	IFT_L3IPVLAN                   = 0x88
+	IFT_PPP                        = 0x17
+	IFT_PROPVIRTUAL                = 0x35
+	IGNBRK                         = 0x1
+	IGNCR                          = 0x80
+	IGNPAR                         = 0x4
+	IMAXBEL                        = 0x2000
+	INLCR                          = 0x40
+	INPCK                          = 0x10
+	IN_CLASSA_HOST                 = 0xffffff
+	IN_CLASSA_MAX                  = 0x80
+	IN_CLASSA_NET                  = 0xff000000
+	IN_CLASSA_NSHIFT               = 0x18
+	IN_CLASSB_HOST                 = 0xffff
+	IN_CLASSB_MAX                  = 0x10000
+	IN_CLASSB_NET                  = 0xffff0000
+	IN_CLASSB_NSHIFT               = 0x10
+	IN_CLASSC_HOST                 = 0xff
+	IN_CLASSC_NET                  = 0xffffff00
+	IN_CLASSC_NSHIFT               = 0x8
+	IN_CLASSD_HOST                 = 0xfffffff
+	IN_CLASSD_NET                  = 0xf0000000
+	IN_CLASSD_NSHIFT               = 0x1c
+	IN_LOOPBACKNET                 = 0x7f
+	IN_RFC3021_MASK                = 0xfffffffe
+	IPPROTO_3PC                    = 0x22
+	IPPROTO_ADFS                   = 0x44
+	IPPROTO_AH                     = 0x33
+	IPPROTO_AHIP                   = 0x3d
+	IPPROTO_APES                   = 0x63
+	IPPROTO_ARGUS                  = 0xd
+	IPPROTO_AX25                   = 0x5d
+	IPPROTO_BHA                    = 0x31
+	IPPROTO_BLT                    = 0x1e
+	IPPROTO_BRSATMON               = 0x4c
+	IPPROTO_CARP                   = 0x70
+	IPPROTO_CFTP                   = 0x3e
+	IPPROTO_CHAOS                  = 0x10
+	IPPROTO_CMTP                   = 0x26
+	IPPROTO_CPHB                   = 0x49
+	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DDP                    = 0x25
+	IPPROTO_DGP                    = 0x56
+	IPPROTO_DIVERT                 = 0x102
+	IPPROTO_DONE                   = 0x101
+	IPPROTO_DSTOPTS                = 0x3c
+	IPPROTO_EGP                    = 0x8
+	IPPROTO_EMCON                  = 0xe
+	IPPROTO_ENCAP                  = 0x62
+	IPPROTO_EON                    = 0x50
+	IPPROTO_ESP                    = 0x32
+	IPPROTO_ETHERIP                = 0x61
+	IPPROTO_FRAGMENT               = 0x2c
+	IPPROTO_GGP                    = 0x3
+	IPPROTO_GMTP                   = 0x64
+	IPPROTO_GRE                    = 0x2f
+	IPPROTO_HELLO                  = 0x3f
+	IPPROTO_HIP                    = 0x8b
+	IPPROTO_HMP                    = 0x14
+	IPPROTO_HOPOPTS                = 0x0
+	IPPROTO_ICMP                   = 0x1
+	IPPROTO_ICMPV6                 = 0x3a
+	IPPROTO_IDP                    = 0x16
+	IPPROTO_IDPR                   = 0x23
+	IPPROTO_IDRP                   = 0x2d
+	IPPROTO_IGMP                   = 0x2
+	IPPROTO_IGP                    = 0x55
+	IPPROTO_IGRP                   = 0x58
+	IPPROTO_IL                     = 0x28
+	IPPROTO_INLSP                  = 0x34
+	IPPROTO_INP                    = 0x20
+	IPPROTO_IP                     = 0x0
+	IPPROTO_IPCOMP                 = 0x6c
+	IPPROTO_IPCV                   = 0x47
+	IPPROTO_IPEIP                  = 0x5e
+	IPPROTO_IPIP                   = 0x4
+	IPPROTO_IPPC                   = 0x43
+	IPPROTO_IPV4                   = 0x4
+	IPPROTO_IPV6                   = 0x29
+	IPPROTO_IRTP                   = 0x1c
+	IPPROTO_KRYPTOLAN              = 0x41
+	IPPROTO_LARP                   = 0x5b
+	IPPROTO_LEAF1                  = 0x19
+	IPPROTO_LEAF2                  = 0x1a
+	IPPROTO_MAX                    = 0x100
+	IPPROTO_MEAS                   = 0x13
+	IPPROTO_MH                     = 0x87
+	IPPROTO_MHRP                   = 0x30
+	IPPROTO_MICP                   = 0x5f
+	IPPROTO_MOBILE                 = 0x37
+	IPPROTO_MPLS                   = 0x89
+	IPPROTO_MTP                    = 0x5c
+	IPPROTO_MUX                    = 0x12
+	IPPROTO_ND                     = 0x4d
+	IPPROTO_NHRP                   = 0x36
+	IPPROTO_NONE                   = 0x3b
+	IPPROTO_NSP                    = 0x1f
+	IPPROTO_NVPII                  = 0xb
+	IPPROTO_OLD_DIVERT             = 0xfe
+	IPPROTO_OSPFIGP                = 0x59
+	IPPROTO_PFSYNC                 = 0xf0
+	IPPROTO_PGM                    = 0x71
+	IPPROTO_PIGP                   = 0x9
+	IPPROTO_PIM                    = 0x67
+	IPPROTO_PRM                    = 0x15
+	IPPROTO_PUP                    = 0xc
+	IPPROTO_PVP                    = 0x4b
+	IPPROTO_RAW                    = 0xff
+	IPPROTO_RCCMON                 = 0xa
+	IPPROTO_RDP                    = 0x1b
+	IPPROTO_RESERVED_253           = 0xfd
+	IPPROTO_RESERVED_254           = 0xfe
+	IPPROTO_ROUTING                = 0x2b
+	IPPROTO_RSVP                   = 0x2e
+	IPPROTO_RVD                    = 0x42
+	IPPROTO_SATEXPAK               = 0x40
+	IPPROTO_SATMON                 = 0x45
+	IPPROTO_SCCSP                  = 0x60
+	IPPROTO_SCTP                   = 0x84
+	IPPROTO_SDRP                   = 0x2a
+	IPPROTO_SEND                   = 0x103
+	IPPROTO_SEP                    = 0x21
+	IPPROTO_SHIM6                  = 0x8c
+	IPPROTO_SKIP                   = 0x39
+	IPPROTO_SPACER                 = 0x7fff
+	IPPROTO_SRPC                   = 0x5a
+	IPPROTO_ST                     = 0x7
+	IPPROTO_SVMTP                  = 0x52
+	IPPROTO_SWIPE                  = 0x35
+	IPPROTO_TCF                    = 0x57
+	IPPROTO_TCP                    = 0x6
+	IPPROTO_TLSP                   = 0x38
+	IPPROTO_TP                     = 0x1d
+	IPPROTO_TPXX                   = 0x27
+	IPPROTO_TRUNK1                 = 0x17
+	IPPROTO_TRUNK2                 = 0x18
+	IPPROTO_TTP                    = 0x54
+	IPPROTO_UDP                    = 0x11
+	IPPROTO_UDPLITE                = 0x88
+	IPPROTO_VINES                  = 0x53
+	IPPROTO_VISA                   = 0x46
+	IPPROTO_VMTP                   = 0x51
+	IPPROTO_WBEXPAK                = 0x4f
+	IPPROTO_WBMON                  = 0x4e
+	IPPROTO_WSN                    = 0x4a
+	IPPROTO_XNET                   = 0xf
+	IPPROTO_XTP                    = 0x24
+	IPV6_AUTOFLOWLABEL             = 0x3b
+	IPV6_BINDANY                   = 0x40
+	IPV6_BINDMULTI                 = 0x41
+	IPV6_BINDV6ONLY                = 0x1b
+	IPV6_CHECKSUM                  = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS    = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP    = 0x1
+	IPV6_DEFHLIM                   = 0x40
+	IPV6_DONTFRAG                  = 0x3e
+	IPV6_DSTOPTS                   = 0x32
+	IPV6_FLOWID                    = 0x43
+	IPV6_FLOWINFO_MASK             = 0xffffff0f
+	IPV6_FLOWLABEL_MASK            = 0xffff0f00
+	IPV6_FLOWTYPE                  = 0x44
+	IPV6_FRAGTTL                   = 0x78
+	IPV6_FW_ADD                    = 0x1e
+	IPV6_FW_DEL                    = 0x1f
+	IPV6_FW_FLUSH                  = 0x20
+	IPV6_FW_GET                    = 0x22
+	IPV6_FW_ZERO                   = 0x21
+	IPV6_HLIMDEC                   = 0x1
+	IPV6_HOPLIMIT                  = 0x2f
+	IPV6_HOPOPTS                   = 0x31
+	IPV6_IPSEC_POLICY              = 0x1c
+	IPV6_JOIN_GROUP                = 0xc
+	IPV6_LEAVE_GROUP               = 0xd
+	IPV6_MAXHLIM                   = 0xff
+	IPV6_MAXOPTHDR                 = 0x800
+	IPV6_MAXPACKET                 = 0xffff
+	IPV6_MAX_GROUP_SRC_FILTER      = 0x200
+	IPV6_MAX_MEMBERSHIPS           = 0xfff
+	IPV6_MAX_SOCK_SRC_FILTER       = 0x80
+	IPV6_MIN_MEMBERSHIPS           = 0x1f
+	IPV6_MMTU                      = 0x500
+	IPV6_MSFILTER                  = 0x4a
+	IPV6_MULTICAST_HOPS            = 0xa
+	IPV6_MULTICAST_IF              = 0x9
+	IPV6_MULTICAST_LOOP            = 0xb
+	IPV6_NEXTHOP                   = 0x30
+	IPV6_PATHMTU                   = 0x2c
+	IPV6_PKTINFO                   = 0x2e
+	IPV6_PORTRANGE                 = 0xe
+	IPV6_PORTRANGE_DEFAULT         = 0x0
+	IPV6_PORTRANGE_HIGH            = 0x1
+	IPV6_PORTRANGE_LOW             = 0x2
+	IPV6_PREFER_TEMPADDR           = 0x3f
+	IPV6_RECVDSTOPTS               = 0x28
+	IPV6_RECVFLOWID                = 0x46
+	IPV6_RECVHOPLIMIT              = 0x25
+	IPV6_RECVHOPOPTS               = 0x27
+	IPV6_RECVPATHMTU               = 0x2b
+	IPV6_RECVPKTINFO               = 0x24
+	IPV6_RECVRSSBUCKETID           = 0x47
+	IPV6_RECVRTHDR                 = 0x26
+	IPV6_RECVTCLASS                = 0x39
+	IPV6_RSSBUCKETID               = 0x45
+	IPV6_RSS_LISTEN_BUCKET         = 0x42
+	IPV6_RTHDR                     = 0x33
+	IPV6_RTHDRDSTOPTS              = 0x23
+	IPV6_RTHDR_LOOSE               = 0x0
+	IPV6_RTHDR_STRICT              = 0x1
+	IPV6_RTHDR_TYPE_0              = 0x0
+	IPV6_SOCKOPT_RESERVED1         = 0x3
+	IPV6_TCLASS                    = 0x3d
+	IPV6_UNICAST_HOPS              = 0x4
+	IPV6_USE_MIN_MTU               = 0x2a
+	IPV6_V6ONLY                    = 0x1b
+	IPV6_VERSION                   = 0x60
+	IPV6_VERSION_MASK              = 0xf0
+	IP_ADD_MEMBERSHIP              = 0xc
+	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
+	IP_BINDANY                     = 0x18
+	IP_BINDMULTI                   = 0x19
+	IP_BLOCK_SOURCE                = 0x48
+	IP_DEFAULT_MULTICAST_LOOP      = 0x1
+	IP_DEFAULT_MULTICAST_TTL       = 0x1
+	IP_DF                          = 0x4000
+	IP_DONTFRAG                    = 0x43
+	IP_DROP_MEMBERSHIP             = 0xd
+	IP_DROP_SOURCE_MEMBERSHIP      = 0x47
+	IP_DUMMYNET3                   = 0x31
+	IP_DUMMYNET_CONFIGURE          = 0x3c
+	IP_DUMMYNET_DEL                = 0x3d
+	IP_DUMMYNET_FLUSH              = 0x3e
+	IP_DUMMYNET_GET                = 0x40
+	IP_FLOWID                      = 0x5a
+	IP_FLOWTYPE                    = 0x5b
+	IP_FW3                         = 0x30
+	IP_FW_ADD                      = 0x32
+	IP_FW_DEL                      = 0x33
+	IP_FW_FLUSH                    = 0x34
+	IP_FW_GET                      = 0x36
+	IP_FW_NAT_CFG                  = 0x38
+	IP_FW_NAT_DEL                  = 0x39
+	IP_FW_NAT_GET_CONFIG           = 0x3a
+	IP_FW_NAT_GET_LOG              = 0x3b
+	IP_FW_RESETLOG                 = 0x37
+	IP_FW_TABLE_ADD                = 0x28
+	IP_FW_TABLE_DEL                = 0x29
+	IP_FW_TABLE_FLUSH              = 0x2a
+	IP_FW_TABLE_GETSIZE            = 0x2b
+	IP_FW_TABLE_LIST               = 0x2c
+	IP_FW_ZERO                     = 0x35
+	IP_HDRINCL                     = 0x2
+	IP_IPSEC_POLICY                = 0x15
+	IP_MAXPACKET                   = 0xffff
+	IP_MAX_GROUP_SRC_FILTER        = 0x200
+	IP_MAX_MEMBERSHIPS             = 0xfff
+	IP_MAX_SOCK_MUTE_FILTER        = 0x80
+	IP_MAX_SOCK_SRC_FILTER         = 0x80
+	IP_MAX_SOURCE_FILTER           = 0x400
+	IP_MF                          = 0x2000
+	IP_MINTTL                      = 0x42
+	IP_MIN_MEMBERSHIPS             = 0x1f
+	IP_MSFILTER                    = 0x4a
+	IP_MSS                         = 0x240
+	IP_MULTICAST_IF                = 0x9
+	IP_MULTICAST_LOOP              = 0xb
+	IP_MULTICAST_TTL               = 0xa
+	IP_MULTICAST_VIF               = 0xe
+	IP_OFFMASK                     = 0x1fff
+	IP_ONESBCAST                   = 0x17
+	IP_OPTIONS                     = 0x1
+	IP_PORTRANGE                   = 0x13
+	IP_PORTRANGE_DEFAULT           = 0x0
+	IP_PORTRANGE_HIGH              = 0x1
+	IP_PORTRANGE_LOW               = 0x2
+	IP_RECVDSTADDR                 = 0x7
+	IP_RECVFLOWID                  = 0x5d
+	IP_RECVIF                      = 0x14
+	IP_RECVOPTS                    = 0x5
+	IP_RECVRETOPTS                 = 0x6
+	IP_RECVRSSBUCKETID             = 0x5e
+	IP_RECVTOS                     = 0x44
+	IP_RECVTTL                     = 0x41
+	IP_RETOPTS                     = 0x8
+	IP_RF                          = 0x8000
+	IP_RSSBUCKETID                 = 0x5c
+	IP_RSS_LISTEN_BUCKET           = 0x1a
+	IP_RSVP_OFF                    = 0x10
+	IP_RSVP_ON                     = 0xf
+	IP_RSVP_VIF_OFF                = 0x12
+	IP_RSVP_VIF_ON                 = 0x11
+	IP_SENDSRCADDR                 = 0x7
+	IP_TOS                         = 0x3
+	IP_TTL                         = 0x4
+	IP_UNBLOCK_SOURCE              = 0x49
+	ISIG                           = 0x80
+	ISTRIP                         = 0x20
+	IXANY                          = 0x800
+	IXOFF                          = 0x400
+	IXON                           = 0x200
+	LOCK_EX                        = 0x2
+	LOCK_NB                        = 0x4
+	LOCK_SH                        = 0x1
+	LOCK_UN                        = 0x8
+	MADV_AUTOSYNC                  = 0x7
+	MADV_CORE                      = 0x9
+	MADV_DONTNEED                  = 0x4
+	MADV_FREE                      = 0x5
+	MADV_NOCORE                    = 0x8
+	MADV_NORMAL                    = 0x0
+	MADV_NOSYNC                    = 0x6
+	MADV_PROTECT                   = 0xa
+	MADV_RANDOM                    = 0x1
+	MADV_SEQUENTIAL                = 0x2
+	MADV_WILLNEED                  = 0x3
+	MAP_ALIGNED_SUPER              = 0x1000000
+	MAP_ALIGNMENT_MASK             = -0x1000000
+	MAP_ALIGNMENT_SHIFT            = 0x18
+	MAP_ANON                       = 0x1000
+	MAP_ANONYMOUS                  = 0x1000
+	MAP_COPY                       = 0x2
+	MAP_EXCL                       = 0x4000
+	MAP_FILE                       = 0x0
+	MAP_FIXED                      = 0x10
+	MAP_HASSEMAPHORE               = 0x200
+	MAP_NOCORE                     = 0x20000
+	MAP_NOSYNC                     = 0x800
+	MAP_PREFAULT_READ              = 0x40000
+	MAP_PRIVATE                    = 0x2
+	MAP_RESERVED0020               = 0x20
+	MAP_RESERVED0040               = 0x40
+	MAP_RESERVED0080               = 0x80
+	MAP_RESERVED0100               = 0x100
+	MAP_SHARED                     = 0x1
+	MAP_STACK                      = 0x400
+	MCL_CURRENT                    = 0x1
+	MCL_FUTURE                     = 0x2
+	MSG_CMSG_CLOEXEC               = 0x40000
+	MSG_COMPAT                     = 0x8000
+	MSG_CTRUNC                     = 0x20
+	MSG_DONTROUTE                  = 0x4
+	MSG_DONTWAIT                   = 0x80
+	MSG_EOF                        = 0x100
+	MSG_EOR                        = 0x8
+	MSG_NBIO                       = 0x4000
+	MSG_NOSIGNAL                   = 0x20000
+	MSG_NOTIFICATION               = 0x2000
+	MSG_OOB                        = 0x1
+	MSG_PEEK                       = 0x2
+	MSG_TRUNC                      = 0x10
+	MSG_WAITALL                    = 0x40
+	MSG_WAITFORONE                 = 0x80000
+	MS_ASYNC                       = 0x1
+	MS_INVALIDATE                  = 0x2
+	MS_SYNC                        = 0x0
+	NAME_MAX                       = 0xff
+	NET_RT_DUMP                    = 0x1
+	NET_RT_FLAGS                   = 0x2
+	NET_RT_IFLIST                  = 0x3
+	NET_RT_IFLISTL                 = 0x5
+	NET_RT_IFMALIST                = 0x4
+	NOFLSH                         = 0x80000000
+	NOKERNINFO                     = 0x2000000
+	NOTE_ATTRIB                    = 0x8
+	NOTE_CHILD                     = 0x4
+	NOTE_CLOSE                     = 0x100
+	NOTE_CLOSE_WRITE               = 0x200
+	NOTE_DELETE                    = 0x1
+	NOTE_EXEC                      = 0x20000000
+	NOTE_EXIT                      = 0x80000000
+	NOTE_EXTEND                    = 0x4
+	NOTE_FFAND                     = 0x40000000
+	NOTE_FFCOPY                    = 0xc0000000
+	NOTE_FFCTRLMASK                = 0xc0000000
+	NOTE_FFLAGSMASK                = 0xffffff
+	NOTE_FFNOP                     = 0x0
+	NOTE_FFOR                      = 0x80000000
+	NOTE_FILE_POLL                 = 0x2
+	NOTE_FORK                      = 0x40000000
+	NOTE_LINK                      = 0x10
+	NOTE_LOWAT                     = 0x1
+	NOTE_MSECONDS                  = 0x2
+	NOTE_NSECONDS                  = 0x8
+	NOTE_OPEN                      = 0x80
+	NOTE_PCTRLMASK                 = 0xf0000000
+	NOTE_PDATAMASK                 = 0xfffff
+	NOTE_READ                      = 0x400
+	NOTE_RENAME                    = 0x20
+	NOTE_REVOKE                    = 0x40
+	NOTE_SECONDS                   = 0x1
+	NOTE_TRACK                     = 0x1
+	NOTE_TRACKERR                  = 0x2
+	NOTE_TRIGGER                   = 0x1000000
+	NOTE_USECONDS                  = 0x4
+	NOTE_WRITE                     = 0x2
+	OCRNL                          = 0x10
+	ONLCR                          = 0x2
+	ONLRET                         = 0x40
+	ONOCR                          = 0x20
+	ONOEOT                         = 0x8
+	OPOST                          = 0x1
+	OXTABS                         = 0x4
+	O_ACCMODE                      = 0x3
+	O_APPEND                       = 0x8
+	O_ASYNC                        = 0x40
+	O_CLOEXEC                      = 0x100000
+	O_CREAT                        = 0x200
+	O_DIRECT                       = 0x10000
+	O_DIRECTORY                    = 0x20000
+	O_EXCL                         = 0x800
+	O_EXEC                         = 0x40000
+	O_EXLOCK                       = 0x20
+	O_FSYNC                        = 0x80
+	O_NDELAY                       = 0x4
+	O_NOCTTY                       = 0x8000
+	O_NOFOLLOW                     = 0x100
+	O_NONBLOCK                     = 0x4
+	O_RDONLY                       = 0x0
+	O_RDWR                         = 0x2
+	O_SHLOCK                       = 0x10
+	O_SYNC                         = 0x80
+	O_TRUNC                        = 0x400
+	O_TTY_INIT                     = 0x80000
+	O_VERIFY                       = 0x200000
+	O_WRONLY                       = 0x1
+	PARENB                         = 0x1000
+	PARMRK                         = 0x8
+	PARODD                         = 0x2000
+	PENDIN                         = 0x20000000
+	PRIO_PGRP                      = 0x1
+	PRIO_PROCESS                   = 0x0
+	PRIO_USER                      = 0x2
+	PROT_EXEC                      = 0x4
+	PROT_NONE                      = 0x0
+	PROT_READ                      = 0x1
+	PROT_WRITE                     = 0x2
+	RLIMIT_AS                      = 0xa
+	RLIMIT_CORE                    = 0x4
+	RLIMIT_CPU                     = 0x0
+	RLIMIT_DATA                    = 0x2
+	RLIMIT_FSIZE                   = 0x1
+	RLIMIT_MEMLOCK                 = 0x6
+	RLIMIT_NOFILE                  = 0x8
+	RLIMIT_NPROC                   = 0x7
+	RLIMIT_RSS                     = 0x5
+	RLIMIT_STACK                   = 0x3
+	RLIM_INFINITY                  = 0x7fffffffffffffff
+	RTAX_AUTHOR                    = 0x6
+	RTAX_BRD                       = 0x7
+	RTAX_DST                       = 0x0
+	RTAX_GATEWAY                   = 0x1
+	RTAX_GENMASK                   = 0x3
+	RTAX_IFA                       = 0x5
+	RTAX_IFP                       = 0x4
+	RTAX_MAX                       = 0x8
+	RTAX_NETMASK                   = 0x2
+	RTA_AUTHOR                     = 0x40
+	RTA_BRD                        = 0x80
+	RTA_DST                        = 0x1
+	RTA_GATEWAY                    = 0x2
+	RTA_GENMASK                    = 0x8
+	RTA_IFA                        = 0x20
+	RTA_IFP                        = 0x10
+	RTA_NETMASK                    = 0x4
+	RTF_BLACKHOLE                  = 0x1000
+	RTF_BROADCAST                  = 0x400000
+	RTF_DONE                       = 0x40
+	RTF_DYNAMIC                    = 0x10
+	RTF_FIXEDMTU                   = 0x80000
+	RTF_FMASK                      = 0x1004d808
+	RTF_GATEWAY                    = 0x2
+	RTF_GWFLAG_COMPAT              = 0x80000000
+	RTF_HOST                       = 0x4
+	RTF_LLDATA                     = 0x400
+	RTF_LLINFO                     = 0x400
+	RTF_LOCAL                      = 0x200000
+	RTF_MODIFIED                   = 0x20
+	RTF_MULTICAST                  = 0x800000
+	RTF_PINNED                     = 0x100000
+	RTF_PROTO1                     = 0x8000
+	RTF_PROTO2                     = 0x4000
+	RTF_PROTO3                     = 0x40000
+	RTF_REJECT                     = 0x8
+	RTF_RNH_LOCKED                 = 0x40000000
+	RTF_STATIC                     = 0x800
+	RTF_STICKY                     = 0x10000000
+	RTF_UP                         = 0x1
+	RTF_XRESOLVE                   = 0x200
+	RTM_ADD                        = 0x1
+	RTM_CHANGE                     = 0x3
+	RTM_DELADDR                    = 0xd
+	RTM_DELETE                     = 0x2
+	RTM_DELMADDR                   = 0x10
+	RTM_GET                        = 0x4
+	RTM_IEEE80211                  = 0x12
+	RTM_IFANNOUNCE                 = 0x11
+	RTM_IFINFO                     = 0xe
+	RTM_LOCK                       = 0x8
+	RTM_LOSING                     = 0x5
+	RTM_MISS                       = 0x7
+	RTM_NEWADDR                    = 0xc
+	RTM_NEWMADDR                   = 0xf
+	RTM_REDIRECT                   = 0x6
+	RTM_RESOLVE                    = 0xb
+	RTM_RTTUNIT                    = 0xf4240
+	RTM_VERSION                    = 0x5
+	RTV_EXPIRE                     = 0x4
+	RTV_HOPCOUNT                   = 0x2
+	RTV_MTU                        = 0x1
+	RTV_RPIPE                      = 0x8
+	RTV_RTT                        = 0x40
+	RTV_RTTVAR                     = 0x80
+	RTV_SPIPE                      = 0x10
+	RTV_SSTHRESH                   = 0x20
+	RTV_WEIGHT                     = 0x100
+	RT_ALL_FIBS                    = -0x1
+	RT_BLACKHOLE                   = 0x40
+	RT_CACHING_CONTEXT             = 0x1
+	RT_DEFAULT_FIB                 = 0x0
+	RT_HAS_GW                      = 0x80
+	RT_HAS_HEADER                  = 0x10
+	RT_HAS_HEADER_BIT              = 0x4
+	RT_L2_ME                       = 0x4
+	RT_L2_ME_BIT                   = 0x2
+	RT_LLE_CACHE                   = 0x100
+	RT_MAY_LOOP                    = 0x8
+	RT_MAY_LOOP_BIT                = 0x3
+	RT_NORTREF                     = 0x2
+	RT_REJECT                      = 0x20
+	RUSAGE_CHILDREN                = -0x1
+	RUSAGE_SELF                    = 0x0
+	RUSAGE_THREAD                  = 0x1
+	SCM_BINTIME                    = 0x4
+	SCM_CREDS                      = 0x3
+	SCM_RIGHTS                     = 0x1
+	SCM_TIMESTAMP                  = 0x2
+	SHUT_RD                        = 0x0
+	SHUT_RDWR                      = 0x2
+	SHUT_WR                        = 0x1
+	SIOCADDMULTI                   = 0x80206931
+	SIOCAIFADDR                    = 0x8040691a
+	SIOCAIFGROUP                   = 0x80246987
+	SIOCATMARK                     = 0x40047307
+	SIOCDELMULTI                   = 0x80206932
+	SIOCDIFADDR                    = 0x80206919
+	SIOCDIFGROUP                   = 0x80246989
+	SIOCDIFPHYADDR                 = 0x80206949
+	SIOCGDRVSPEC                   = 0xc01c697b
+	SIOCGETSGCNT                   = 0xc0147210
+	SIOCGETVIFCNT                  = 0xc014720f
+	SIOCGHIWAT                     = 0x40047301
+	SIOCGI2C                       = 0xc020693d
+	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFBRDADDR                 = 0xc0206923
+	SIOCGIFCAP                     = 0xc020691f
+	SIOCGIFCONF                    = 0xc0086924
+	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDSTADDR                 = 0xc0206922
+	SIOCGIFFIB                     = 0xc020695c
+	SIOCGIFFLAGS                   = 0xc0206911
+	SIOCGIFGENERIC                 = 0xc020693a
+	SIOCGIFGMEMB                   = 0xc024698a
+	SIOCGIFGROUP                   = 0xc0246988
+	SIOCGIFINDEX                   = 0xc0206920
+	SIOCGIFMAC                     = 0xc0206926
+	SIOCGIFMEDIA                   = 0xc0286938
+	SIOCGIFMETRIC                  = 0xc0206917
+	SIOCGIFMTU                     = 0xc0206933
+	SIOCGIFNETMASK                 = 0xc0206925
+	SIOCGIFPDSTADDR                = 0xc0206948
+	SIOCGIFPHYS                    = 0xc0206935
+	SIOCGIFPSRCADDR                = 0xc0206947
+	SIOCGIFSTATUS                  = 0xc331693b
+	SIOCGIFXMEDIA                  = 0xc028698b
+	SIOCGLOWAT                     = 0x40047303
+	SIOCGPGRP                      = 0x40047309
+	SIOCGPRIVATE_0                 = 0xc0206950
+	SIOCGPRIVATE_1                 = 0xc0206951
+	SIOCGTUNFIB                    = 0xc020695e
+	SIOCIFCREATE                   = 0xc020697a
+	SIOCIFCREATE2                  = 0xc020697c
+	SIOCIFDESTROY                  = 0x80206979
+	SIOCIFGCLONERS                 = 0xc00c6978
+	SIOCSDRVSPEC                   = 0x801c697b
+	SIOCSHIWAT                     = 0x80047300
+	SIOCSIFADDR                    = 0x8020690c
+	SIOCSIFBRDADDR                 = 0x80206913
+	SIOCSIFCAP                     = 0x8020691e
+	SIOCSIFDESCR                   = 0x80206929
+	SIOCSIFDSTADDR                 = 0x8020690e
+	SIOCSIFFIB                     = 0x8020695d
+	SIOCSIFFLAGS                   = 0x80206910
+	SIOCSIFGENERIC                 = 0x80206939
+	SIOCSIFLLADDR                  = 0x8020693c
+	SIOCSIFMAC                     = 0x80206927
+	SIOCSIFMEDIA                   = 0xc0206937
+	SIOCSIFMETRIC                  = 0x80206918
+	SIOCSIFMTU                     = 0x80206934
+	SIOCSIFNAME                    = 0x80206928
+	SIOCSIFNETMASK                 = 0x80206916
+	SIOCSIFPHYADDR                 = 0x80406946
+	SIOCSIFPHYS                    = 0x80206936
+	SIOCSIFRVNET                   = 0xc020695b
+	SIOCSIFVNET                    = 0xc020695a
+	SIOCSLOWAT                     = 0x80047302
+	SIOCSPGRP                      = 0x80047308
+	SIOCSTUNFIB                    = 0x8020695f
+	SOCK_CLOEXEC                   = 0x10000000
+	SOCK_DGRAM                     = 0x2
+	SOCK_MAXADDRLEN                = 0xff
+	SOCK_NONBLOCK                  = 0x20000000
+	SOCK_RAW                       = 0x3
+	SOCK_RDM                       = 0x4
+	SOCK_SEQPACKET                 = 0x5
+	SOCK_STREAM                    = 0x1
+	SOL_SOCKET                     = 0xffff
+	SOMAXCONN                      = 0x80
+	SO_ACCEPTCONN                  = 0x2
+	SO_ACCEPTFILTER                = 0x1000
+	SO_BINTIME                     = 0x2000
+	SO_BROADCAST                   = 0x20
+	SO_DEBUG                       = 0x1
+	SO_DONTROUTE                   = 0x10
+	SO_ERROR                       = 0x1007
+	SO_KEEPALIVE                   = 0x8
+	SO_LABEL                       = 0x1009
+	SO_LINGER                      = 0x80
+	SO_LISTENINCQLEN               = 0x1013
+	SO_LISTENQLEN                  = 0x1012
+	SO_LISTENQLIMIT                = 0x1011
+	SO_NOSIGPIPE                   = 0x800
+	SO_NO_DDP                      = 0x8000
+	SO_NO_OFFLOAD                  = 0x4000
+	SO_OOBINLINE                   = 0x100
+	SO_PEERLABEL                   = 0x1010
+	SO_PROTOCOL                    = 0x1016
+	SO_PROTOTYPE                   = 0x1016
+	SO_RCVBUF                      = 0x1002
+	SO_RCVLOWAT                    = 0x1004
+	SO_RCVTIMEO                    = 0x1006
+	SO_REUSEADDR                   = 0x4
+	SO_REUSEPORT                   = 0x200
+	SO_SETFIB                      = 0x1014
+	SO_SNDBUF                      = 0x1001
+	SO_SNDLOWAT                    = 0x1003
+	SO_SNDTIMEO                    = 0x1005
+	SO_TIMESTAMP                   = 0x400
+	SO_TYPE                        = 0x1008
+	SO_USELOOPBACK                 = 0x40
+	SO_USER_COOKIE                 = 0x1015
+	SO_VENDOR                      = 0x80000000
+	TAB0                           = 0x0
+	TAB3                           = 0x4
+	TABDLY                         = 0x4
+	TCIFLUSH                       = 0x1
+	TCIOFF                         = 0x3
+	TCIOFLUSH                      = 0x3
+	TCION                          = 0x4
+	TCOFLUSH                       = 0x2
+	TCOOFF                         = 0x1
+	TCOON                          = 0x2
+	TCP_CA_NAME_MAX                = 0x10
+	TCP_CCALGOOPT                  = 0x41
+	TCP_CONGESTION                 = 0x40
+	TCP_FASTOPEN                   = 0x401
+	TCP_FUNCTION_BLK               = 0x2000
+	TCP_FUNCTION_NAME_LEN_MAX      = 0x20
+	TCP_INFO                       = 0x20
+	TCP_KEEPCNT                    = 0x400
+	TCP_KEEPIDLE                   = 0x100
+	TCP_KEEPINIT                   = 0x80
+	TCP_KEEPINTVL                  = 0x200
+	TCP_MAXBURST                   = 0x4
+	TCP_MAXHLEN                    = 0x3c
+	TCP_MAXOLEN                    = 0x28
+	TCP_MAXSEG                     = 0x2
+	TCP_MAXWIN                     = 0xffff
+	TCP_MAX_SACK                   = 0x4
+	TCP_MAX_WINSHIFT               = 0xe
+	TCP_MD5SIG                     = 0x10
+	TCP_MINMSS                     = 0xd8
+	TCP_MSS                        = 0x218
+	TCP_NODELAY                    = 0x1
+	TCP_NOOPT                      = 0x8
+	TCP_NOPUSH                     = 0x4
+	TCP_PCAP_IN                    = 0x1000
+	TCP_PCAP_OUT                   = 0x800
+	TCP_VENDOR                     = 0x80000000
+	TCSAFLUSH                      = 0x2
+	TIOCCBRK                       = 0x2000747a
+	TIOCCDTR                       = 0x20007478
+	TIOCCONS                       = 0x80047462
+	TIOCDRAIN                      = 0x2000745e
+	TIOCEXCL                       = 0x2000740d
+	TIOCEXT                        = 0x80047460
+	TIOCFLUSH                      = 0x80047410
+	TIOCGDRAINWAIT                 = 0x40047456
+	TIOCGETA                       = 0x402c7413
+	TIOCGETD                       = 0x4004741a
+	TIOCGPGRP                      = 0x40047477
+	TIOCGPTN                       = 0x4004740f
+	TIOCGSID                       = 0x40047463
+	TIOCGWINSZ                     = 0x40087468
+	TIOCMBIC                       = 0x8004746b
+	TIOCMBIS                       = 0x8004746c
+	TIOCMGDTRWAIT                  = 0x4004745a
+	TIOCMGET                       = 0x4004746a
+	TIOCMSDTRWAIT                  = 0x8004745b
+	TIOCMSET                       = 0x8004746d
+	TIOCM_CAR                      = 0x40
+	TIOCM_CD                       = 0x40
+	TIOCM_CTS                      = 0x20
+	TIOCM_DCD                      = 0x40
+	TIOCM_DSR                      = 0x100
+	TIOCM_DTR                      = 0x2
+	TIOCM_LE                       = 0x1
+	TIOCM_RI                       = 0x80
+	TIOCM_RNG                      = 0x80
+	TIOCM_RTS                      = 0x4
+	TIOCM_SR                       = 0x10
+	TIOCM_ST                       = 0x8
+	TIOCNOTTY                      = 0x20007471
+	TIOCNXCL                       = 0x2000740e
+	TIOCOUTQ                       = 0x40047473
+	TIOCPKT                        = 0x80047470
+	TIOCPKT_DATA                   = 0x0
+	TIOCPKT_DOSTOP                 = 0x20
+	TIOCPKT_FLUSHREAD              = 0x1
+	TIOCPKT_FLUSHWRITE             = 0x2
+	TIOCPKT_IOCTL                  = 0x40
+	TIOCPKT_NOSTOP                 = 0x10
+	TIOCPKT_START                  = 0x8
+	TIOCPKT_STOP                   = 0x4
+	TIOCPTMASTER                   = 0x2000741c
+	TIOCSBRK                       = 0x2000747b
+	TIOCSCTTY                      = 0x20007461
+	TIOCSDRAINWAIT                 = 0x80047457
+	TIOCSDTR                       = 0x20007479
+	TIOCSETA                       = 0x802c7414
+	TIOCSETAF                      = 0x802c7416
+	TIOCSETAW                      = 0x802c7415
+	TIOCSETD                       = 0x8004741b
+	TIOCSIG                        = 0x2004745f
+	TIOCSPGRP                      = 0x80047476
+	TIOCSTART                      = 0x2000746e
+	TIOCSTAT                       = 0x20007465
+	TIOCSTI                        = 0x80017472
+	TIOCSTOP                       = 0x2000746f
+	TIOCSWINSZ                     = 0x80087467
+	TIOCTIMESTAMP                  = 0x40087459
+	TIOCUCNTL                      = 0x80047466
+	TOSTOP                         = 0x400000
+	VDISCARD                       = 0xf
+	VDSUSP                         = 0xb
+	VEOF                           = 0x0
+	VEOL                           = 0x1
+	VEOL2                          = 0x2
+	VERASE                         = 0x3
+	VERASE2                        = 0x7
+	VINTR                          = 0x8
+	VKILL                          = 0x5
+	VLNEXT                         = 0xe
+	VMIN                           = 0x10
+	VQUIT                          = 0x9
+	VREPRINT                       = 0x6
+	VSTART                         = 0xc
+	VSTATUS                        = 0x12
+	VSTOP                          = 0xd
+	VSUSP                          = 0xa
+	VTIME                          = 0x11
+	VWERASE                        = 0x4
+	WCONTINUED                     = 0x4
+	WCOREFLAG                      = 0x80
+	WEXITED                        = 0x10
+	WLINUXCLONE                    = 0x80000000
+	WNOHANG                        = 0x1
+	WNOWAIT                        = 0x8
+	WSTOPPED                       = 0x2
+	WTRAPPED                       = 0x20
+	WUNTRACED                      = 0x2
 )
 
 // Errors
diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
index e48e779..ac094f9 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
@@ -1,5 +1,5 @@
 // mkerrors.sh -m64
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build amd64,freebsd
 
@@ -11,1461 +11,1420 @@
 import "syscall"
 
 const (
-	AF_APPLETALK                      = 0x10
-	AF_ARP                            = 0x23
-	AF_ATM                            = 0x1e
-	AF_BLUETOOTH                      = 0x24
-	AF_CCITT                          = 0xa
-	AF_CHAOS                          = 0x5
-	AF_CNT                            = 0x15
-	AF_COIP                           = 0x14
-	AF_DATAKIT                        = 0x9
-	AF_DECnet                         = 0xc
-	AF_DLI                            = 0xd
-	AF_E164                           = 0x1a
-	AF_ECMA                           = 0x8
-	AF_HYLINK                         = 0xf
-	AF_IEEE80211                      = 0x25
-	AF_IMPLINK                        = 0x3
-	AF_INET                           = 0x2
-	AF_INET6                          = 0x1c
-	AF_INET6_SDP                      = 0x2a
-	AF_INET_SDP                       = 0x28
-	AF_IPX                            = 0x17
-	AF_ISDN                           = 0x1a
-	AF_ISO                            = 0x7
-	AF_LAT                            = 0xe
-	AF_LINK                           = 0x12
-	AF_LOCAL                          = 0x1
-	AF_MAX                            = 0x2a
-	AF_NATM                           = 0x1d
-	AF_NETBIOS                        = 0x6
-	AF_NETGRAPH                       = 0x20
-	AF_OSI                            = 0x7
-	AF_PUP                            = 0x4
-	AF_ROUTE                          = 0x11
-	AF_SCLUSTER                       = 0x22
-	AF_SIP                            = 0x18
-	AF_SLOW                           = 0x21
-	AF_SNA                            = 0xb
-	AF_UNIX                           = 0x1
-	AF_UNSPEC                         = 0x0
-	AF_VENDOR00                       = 0x27
-	AF_VENDOR01                       = 0x29
-	AF_VENDOR02                       = 0x2b
-	AF_VENDOR03                       = 0x2d
-	AF_VENDOR04                       = 0x2f
-	AF_VENDOR05                       = 0x31
-	AF_VENDOR06                       = 0x33
-	AF_VENDOR07                       = 0x35
-	AF_VENDOR08                       = 0x37
-	AF_VENDOR09                       = 0x39
-	AF_VENDOR10                       = 0x3b
-	AF_VENDOR11                       = 0x3d
-	AF_VENDOR12                       = 0x3f
-	AF_VENDOR13                       = 0x41
-	AF_VENDOR14                       = 0x43
-	AF_VENDOR15                       = 0x45
-	AF_VENDOR16                       = 0x47
-	AF_VENDOR17                       = 0x49
-	AF_VENDOR18                       = 0x4b
-	AF_VENDOR19                       = 0x4d
-	AF_VENDOR20                       = 0x4f
-	AF_VENDOR21                       = 0x51
-	AF_VENDOR22                       = 0x53
-	AF_VENDOR23                       = 0x55
-	AF_VENDOR24                       = 0x57
-	AF_VENDOR25                       = 0x59
-	AF_VENDOR26                       = 0x5b
-	AF_VENDOR27                       = 0x5d
-	AF_VENDOR28                       = 0x5f
-	AF_VENDOR29                       = 0x61
-	AF_VENDOR30                       = 0x63
-	AF_VENDOR31                       = 0x65
-	AF_VENDOR32                       = 0x67
-	AF_VENDOR33                       = 0x69
-	AF_VENDOR34                       = 0x6b
-	AF_VENDOR35                       = 0x6d
-	AF_VENDOR36                       = 0x6f
-	AF_VENDOR37                       = 0x71
-	AF_VENDOR38                       = 0x73
-	AF_VENDOR39                       = 0x75
-	AF_VENDOR40                       = 0x77
-	AF_VENDOR41                       = 0x79
-	AF_VENDOR42                       = 0x7b
-	AF_VENDOR43                       = 0x7d
-	AF_VENDOR44                       = 0x7f
-	AF_VENDOR45                       = 0x81
-	AF_VENDOR46                       = 0x83
-	AF_VENDOR47                       = 0x85
-	B0                                = 0x0
-	B110                              = 0x6e
-	B115200                           = 0x1c200
-	B1200                             = 0x4b0
-	B134                              = 0x86
-	B14400                            = 0x3840
-	B150                              = 0x96
-	B1800                             = 0x708
-	B19200                            = 0x4b00
-	B200                              = 0xc8
-	B230400                           = 0x38400
-	B2400                             = 0x960
-	B28800                            = 0x7080
-	B300                              = 0x12c
-	B38400                            = 0x9600
-	B460800                           = 0x70800
-	B4800                             = 0x12c0
-	B50                               = 0x32
-	B57600                            = 0xe100
-	B600                              = 0x258
-	B7200                             = 0x1c20
-	B75                               = 0x4b
-	B76800                            = 0x12c00
-	B921600                           = 0xe1000
-	B9600                             = 0x2580
-	BIOCFEEDBACK                      = 0x8004427c
-	BIOCFLUSH                         = 0x20004268
-	BIOCGBLEN                         = 0x40044266
-	BIOCGDIRECTION                    = 0x40044276
-	BIOCGDLT                          = 0x4004426a
-	BIOCGDLTLIST                      = 0xc0104279
-	BIOCGETBUFMODE                    = 0x4004427d
-	BIOCGETIF                         = 0x4020426b
-	BIOCGETZMAX                       = 0x4008427f
-	BIOCGHDRCMPLT                     = 0x40044274
-	BIOCGRSIG                         = 0x40044272
-	BIOCGRTIMEOUT                     = 0x4010426e
-	BIOCGSEESENT                      = 0x40044276
-	BIOCGSTATS                        = 0x4008426f
-	BIOCGTSTAMP                       = 0x40044283
-	BIOCIMMEDIATE                     = 0x80044270
-	BIOCLOCK                          = 0x2000427a
-	BIOCPROMISC                       = 0x20004269
-	BIOCROTZBUF                       = 0x40184280
-	BIOCSBLEN                         = 0xc0044266
-	BIOCSDIRECTION                    = 0x80044277
-	BIOCSDLT                          = 0x80044278
-	BIOCSETBUFMODE                    = 0x8004427e
-	BIOCSETF                          = 0x80104267
-	BIOCSETFNR                        = 0x80104282
-	BIOCSETIF                         = 0x8020426c
-	BIOCSETWF                         = 0x8010427b
-	BIOCSETZBUF                       = 0x80184281
-	BIOCSHDRCMPLT                     = 0x80044275
-	BIOCSRSIG                         = 0x80044273
-	BIOCSRTIMEOUT                     = 0x8010426d
-	BIOCSSEESENT                      = 0x80044277
-	BIOCSTSTAMP                       = 0x80044284
-	BIOCVERSION                       = 0x40044271
-	BPF_A                             = 0x10
-	BPF_ABS                           = 0x20
-	BPF_ADD                           = 0x0
-	BPF_ALIGNMENT                     = 0x8
-	BPF_ALU                           = 0x4
-	BPF_AND                           = 0x50
-	BPF_B                             = 0x10
-	BPF_BUFMODE_BUFFER                = 0x1
-	BPF_BUFMODE_ZBUF                  = 0x2
-	BPF_DIV                           = 0x30
-	BPF_H                             = 0x8
-	BPF_IMM                           = 0x0
-	BPF_IND                           = 0x40
-	BPF_JA                            = 0x0
-	BPF_JEQ                           = 0x10
-	BPF_JGE                           = 0x30
-	BPF_JGT                           = 0x20
-	BPF_JMP                           = 0x5
-	BPF_JSET                          = 0x40
-	BPF_K                             = 0x0
-	BPF_LD                            = 0x0
-	BPF_LDX                           = 0x1
-	BPF_LEN                           = 0x80
-	BPF_LSH                           = 0x60
-	BPF_MAJOR_VERSION                 = 0x1
-	BPF_MAXBUFSIZE                    = 0x80000
-	BPF_MAXINSNS                      = 0x200
-	BPF_MEM                           = 0x60
-	BPF_MEMWORDS                      = 0x10
-	BPF_MINBUFSIZE                    = 0x20
-	BPF_MINOR_VERSION                 = 0x1
-	BPF_MISC                          = 0x7
-	BPF_MSH                           = 0xa0
-	BPF_MUL                           = 0x20
-	BPF_NEG                           = 0x80
-	BPF_OR                            = 0x40
-	BPF_RELEASE                       = 0x30bb6
-	BPF_RET                           = 0x6
-	BPF_RSH                           = 0x70
-	BPF_ST                            = 0x2
-	BPF_STX                           = 0x3
-	BPF_SUB                           = 0x10
-	BPF_TAX                           = 0x0
-	BPF_TXA                           = 0x80
-	BPF_T_BINTIME                     = 0x2
-	BPF_T_BINTIME_FAST                = 0x102
-	BPF_T_BINTIME_MONOTONIC           = 0x202
-	BPF_T_BINTIME_MONOTONIC_FAST      = 0x302
-	BPF_T_FAST                        = 0x100
-	BPF_T_FLAG_MASK                   = 0x300
-	BPF_T_FORMAT_MASK                 = 0x3
-	BPF_T_MICROTIME                   = 0x0
-	BPF_T_MICROTIME_FAST              = 0x100
-	BPF_T_MICROTIME_MONOTONIC         = 0x200
-	BPF_T_MICROTIME_MONOTONIC_FAST    = 0x300
-	BPF_T_MONOTONIC                   = 0x200
-	BPF_T_MONOTONIC_FAST              = 0x300
-	BPF_T_NANOTIME                    = 0x1
-	BPF_T_NANOTIME_FAST               = 0x101
-	BPF_T_NANOTIME_MONOTONIC          = 0x201
-	BPF_T_NANOTIME_MONOTONIC_FAST     = 0x301
-	BPF_T_NONE                        = 0x3
-	BPF_T_NORMAL                      = 0x0
-	BPF_W                             = 0x0
-	BPF_X                             = 0x8
-	BRKINT                            = 0x2
-	CFLUSH                            = 0xf
-	CLOCAL                            = 0x8000
-	CLOCK_MONOTONIC                   = 0x4
-	CLOCK_MONOTONIC_FAST              = 0xc
-	CLOCK_MONOTONIC_PRECISE           = 0xb
-	CLOCK_PROCESS_CPUTIME_ID          = 0xf
-	CLOCK_PROF                        = 0x2
-	CLOCK_REALTIME                    = 0x0
-	CLOCK_REALTIME_FAST               = 0xa
-	CLOCK_REALTIME_PRECISE            = 0x9
-	CLOCK_SECOND                      = 0xd
-	CLOCK_THREAD_CPUTIME_ID           = 0xe
-	CLOCK_UPTIME                      = 0x5
-	CLOCK_UPTIME_FAST                 = 0x8
-	CLOCK_UPTIME_PRECISE              = 0x7
-	CLOCK_VIRTUAL                     = 0x1
-	CREAD                             = 0x800
-	CS5                               = 0x0
-	CS6                               = 0x100
-	CS7                               = 0x200
-	CS8                               = 0x300
-	CSIZE                             = 0x300
-	CSTART                            = 0x11
-	CSTATUS                           = 0x14
-	CSTOP                             = 0x13
-	CSTOPB                            = 0x400
-	CSUSP                             = 0x1a
-	CTL_MAXNAME                       = 0x18
-	CTL_NET                           = 0x4
-	DLT_A429                          = 0xb8
-	DLT_A653_ICM                      = 0xb9
-	DLT_AIRONET_HEADER                = 0x78
-	DLT_AOS                           = 0xde
-	DLT_APPLE_IP_OVER_IEEE1394        = 0x8a
-	DLT_ARCNET                        = 0x7
-	DLT_ARCNET_LINUX                  = 0x81
-	DLT_ATM_CLIP                      = 0x13
-	DLT_ATM_RFC1483                   = 0xb
-	DLT_AURORA                        = 0x7e
-	DLT_AX25                          = 0x3
-	DLT_AX25_KISS                     = 0xca
-	DLT_BACNET_MS_TP                  = 0xa5
-	DLT_BLUETOOTH_HCI_H4              = 0xbb
-	DLT_BLUETOOTH_HCI_H4_WITH_PHDR    = 0xc9
-	DLT_CAN20B                        = 0xbe
-	DLT_CAN_SOCKETCAN                 = 0xe3
-	DLT_CHAOS                         = 0x5
-	DLT_CHDLC                         = 0x68
-	DLT_CISCO_IOS                     = 0x76
-	DLT_C_HDLC                        = 0x68
-	DLT_C_HDLC_WITH_DIR               = 0xcd
-	DLT_DBUS                          = 0xe7
-	DLT_DECT                          = 0xdd
-	DLT_DOCSIS                        = 0x8f
-	DLT_DVB_CI                        = 0xeb
-	DLT_ECONET                        = 0x73
-	DLT_EN10MB                        = 0x1
-	DLT_EN3MB                         = 0x2
-	DLT_ENC                           = 0x6d
-	DLT_ERF                           = 0xc5
-	DLT_ERF_ETH                       = 0xaf
-	DLT_ERF_POS                       = 0xb0
-	DLT_FC_2                          = 0xe0
-	DLT_FC_2_WITH_FRAME_DELIMS        = 0xe1
-	DLT_FDDI                          = 0xa
-	DLT_FLEXRAY                       = 0xd2
-	DLT_FRELAY                        = 0x6b
-	DLT_FRELAY_WITH_DIR               = 0xce
-	DLT_GCOM_SERIAL                   = 0xad
-	DLT_GCOM_T1E1                     = 0xac
-	DLT_GPF_F                         = 0xab
-	DLT_GPF_T                         = 0xaa
-	DLT_GPRS_LLC                      = 0xa9
-	DLT_GSMTAP_ABIS                   = 0xda
-	DLT_GSMTAP_UM                     = 0xd9
-	DLT_HHDLC                         = 0x79
-	DLT_IBM_SN                        = 0x92
-	DLT_IBM_SP                        = 0x91
-	DLT_IEEE802                       = 0x6
-	DLT_IEEE802_11                    = 0x69
-	DLT_IEEE802_11_RADIO              = 0x7f
-	DLT_IEEE802_11_RADIO_AVS          = 0xa3
-	DLT_IEEE802_15_4                  = 0xc3
-	DLT_IEEE802_15_4_LINUX            = 0xbf
-	DLT_IEEE802_15_4_NOFCS            = 0xe6
-	DLT_IEEE802_15_4_NONASK_PHY       = 0xd7
-	DLT_IEEE802_16_MAC_CPS            = 0xbc
-	DLT_IEEE802_16_MAC_CPS_RADIO      = 0xc1
-	DLT_IPFILTER                      = 0x74
-	DLT_IPMB                          = 0xc7
-	DLT_IPMB_LINUX                    = 0xd1
-	DLT_IPNET                         = 0xe2
-	DLT_IPOIB                         = 0xf2
-	DLT_IPV4                          = 0xe4
-	DLT_IPV6                          = 0xe5
-	DLT_IP_OVER_FC                    = 0x7a
-	DLT_JUNIPER_ATM1                  = 0x89
-	DLT_JUNIPER_ATM2                  = 0x87
-	DLT_JUNIPER_ATM_CEMIC             = 0xee
-	DLT_JUNIPER_CHDLC                 = 0xb5
-	DLT_JUNIPER_ES                    = 0x84
-	DLT_JUNIPER_ETHER                 = 0xb2
-	DLT_JUNIPER_FIBRECHANNEL          = 0xea
-	DLT_JUNIPER_FRELAY                = 0xb4
-	DLT_JUNIPER_GGSN                  = 0x85
-	DLT_JUNIPER_ISM                   = 0xc2
-	DLT_JUNIPER_MFR                   = 0x86
-	DLT_JUNIPER_MLFR                  = 0x83
-	DLT_JUNIPER_MLPPP                 = 0x82
-	DLT_JUNIPER_MONITOR               = 0xa4
-	DLT_JUNIPER_PIC_PEER              = 0xae
-	DLT_JUNIPER_PPP                   = 0xb3
-	DLT_JUNIPER_PPPOE                 = 0xa7
-	DLT_JUNIPER_PPPOE_ATM             = 0xa8
-	DLT_JUNIPER_SERVICES              = 0x88
-	DLT_JUNIPER_SRX_E2E               = 0xe9
-	DLT_JUNIPER_ST                    = 0xc8
-	DLT_JUNIPER_VP                    = 0xb7
-	DLT_JUNIPER_VS                    = 0xe8
-	DLT_LAPB_WITH_DIR                 = 0xcf
-	DLT_LAPD                          = 0xcb
-	DLT_LIN                           = 0xd4
-	DLT_LINUX_EVDEV                   = 0xd8
-	DLT_LINUX_IRDA                    = 0x90
-	DLT_LINUX_LAPD                    = 0xb1
-	DLT_LINUX_PPP_WITHDIRECTION       = 0xa6
-	DLT_LINUX_SLL                     = 0x71
-	DLT_LOOP                          = 0x6c
-	DLT_LTALK                         = 0x72
-	DLT_MATCHING_MAX                  = 0xf6
-	DLT_MATCHING_MIN                  = 0x68
-	DLT_MFR                           = 0xb6
-	DLT_MOST                          = 0xd3
-	DLT_MPEG_2_TS                     = 0xf3
-	DLT_MPLS                          = 0xdb
-	DLT_MTP2                          = 0x8c
-	DLT_MTP2_WITH_PHDR                = 0x8b
-	DLT_MTP3                          = 0x8d
-	DLT_MUX27010                      = 0xec
-	DLT_NETANALYZER                   = 0xf0
-	DLT_NETANALYZER_TRANSPARENT       = 0xf1
-	DLT_NFC_LLCP                      = 0xf5
-	DLT_NFLOG                         = 0xef
-	DLT_NG40                          = 0xf4
-	DLT_NULL                          = 0x0
-	DLT_PCI_EXP                       = 0x7d
-	DLT_PFLOG                         = 0x75
-	DLT_PFSYNC                        = 0x79
-	DLT_PPI                           = 0xc0
-	DLT_PPP                           = 0x9
-	DLT_PPP_BSDOS                     = 0x10
-	DLT_PPP_ETHER                     = 0x33
-	DLT_PPP_PPPD                      = 0xa6
-	DLT_PPP_SERIAL                    = 0x32
-	DLT_PPP_WITH_DIR                  = 0xcc
-	DLT_PPP_WITH_DIRECTION            = 0xa6
-	DLT_PRISM_HEADER                  = 0x77
-	DLT_PRONET                        = 0x4
-	DLT_RAIF1                         = 0xc6
-	DLT_RAW                           = 0xc
-	DLT_RIO                           = 0x7c
-	DLT_SCCP                          = 0x8e
-	DLT_SITA                          = 0xc4
-	DLT_SLIP                          = 0x8
-	DLT_SLIP_BSDOS                    = 0xf
-	DLT_STANAG_5066_D_PDU             = 0xed
-	DLT_SUNATM                        = 0x7b
-	DLT_SYMANTEC_FIREWALL             = 0x63
-	DLT_TZSP                          = 0x80
-	DLT_USB                           = 0xba
-	DLT_USB_LINUX                     = 0xbd
-	DLT_USB_LINUX_MMAPPED             = 0xdc
-	DLT_USER0                         = 0x93
-	DLT_USER1                         = 0x94
-	DLT_USER10                        = 0x9d
-	DLT_USER11                        = 0x9e
-	DLT_USER12                        = 0x9f
-	DLT_USER13                        = 0xa0
-	DLT_USER14                        = 0xa1
-	DLT_USER15                        = 0xa2
-	DLT_USER2                         = 0x95
-	DLT_USER3                         = 0x96
-	DLT_USER4                         = 0x97
-	DLT_USER5                         = 0x98
-	DLT_USER6                         = 0x99
-	DLT_USER7                         = 0x9a
-	DLT_USER8                         = 0x9b
-	DLT_USER9                         = 0x9c
-	DLT_WIHART                        = 0xdf
-	DLT_X2E_SERIAL                    = 0xd5
-	DLT_X2E_XORAYA                    = 0xd6
-	DT_BLK                            = 0x6
-	DT_CHR                            = 0x2
-	DT_DIR                            = 0x4
-	DT_FIFO                           = 0x1
-	DT_LNK                            = 0xa
-	DT_REG                            = 0x8
-	DT_SOCK                           = 0xc
-	DT_UNKNOWN                        = 0x0
-	DT_WHT                            = 0xe
-	ECHO                              = 0x8
-	ECHOCTL                           = 0x40
-	ECHOE                             = 0x2
-	ECHOK                             = 0x4
-	ECHOKE                            = 0x1
-	ECHONL                            = 0x10
-	ECHOPRT                           = 0x20
-	EVFILT_AIO                        = -0x3
-	EVFILT_FS                         = -0x9
-	EVFILT_LIO                        = -0xa
-	EVFILT_PROC                       = -0x5
-	EVFILT_READ                       = -0x1
-	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xb
-	EVFILT_TIMER                      = -0x7
-	EVFILT_USER                       = -0xb
-	EVFILT_VNODE                      = -0x4
-	EVFILT_WRITE                      = -0x2
-	EV_ADD                            = 0x1
-	EV_CLEAR                          = 0x20
-	EV_DELETE                         = 0x2
-	EV_DISABLE                        = 0x8
-	EV_DISPATCH                       = 0x80
-	EV_DROP                           = 0x1000
-	EV_ENABLE                         = 0x4
-	EV_EOF                            = 0x8000
-	EV_ERROR                          = 0x4000
-	EV_FLAG1                          = 0x2000
-	EV_ONESHOT                        = 0x10
-	EV_RECEIPT                        = 0x40
-	EV_SYSFLAGS                       = 0xf000
-	EXTA                              = 0x4b00
-	EXTATTR_NAMESPACE_EMPTY           = 0x0
-	EXTATTR_NAMESPACE_SYSTEM          = 0x2
-	EXTATTR_NAMESPACE_USER            = 0x1
-	EXTB                              = 0x9600
-	EXTPROC                           = 0x800
-	FD_CLOEXEC                        = 0x1
-	FD_SETSIZE                        = 0x400
-	FLUSHO                            = 0x800000
-	F_CANCEL                          = 0x5
-	F_DUP2FD                          = 0xa
-	F_DUP2FD_CLOEXEC                  = 0x12
-	F_DUPFD                           = 0x0
-	F_DUPFD_CLOEXEC                   = 0x11
-	F_GETFD                           = 0x1
-	F_GETFL                           = 0x3
-	F_GETLK                           = 0xb
-	F_GETOWN                          = 0x5
-	F_OGETLK                          = 0x7
-	F_OK                              = 0x0
-	F_OSETLK                          = 0x8
-	F_OSETLKW                         = 0x9
-	F_RDAHEAD                         = 0x10
-	F_RDLCK                           = 0x1
-	F_READAHEAD                       = 0xf
-	F_SETFD                           = 0x2
-	F_SETFL                           = 0x4
-	F_SETLK                           = 0xc
-	F_SETLKW                          = 0xd
-	F_SETLK_REMOTE                    = 0xe
-	F_SETOWN                          = 0x6
-	F_UNLCK                           = 0x2
-	F_UNLCKSYS                        = 0x4
-	F_WRLCK                           = 0x3
-	HUPCL                             = 0x4000
-	ICANON                            = 0x100
-	ICMP6_FILTER                      = 0x12
-	ICRNL                             = 0x100
-	IEXTEN                            = 0x400
-	IFAN_ARRIVAL                      = 0x0
-	IFAN_DEPARTURE                    = 0x1
-	IFF_ALLMULTI                      = 0x200
-	IFF_ALTPHYS                       = 0x4000
-	IFF_BROADCAST                     = 0x2
-	IFF_CANTCHANGE                    = 0x218f72
-	IFF_CANTCONFIG                    = 0x10000
-	IFF_DEBUG                         = 0x4
-	IFF_DRV_OACTIVE                   = 0x400
-	IFF_DRV_RUNNING                   = 0x40
-	IFF_DYING                         = 0x200000
-	IFF_LINK0                         = 0x1000
-	IFF_LINK1                         = 0x2000
-	IFF_LINK2                         = 0x4000
-	IFF_LOOPBACK                      = 0x8
-	IFF_MONITOR                       = 0x40000
-	IFF_MULTICAST                     = 0x8000
-	IFF_NOARP                         = 0x80
-	IFF_OACTIVE                       = 0x400
-	IFF_POINTOPOINT                   = 0x10
-	IFF_PPROMISC                      = 0x20000
-	IFF_PROMISC                       = 0x100
-	IFF_RENAMING                      = 0x400000
-	IFF_RUNNING                       = 0x40
-	IFF_SIMPLEX                       = 0x800
-	IFF_SMART                         = 0x20
-	IFF_STATICARP                     = 0x80000
-	IFF_UP                            = 0x1
-	IFNAMSIZ                          = 0x10
-	IFT_1822                          = 0x2
-	IFT_A12MPPSWITCH                  = 0x82
-	IFT_AAL2                          = 0xbb
-	IFT_AAL5                          = 0x31
-	IFT_ADSL                          = 0x5e
-	IFT_AFLANE8023                    = 0x3b
-	IFT_AFLANE8025                    = 0x3c
-	IFT_ARAP                          = 0x58
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ASYNC                         = 0x54
-	IFT_ATM                           = 0x25
-	IFT_ATMDXI                        = 0x69
-	IFT_ATMFUNI                       = 0x6a
-	IFT_ATMIMA                        = 0x6b
-	IFT_ATMLOGICAL                    = 0x50
-	IFT_ATMRADIO                      = 0xbd
-	IFT_ATMSUBINTERFACE               = 0x86
-	IFT_ATMVCIENDPT                   = 0xc2
-	IFT_ATMVIRTUAL                    = 0x95
-	IFT_BGPPOLICYACCOUNTING           = 0xa2
-	IFT_BRIDGE                        = 0xd1
-	IFT_BSC                           = 0x53
-	IFT_CARP                          = 0xf8
-	IFT_CCTEMUL                       = 0x3d
-	IFT_CEPT                          = 0x13
-	IFT_CES                           = 0x85
-	IFT_CHANNEL                       = 0x46
-	IFT_CNR                           = 0x55
-	IFT_COFFEE                        = 0x84
-	IFT_COMPOSITELINK                 = 0x9b
-	IFT_DCN                           = 0x8d
-	IFT_DIGITALPOWERLINE              = 0x8a
-	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
-	IFT_DLSW                          = 0x4a
-	IFT_DOCSCABLEDOWNSTREAM           = 0x80
-	IFT_DOCSCABLEMACLAYER             = 0x7f
-	IFT_DOCSCABLEUPSTREAM             = 0x81
-	IFT_DS0                           = 0x51
-	IFT_DS0BUNDLE                     = 0x52
-	IFT_DS1FDL                        = 0xaa
-	IFT_DS3                           = 0x1e
-	IFT_DTM                           = 0x8c
-	IFT_DVBASILN                      = 0xac
-	IFT_DVBASIOUT                     = 0xad
-	IFT_DVBRCCDOWNSTREAM              = 0x93
-	IFT_DVBRCCMACLAYER                = 0x92
-	IFT_DVBRCCUPSTREAM                = 0x94
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_EPLRS                         = 0x57
-	IFT_ESCON                         = 0x49
-	IFT_ETHER                         = 0x6
-	IFT_FAITH                         = 0xf2
-	IFT_FAST                          = 0x7d
-	IFT_FASTETHER                     = 0x3e
-	IFT_FASTETHERFX                   = 0x45
-	IFT_FDDI                          = 0xf
-	IFT_FIBRECHANNEL                  = 0x38
-	IFT_FRAMERELAYINTERCONNECT        = 0x3a
-	IFT_FRAMERELAYMPI                 = 0x5c
-	IFT_FRDLCIENDPT                   = 0xc1
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_FRF16MFRBUNDLE                = 0xa3
-	IFT_FRFORWARD                     = 0x9e
-	IFT_G703AT2MB                     = 0x43
-	IFT_G703AT64K                     = 0x42
-	IFT_GIF                           = 0xf0
-	IFT_GIGABITETHERNET               = 0x75
-	IFT_GR303IDT                      = 0xb2
-	IFT_GR303RDT                      = 0xb1
-	IFT_H323GATEKEEPER                = 0xa4
-	IFT_H323PROXY                     = 0xa5
-	IFT_HDH1822                       = 0x3
-	IFT_HDLC                          = 0x76
-	IFT_HDSL2                         = 0xa8
-	IFT_HIPERLAN2                     = 0xb7
-	IFT_HIPPI                         = 0x2f
-	IFT_HIPPIINTERFACE                = 0x39
-	IFT_HOSTPAD                       = 0x5a
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IBM370PARCHAN                 = 0x48
-	IFT_IDSL                          = 0x9a
-	IFT_IEEE1394                      = 0x90
-	IFT_IEEE80211                     = 0x47
-	IFT_IEEE80212                     = 0x37
-	IFT_IEEE8023ADLAG                 = 0xa1
-	IFT_IFGSN                         = 0x91
-	IFT_IMT                           = 0xbe
-	IFT_INFINIBAND                    = 0xc7
-	IFT_INTERLEAVE                    = 0x7c
-	IFT_IP                            = 0x7e
-	IFT_IPFORWARD                     = 0x8e
-	IFT_IPOVERATM                     = 0x72
-	IFT_IPOVERCDLC                    = 0x6d
-	IFT_IPOVERCLAW                    = 0x6e
-	IFT_IPSWITCH                      = 0x4e
-	IFT_IPXIP                         = 0xf9
-	IFT_ISDN                          = 0x3f
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISDNS                         = 0x4b
-	IFT_ISDNU                         = 0x4c
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88025CRFPINT               = 0x62
-	IFT_ISO88025DTR                   = 0x56
-	IFT_ISO88025FIBER                 = 0x73
-	IFT_ISO88026                      = 0xa
-	IFT_ISUP                          = 0xb3
-	IFT_L2VLAN                        = 0x87
-	IFT_L3IPVLAN                      = 0x88
-	IFT_L3IPXVLAN                     = 0x89
-	IFT_LAPB                          = 0x10
-	IFT_LAPD                          = 0x4d
-	IFT_LAPF                          = 0x77
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MEDIAMAILOVERIP               = 0x8b
-	IFT_MFSIGLINK                     = 0xa7
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_MPC                           = 0x71
-	IFT_MPLS                          = 0xa6
-	IFT_MPLSTUNNEL                    = 0x96
-	IFT_MSDSL                         = 0x8f
-	IFT_MVL                           = 0xbf
-	IFT_MYRINET                       = 0x63
-	IFT_NFAS                          = 0xaf
-	IFT_NSIP                          = 0x1b
-	IFT_OPTICALCHANNEL                = 0xc3
-	IFT_OPTICALTRANSPORT              = 0xc4
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PFLOG                         = 0xf6
-	IFT_PFSYNC                        = 0xf7
-	IFT_PLC                           = 0xae
-	IFT_POS                           = 0xab
-	IFT_PPP                           = 0x17
-	IFT_PPPMULTILINKBUNDLE            = 0x6c
-	IFT_PROPBWAP2MP                   = 0xb8
-	IFT_PROPCNLS                      = 0x59
-	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
-	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
-	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPVIRTUAL                   = 0x35
-	IFT_PROPWIRELESSP2P               = 0x9d
-	IFT_PTPSERIAL                     = 0x16
-	IFT_PVC                           = 0xf1
-	IFT_QLLC                          = 0x44
-	IFT_RADIOMAC                      = 0xbc
-	IFT_RADSL                         = 0x5f
-	IFT_REACHDSL                      = 0xc0
-	IFT_RFC1483                       = 0x9f
-	IFT_RS232                         = 0x21
-	IFT_RSRB                          = 0x4f
-	IFT_SDLC                          = 0x11
-	IFT_SDSL                          = 0x60
-	IFT_SHDSL                         = 0xa9
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETOVERHEADCHANNEL          = 0xb9
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_SRP                           = 0x97
-	IFT_SS7SIGLINK                    = 0x9c
-	IFT_STACKTOSTACK                  = 0x6f
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0xd7
-	IFT_T1                            = 0x12
-	IFT_TDLC                          = 0x74
-	IFT_TERMPAD                       = 0x5b
-	IFT_TR008                         = 0xb0
-	IFT_TRANSPHDLC                    = 0x7b
-	IFT_TUNNEL                        = 0x83
-	IFT_ULTRA                         = 0x1d
-	IFT_USB                           = 0xa0
-	IFT_V11                           = 0x40
-	IFT_V35                           = 0x2d
-	IFT_V36                           = 0x41
-	IFT_V37                           = 0x78
-	IFT_VDSL                          = 0x61
-	IFT_VIRTUALIPADDRESS              = 0x70
-	IFT_VOICEEM                       = 0x64
-	IFT_VOICEENCAP                    = 0x67
-	IFT_VOICEFXO                      = 0x65
-	IFT_VOICEFXS                      = 0x66
-	IFT_VOICEOVERATM                  = 0x98
-	IFT_VOICEOVERFRAMERELAY           = 0x99
-	IFT_VOICEOVERIP                   = 0x68
-	IFT_X213                          = 0x5d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25HUNTGROUP                  = 0x7a
-	IFT_X25MLP                        = 0x79
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-	IGNBRK                            = 0x1
-	IGNCR                             = 0x80
-	IGNPAR                            = 0x4
-	IMAXBEL                           = 0x2000
-	INLCR                             = 0x40
-	INPCK                             = 0x10
-	IN_CLASSA_HOST                    = 0xffffff
-	IN_CLASSA_MAX                     = 0x80
-	IN_CLASSA_NET                     = 0xff000000
-	IN_CLASSA_NSHIFT                  = 0x18
-	IN_CLASSB_HOST                    = 0xffff
-	IN_CLASSB_MAX                     = 0x10000
-	IN_CLASSB_NET                     = 0xffff0000
-	IN_CLASSB_NSHIFT                  = 0x10
-	IN_CLASSC_HOST                    = 0xff
-	IN_CLASSC_NET                     = 0xffffff00
-	IN_CLASSC_NSHIFT                  = 0x8
-	IN_CLASSD_HOST                    = 0xfffffff
-	IN_CLASSD_NET                     = 0xf0000000
-	IN_CLASSD_NSHIFT                  = 0x1c
-	IN_LOOPBACKNET                    = 0x7f
-	IN_RFC3021_MASK                   = 0xfffffffe
-	IPPROTO_3PC                       = 0x22
-	IPPROTO_ADFS                      = 0x44
-	IPPROTO_AH                        = 0x33
-	IPPROTO_AHIP                      = 0x3d
-	IPPROTO_APES                      = 0x63
-	IPPROTO_ARGUS                     = 0xd
-	IPPROTO_AX25                      = 0x5d
-	IPPROTO_BHA                       = 0x31
-	IPPROTO_BLT                       = 0x1e
-	IPPROTO_BRSATMON                  = 0x4c
-	IPPROTO_CARP                      = 0x70
-	IPPROTO_CFTP                      = 0x3e
-	IPPROTO_CHAOS                     = 0x10
-	IPPROTO_CMTP                      = 0x26
-	IPPROTO_CPHB                      = 0x49
-	IPPROTO_CPNX                      = 0x48
-	IPPROTO_DDP                       = 0x25
-	IPPROTO_DGP                       = 0x56
-	IPPROTO_DIVERT                    = 0x102
-	IPPROTO_DONE                      = 0x101
-	IPPROTO_DSTOPTS                   = 0x3c
-	IPPROTO_EGP                       = 0x8
-	IPPROTO_EMCON                     = 0xe
-	IPPROTO_ENCAP                     = 0x62
-	IPPROTO_EON                       = 0x50
-	IPPROTO_ESP                       = 0x32
-	IPPROTO_ETHERIP                   = 0x61
-	IPPROTO_FRAGMENT                  = 0x2c
-	IPPROTO_GGP                       = 0x3
-	IPPROTO_GMTP                      = 0x64
-	IPPROTO_GRE                       = 0x2f
-	IPPROTO_HELLO                     = 0x3f
-	IPPROTO_HIP                       = 0x8b
-	IPPROTO_HMP                       = 0x14
-	IPPROTO_HOPOPTS                   = 0x0
-	IPPROTO_ICMP                      = 0x1
-	IPPROTO_ICMPV6                    = 0x3a
-	IPPROTO_IDP                       = 0x16
-	IPPROTO_IDPR                      = 0x23
-	IPPROTO_IDRP                      = 0x2d
-	IPPROTO_IGMP                      = 0x2
-	IPPROTO_IGP                       = 0x55
-	IPPROTO_IGRP                      = 0x58
-	IPPROTO_IL                        = 0x28
-	IPPROTO_INLSP                     = 0x34
-	IPPROTO_INP                       = 0x20
-	IPPROTO_IP                        = 0x0
-	IPPROTO_IPCOMP                    = 0x6c
-	IPPROTO_IPCV                      = 0x47
-	IPPROTO_IPEIP                     = 0x5e
-	IPPROTO_IPIP                      = 0x4
-	IPPROTO_IPPC                      = 0x43
-	IPPROTO_IPV4                      = 0x4
-	IPPROTO_IPV6                      = 0x29
-	IPPROTO_IRTP                      = 0x1c
-	IPPROTO_KRYPTOLAN                 = 0x41
-	IPPROTO_LARP                      = 0x5b
-	IPPROTO_LEAF1                     = 0x19
-	IPPROTO_LEAF2                     = 0x1a
-	IPPROTO_MAX                       = 0x100
-	IPPROTO_MAXID                     = 0x34
-	IPPROTO_MEAS                      = 0x13
-	IPPROTO_MH                        = 0x87
-	IPPROTO_MHRP                      = 0x30
-	IPPROTO_MICP                      = 0x5f
-	IPPROTO_MOBILE                    = 0x37
-	IPPROTO_MPLS                      = 0x89
-	IPPROTO_MTP                       = 0x5c
-	IPPROTO_MUX                       = 0x12
-	IPPROTO_ND                        = 0x4d
-	IPPROTO_NHRP                      = 0x36
-	IPPROTO_NONE                      = 0x3b
-	IPPROTO_NSP                       = 0x1f
-	IPPROTO_NVPII                     = 0xb
-	IPPROTO_OLD_DIVERT                = 0xfe
-	IPPROTO_OSPFIGP                   = 0x59
-	IPPROTO_PFSYNC                    = 0xf0
-	IPPROTO_PGM                       = 0x71
-	IPPROTO_PIGP                      = 0x9
-	IPPROTO_PIM                       = 0x67
-	IPPROTO_PRM                       = 0x15
-	IPPROTO_PUP                       = 0xc
-	IPPROTO_PVP                       = 0x4b
-	IPPROTO_RAW                       = 0xff
-	IPPROTO_RCCMON                    = 0xa
-	IPPROTO_RDP                       = 0x1b
-	IPPROTO_RESERVED_253              = 0xfd
-	IPPROTO_RESERVED_254              = 0xfe
-	IPPROTO_ROUTING                   = 0x2b
-	IPPROTO_RSVP                      = 0x2e
-	IPPROTO_RVD                       = 0x42
-	IPPROTO_SATEXPAK                  = 0x40
-	IPPROTO_SATMON                    = 0x45
-	IPPROTO_SCCSP                     = 0x60
-	IPPROTO_SCTP                      = 0x84
-	IPPROTO_SDRP                      = 0x2a
-	IPPROTO_SEND                      = 0x103
-	IPPROTO_SEP                       = 0x21
-	IPPROTO_SHIM6                     = 0x8c
-	IPPROTO_SKIP                      = 0x39
-	IPPROTO_SPACER                    = 0x7fff
-	IPPROTO_SRPC                      = 0x5a
-	IPPROTO_ST                        = 0x7
-	IPPROTO_SVMTP                     = 0x52
-	IPPROTO_SWIPE                     = 0x35
-	IPPROTO_TCF                       = 0x57
-	IPPROTO_TCP                       = 0x6
-	IPPROTO_TLSP                      = 0x38
-	IPPROTO_TP                        = 0x1d
-	IPPROTO_TPXX                      = 0x27
-	IPPROTO_TRUNK1                    = 0x17
-	IPPROTO_TRUNK2                    = 0x18
-	IPPROTO_TTP                       = 0x54
-	IPPROTO_UDP                       = 0x11
-	IPPROTO_UDPLITE                   = 0x88
-	IPPROTO_VINES                     = 0x53
-	IPPROTO_VISA                      = 0x46
-	IPPROTO_VMTP                      = 0x51
-	IPPROTO_WBEXPAK                   = 0x4f
-	IPPROTO_WBMON                     = 0x4e
-	IPPROTO_WSN                       = 0x4a
-	IPPROTO_XNET                      = 0xf
-	IPPROTO_XTP                       = 0x24
-	IPV6_AUTOFLOWLABEL                = 0x3b
-	IPV6_BINDANY                      = 0x40
-	IPV6_BINDV6ONLY                   = 0x1b
-	IPV6_CHECKSUM                     = 0x1a
-	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
-	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
-	IPV6_DEFHLIM                      = 0x40
-	IPV6_DONTFRAG                     = 0x3e
-	IPV6_DSTOPTS                      = 0x32
-	IPV6_FAITH                        = 0x1d
-	IPV6_FLOWINFO_MASK                = 0xffffff0f
-	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FRAGTTL                      = 0x78
-	IPV6_FW_ADD                       = 0x1e
-	IPV6_FW_DEL                       = 0x1f
-	IPV6_FW_FLUSH                     = 0x20
-	IPV6_FW_GET                       = 0x22
-	IPV6_FW_ZERO                      = 0x21
-	IPV6_HLIMDEC                      = 0x1
-	IPV6_HOPLIMIT                     = 0x2f
-	IPV6_HOPOPTS                      = 0x31
-	IPV6_IPSEC_POLICY                 = 0x1c
-	IPV6_JOIN_GROUP                   = 0xc
-	IPV6_LEAVE_GROUP                  = 0xd
-	IPV6_MAXHLIM                      = 0xff
-	IPV6_MAXOPTHDR                    = 0x800
-	IPV6_MAXPACKET                    = 0xffff
-	IPV6_MAX_GROUP_SRC_FILTER         = 0x200
-	IPV6_MAX_MEMBERSHIPS              = 0xfff
-	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
-	IPV6_MIN_MEMBERSHIPS              = 0x1f
-	IPV6_MMTU                         = 0x500
-	IPV6_MSFILTER                     = 0x4a
-	IPV6_MULTICAST_HOPS               = 0xa
-	IPV6_MULTICAST_IF                 = 0x9
-	IPV6_MULTICAST_LOOP               = 0xb
-	IPV6_NEXTHOP                      = 0x30
-	IPV6_PATHMTU                      = 0x2c
-	IPV6_PKTINFO                      = 0x2e
-	IPV6_PORTRANGE                    = 0xe
-	IPV6_PORTRANGE_DEFAULT            = 0x0
-	IPV6_PORTRANGE_HIGH               = 0x1
-	IPV6_PORTRANGE_LOW                = 0x2
-	IPV6_PREFER_TEMPADDR              = 0x3f
-	IPV6_RECVDSTOPTS                  = 0x28
-	IPV6_RECVHOPLIMIT                 = 0x25
-	IPV6_RECVHOPOPTS                  = 0x27
-	IPV6_RECVPATHMTU                  = 0x2b
-	IPV6_RECVPKTINFO                  = 0x24
-	IPV6_RECVRTHDR                    = 0x26
-	IPV6_RECVTCLASS                   = 0x39
-	IPV6_RTHDR                        = 0x33
-	IPV6_RTHDRDSTOPTS                 = 0x23
-	IPV6_RTHDR_LOOSE                  = 0x0
-	IPV6_RTHDR_STRICT                 = 0x1
-	IPV6_RTHDR_TYPE_0                 = 0x0
-	IPV6_SOCKOPT_RESERVED1            = 0x3
-	IPV6_TCLASS                       = 0x3d
-	IPV6_UNICAST_HOPS                 = 0x4
-	IPV6_USE_MIN_MTU                  = 0x2a
-	IPV6_V6ONLY                       = 0x1b
-	IPV6_VERSION                      = 0x60
-	IPV6_VERSION_MASK                 = 0xf0
-	IP_ADD_MEMBERSHIP                 = 0xc
-	IP_ADD_SOURCE_MEMBERSHIP          = 0x46
-	IP_BINDANY                        = 0x18
-	IP_BLOCK_SOURCE                   = 0x48
-	IP_DEFAULT_MULTICAST_LOOP         = 0x1
-	IP_DEFAULT_MULTICAST_TTL          = 0x1
-	IP_DF                             = 0x4000
-	IP_DONTFRAG                       = 0x43
-	IP_DROP_MEMBERSHIP                = 0xd
-	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
-	IP_DUMMYNET3                      = 0x31
-	IP_DUMMYNET_CONFIGURE             = 0x3c
-	IP_DUMMYNET_DEL                   = 0x3d
-	IP_DUMMYNET_FLUSH                 = 0x3e
-	IP_DUMMYNET_GET                   = 0x40
-	IP_FAITH                          = 0x16
-	IP_FW3                            = 0x30
-	IP_FW_ADD                         = 0x32
-	IP_FW_DEL                         = 0x33
-	IP_FW_FLUSH                       = 0x34
-	IP_FW_GET                         = 0x36
-	IP_FW_NAT_CFG                     = 0x38
-	IP_FW_NAT_DEL                     = 0x39
-	IP_FW_NAT_GET_CONFIG              = 0x3a
-	IP_FW_NAT_GET_LOG                 = 0x3b
-	IP_FW_RESETLOG                    = 0x37
-	IP_FW_TABLE_ADD                   = 0x28
-	IP_FW_TABLE_DEL                   = 0x29
-	IP_FW_TABLE_FLUSH                 = 0x2a
-	IP_FW_TABLE_GETSIZE               = 0x2b
-	IP_FW_TABLE_LIST                  = 0x2c
-	IP_FW_ZERO                        = 0x35
-	IP_HDRINCL                        = 0x2
-	IP_IPSEC_POLICY                   = 0x15
-	IP_MAXPACKET                      = 0xffff
-	IP_MAX_GROUP_SRC_FILTER           = 0x200
-	IP_MAX_MEMBERSHIPS                = 0xfff
-	IP_MAX_SOCK_MUTE_FILTER           = 0x80
-	IP_MAX_SOCK_SRC_FILTER            = 0x80
-	IP_MAX_SOURCE_FILTER              = 0x400
-	IP_MF                             = 0x2000
-	IP_MINTTL                         = 0x42
-	IP_MIN_MEMBERSHIPS                = 0x1f
-	IP_MSFILTER                       = 0x4a
-	IP_MSS                            = 0x240
-	IP_MULTICAST_IF                   = 0x9
-	IP_MULTICAST_LOOP                 = 0xb
-	IP_MULTICAST_TTL                  = 0xa
-	IP_MULTICAST_VIF                  = 0xe
-	IP_OFFMASK                        = 0x1fff
-	IP_ONESBCAST                      = 0x17
-	IP_OPTIONS                        = 0x1
-	IP_PORTRANGE                      = 0x13
-	IP_PORTRANGE_DEFAULT              = 0x0
-	IP_PORTRANGE_HIGH                 = 0x1
-	IP_PORTRANGE_LOW                  = 0x2
-	IP_RECVDSTADDR                    = 0x7
-	IP_RECVIF                         = 0x14
-	IP_RECVOPTS                       = 0x5
-	IP_RECVRETOPTS                    = 0x6
-	IP_RECVTOS                        = 0x44
-	IP_RECVTTL                        = 0x41
-	IP_RETOPTS                        = 0x8
-	IP_RF                             = 0x8000
-	IP_RSVP_OFF                       = 0x10
-	IP_RSVP_ON                        = 0xf
-	IP_RSVP_VIF_OFF                   = 0x12
-	IP_RSVP_VIF_ON                    = 0x11
-	IP_SENDSRCADDR                    = 0x7
-	IP_TOS                            = 0x3
-	IP_TTL                            = 0x4
-	IP_UNBLOCK_SOURCE                 = 0x49
-	ISIG                              = 0x80
-	ISTRIP                            = 0x20
-	IXANY                             = 0x800
-	IXOFF                             = 0x400
-	IXON                              = 0x200
-	LOCK_EX                           = 0x2
-	LOCK_NB                           = 0x4
-	LOCK_SH                           = 0x1
-	LOCK_UN                           = 0x8
-	MADV_AUTOSYNC                     = 0x7
-	MADV_CORE                         = 0x9
-	MADV_DONTNEED                     = 0x4
-	MADV_FREE                         = 0x5
-	MADV_NOCORE                       = 0x8
-	MADV_NORMAL                       = 0x0
-	MADV_NOSYNC                       = 0x6
-	MADV_PROTECT                      = 0xa
-	MADV_RANDOM                       = 0x1
-	MADV_SEQUENTIAL                   = 0x2
-	MADV_WILLNEED                     = 0x3
-	MAP_32BIT                         = 0x80000
-	MAP_ALIGNED_SUPER                 = 0x1000000
-	MAP_ALIGNMENT_MASK                = -0x1000000
-	MAP_ALIGNMENT_SHIFT               = 0x18
-	MAP_ANON                          = 0x1000
-	MAP_ANONYMOUS                     = 0x1000
-	MAP_COPY                          = 0x2
-	MAP_EXCL                          = 0x4000
-	MAP_FILE                          = 0x0
-	MAP_FIXED                         = 0x10
-	MAP_HASSEMAPHORE                  = 0x200
-	MAP_NOCORE                        = 0x20000
-	MAP_NORESERVE                     = 0x40
-	MAP_NOSYNC                        = 0x800
-	MAP_PREFAULT_READ                 = 0x40000
-	MAP_PRIVATE                       = 0x2
-	MAP_RENAME                        = 0x20
-	MAP_RESERVED0080                  = 0x80
-	MAP_RESERVED0100                  = 0x100
-	MAP_SHARED                        = 0x1
-	MAP_STACK                         = 0x400
-	MCL_CURRENT                       = 0x1
-	MCL_FUTURE                        = 0x2
-	MSG_CMSG_CLOEXEC                  = 0x40000
-	MSG_COMPAT                        = 0x8000
-	MSG_CTRUNC                        = 0x20
-	MSG_DONTROUTE                     = 0x4
-	MSG_DONTWAIT                      = 0x80
-	MSG_EOF                           = 0x100
-	MSG_EOR                           = 0x8
-	MSG_NBIO                          = 0x4000
-	MSG_NOSIGNAL                      = 0x20000
-	MSG_NOTIFICATION                  = 0x2000
-	MSG_OOB                           = 0x1
-	MSG_PEEK                          = 0x2
-	MSG_TRUNC                         = 0x10
-	MSG_WAITALL                       = 0x40
-	MS_ASYNC                          = 0x1
-	MS_INVALIDATE                     = 0x2
-	MS_SYNC                           = 0x0
-	NAME_MAX                          = 0xff
-	NET_RT_DUMP                       = 0x1
-	NET_RT_FLAGS                      = 0x2
-	NET_RT_IFLIST                     = 0x3
-	NET_RT_IFLISTL                    = 0x5
-	NET_RT_IFMALIST                   = 0x4
-	NET_RT_MAXID                      = 0x6
-	NOFLSH                            = 0x80000000
-	NOTE_ATTRIB                       = 0x8
-	NOTE_CHILD                        = 0x4
-	NOTE_DELETE                       = 0x1
-	NOTE_EXEC                         = 0x20000000
-	NOTE_EXIT                         = 0x80000000
-	NOTE_EXTEND                       = 0x4
-	NOTE_FFAND                        = 0x40000000
-	NOTE_FFCOPY                       = 0xc0000000
-	NOTE_FFCTRLMASK                   = 0xc0000000
-	NOTE_FFLAGSMASK                   = 0xffffff
-	NOTE_FFNOP                        = 0x0
-	NOTE_FFOR                         = 0x80000000
-	NOTE_FORK                         = 0x40000000
-	NOTE_LINK                         = 0x10
-	NOTE_LOWAT                        = 0x1
-	NOTE_MSECONDS                     = 0x2
-	NOTE_NSECONDS                     = 0x8
-	NOTE_PCTRLMASK                    = 0xf0000000
-	NOTE_PDATAMASK                    = 0xfffff
-	NOTE_RENAME                       = 0x20
-	NOTE_REVOKE                       = 0x40
-	NOTE_SECONDS                      = 0x1
-	NOTE_TRACK                        = 0x1
-	NOTE_TRACKERR                     = 0x2
-	NOTE_TRIGGER                      = 0x1000000
-	NOTE_USECONDS                     = 0x4
-	NOTE_WRITE                        = 0x2
-	OCRNL                             = 0x10
-	ONLCR                             = 0x2
-	ONLRET                            = 0x40
-	ONOCR                             = 0x20
-	ONOEOT                            = 0x8
-	OPOST                             = 0x1
-	O_ACCMODE                         = 0x3
-	O_APPEND                          = 0x8
-	O_ASYNC                           = 0x40
-	O_CLOEXEC                         = 0x100000
-	O_CREAT                           = 0x200
-	O_DIRECT                          = 0x10000
-	O_DIRECTORY                       = 0x20000
-	O_EXCL                            = 0x800
-	O_EXEC                            = 0x40000
-	O_EXLOCK                          = 0x20
-	O_FSYNC                           = 0x80
-	O_NDELAY                          = 0x4
-	O_NOCTTY                          = 0x8000
-	O_NOFOLLOW                        = 0x100
-	O_NONBLOCK                        = 0x4
-	O_RDONLY                          = 0x0
-	O_RDWR                            = 0x2
-	O_SHLOCK                          = 0x10
-	O_SYNC                            = 0x80
-	O_TRUNC                           = 0x400
-	O_TTY_INIT                        = 0x80000
-	O_WRONLY                          = 0x1
-	PARENB                            = 0x1000
-	PARMRK                            = 0x8
-	PARODD                            = 0x2000
-	PENDIN                            = 0x20000000
-	PRIO_PGRP                         = 0x1
-	PRIO_PROCESS                      = 0x0
-	PRIO_USER                         = 0x2
-	PROT_EXEC                         = 0x4
-	PROT_NONE                         = 0x0
-	PROT_READ                         = 0x1
-	PROT_WRITE                        = 0x2
-	RLIMIT_AS                         = 0xa
-	RLIMIT_CORE                       = 0x4
-	RLIMIT_CPU                        = 0x0
-	RLIMIT_DATA                       = 0x2
-	RLIMIT_FSIZE                      = 0x1
-	RLIMIT_NOFILE                     = 0x8
-	RLIMIT_STACK                      = 0x3
-	RLIM_INFINITY                     = 0x7fffffffffffffff
-	RTAX_AUTHOR                       = 0x6
-	RTAX_BRD                          = 0x7
-	RTAX_DST                          = 0x0
-	RTAX_GATEWAY                      = 0x1
-	RTAX_GENMASK                      = 0x3
-	RTAX_IFA                          = 0x5
-	RTAX_IFP                          = 0x4
-	RTAX_MAX                          = 0x8
-	RTAX_NETMASK                      = 0x2
-	RTA_AUTHOR                        = 0x40
-	RTA_BRD                           = 0x80
-	RTA_DST                           = 0x1
-	RTA_GATEWAY                       = 0x2
-	RTA_GENMASK                       = 0x8
-	RTA_IFA                           = 0x20
-	RTA_IFP                           = 0x10
-	RTA_NETMASK                       = 0x4
-	RTF_BLACKHOLE                     = 0x1000
-	RTF_BROADCAST                     = 0x400000
-	RTF_DONE                          = 0x40
-	RTF_DYNAMIC                       = 0x10
-	RTF_FMASK                         = 0x1004d808
-	RTF_GATEWAY                       = 0x2
-	RTF_GWFLAG_COMPAT                 = 0x80000000
-	RTF_HOST                          = 0x4
-	RTF_LLDATA                        = 0x400
-	RTF_LLINFO                        = 0x400
-	RTF_LOCAL                         = 0x200000
-	RTF_MODIFIED                      = 0x20
-	RTF_MULTICAST                     = 0x800000
-	RTF_PINNED                        = 0x100000
-	RTF_PRCLONING                     = 0x10000
-	RTF_PROTO1                        = 0x8000
-	RTF_PROTO2                        = 0x4000
-	RTF_PROTO3                        = 0x40000
-	RTF_REJECT                        = 0x8
-	RTF_RNH_LOCKED                    = 0x40000000
-	RTF_STATIC                        = 0x800
-	RTF_STICKY                        = 0x10000000
-	RTF_UP                            = 0x1
-	RTF_XRESOLVE                      = 0x200
-	RTM_ADD                           = 0x1
-	RTM_CHANGE                        = 0x3
-	RTM_DELADDR                       = 0xd
-	RTM_DELETE                        = 0x2
-	RTM_DELMADDR                      = 0x10
-	RTM_GET                           = 0x4
-	RTM_IEEE80211                     = 0x12
-	RTM_IFANNOUNCE                    = 0x11
-	RTM_IFINFO                        = 0xe
-	RTM_LOCK                          = 0x8
-	RTM_LOSING                        = 0x5
-	RTM_MISS                          = 0x7
-	RTM_NEWADDR                       = 0xc
-	RTM_NEWMADDR                      = 0xf
-	RTM_OLDADD                        = 0x9
-	RTM_OLDDEL                        = 0xa
-	RTM_REDIRECT                      = 0x6
-	RTM_RESOLVE                       = 0xb
-	RTM_RTTUNIT                       = 0xf4240
-	RTM_VERSION                       = 0x5
-	RTV_EXPIRE                        = 0x4
-	RTV_HOPCOUNT                      = 0x2
-	RTV_MTU                           = 0x1
-	RTV_RPIPE                         = 0x8
-	RTV_RTT                           = 0x40
-	RTV_RTTVAR                        = 0x80
-	RTV_SPIPE                         = 0x10
-	RTV_SSTHRESH                      = 0x20
-	RTV_WEIGHT                        = 0x100
-	RT_ALL_FIBS                       = -0x1
-	RT_CACHING_CONTEXT                = 0x1
-	RT_DEFAULT_FIB                    = 0x0
-	RT_NORTREF                        = 0x2
-	RUSAGE_CHILDREN                   = -0x1
-	RUSAGE_SELF                       = 0x0
-	RUSAGE_THREAD                     = 0x1
-	SCM_BINTIME                       = 0x4
-	SCM_CREDS                         = 0x3
-	SCM_RIGHTS                        = 0x1
-	SCM_TIMESTAMP                     = 0x2
-	SHUT_RD                           = 0x0
-	SHUT_RDWR                         = 0x2
-	SHUT_WR                           = 0x1
-	SIOCADDMULTI                      = 0x80206931
-	SIOCADDRT                         = 0x8040720a
-	SIOCAIFADDR                       = 0x8040691a
-	SIOCAIFGROUP                      = 0x80286987
-	SIOCALIFADDR                      = 0x8118691b
-	SIOCATMARK                        = 0x40047307
-	SIOCDELMULTI                      = 0x80206932
-	SIOCDELRT                         = 0x8040720b
-	SIOCDIFADDR                       = 0x80206919
-	SIOCDIFGROUP                      = 0x80286989
-	SIOCDIFPHYADDR                    = 0x80206949
-	SIOCDLIFADDR                      = 0x8118691d
-	SIOCGDRVSPEC                      = 0xc028697b
-	SIOCGETSGCNT                      = 0xc0207210
-	SIOCGETVIFCNT                     = 0xc028720f
-	SIOCGHIWAT                        = 0x40047301
-	SIOCGIFADDR                       = 0xc0206921
-	SIOCGIFBRDADDR                    = 0xc0206923
-	SIOCGIFCAP                        = 0xc020691f
-	SIOCGIFCONF                       = 0xc0106924
-	SIOCGIFDESCR                      = 0xc020692a
-	SIOCGIFDSTADDR                    = 0xc0206922
-	SIOCGIFFIB                        = 0xc020695c
-	SIOCGIFFLAGS                      = 0xc0206911
-	SIOCGIFGENERIC                    = 0xc020693a
-	SIOCGIFGMEMB                      = 0xc028698a
-	SIOCGIFGROUP                      = 0xc0286988
-	SIOCGIFINDEX                      = 0xc0206920
-	SIOCGIFMAC                        = 0xc0206926
-	SIOCGIFMEDIA                      = 0xc0306938
-	SIOCGIFMETRIC                     = 0xc0206917
-	SIOCGIFMTU                        = 0xc0206933
-	SIOCGIFNETMASK                    = 0xc0206925
-	SIOCGIFPDSTADDR                   = 0xc0206948
-	SIOCGIFPHYS                       = 0xc0206935
-	SIOCGIFPSRCADDR                   = 0xc0206947
-	SIOCGIFSTATUS                     = 0xc331693b
-	SIOCGLIFADDR                      = 0xc118691c
-	SIOCGLIFPHYADDR                   = 0xc118694b
-	SIOCGLOWAT                        = 0x40047303
-	SIOCGPGRP                         = 0x40047309
-	SIOCGPRIVATE_0                    = 0xc0206950
-	SIOCGPRIVATE_1                    = 0xc0206951
-	SIOCIFCREATE                      = 0xc020697a
-	SIOCIFCREATE2                     = 0xc020697c
-	SIOCIFDESTROY                     = 0x80206979
-	SIOCIFGCLONERS                    = 0xc0106978
-	SIOCSDRVSPEC                      = 0x8028697b
-	SIOCSHIWAT                        = 0x80047300
-	SIOCSIFADDR                       = 0x8020690c
-	SIOCSIFBRDADDR                    = 0x80206913
-	SIOCSIFCAP                        = 0x8020691e
-	SIOCSIFDESCR                      = 0x80206929
-	SIOCSIFDSTADDR                    = 0x8020690e
-	SIOCSIFFIB                        = 0x8020695d
-	SIOCSIFFLAGS                      = 0x80206910
-	SIOCSIFGENERIC                    = 0x80206939
-	SIOCSIFLLADDR                     = 0x8020693c
-	SIOCSIFMAC                        = 0x80206927
-	SIOCSIFMEDIA                      = 0xc0206937
-	SIOCSIFMETRIC                     = 0x80206918
-	SIOCSIFMTU                        = 0x80206934
-	SIOCSIFNAME                       = 0x80206928
-	SIOCSIFNETMASK                    = 0x80206916
-	SIOCSIFPHYADDR                    = 0x80406946
-	SIOCSIFPHYS                       = 0x80206936
-	SIOCSIFRVNET                      = 0xc020695b
-	SIOCSIFVNET                       = 0xc020695a
-	SIOCSLIFPHYADDR                   = 0x8118694a
-	SIOCSLOWAT                        = 0x80047302
-	SIOCSPGRP                         = 0x80047308
-	SOCK_CLOEXEC                      = 0x10000000
-	SOCK_DGRAM                        = 0x2
-	SOCK_MAXADDRLEN                   = 0xff
-	SOCK_NONBLOCK                     = 0x20000000
-	SOCK_RAW                          = 0x3
-	SOCK_RDM                          = 0x4
-	SOCK_SEQPACKET                    = 0x5
-	SOCK_STREAM                       = 0x1
-	SOL_SOCKET                        = 0xffff
-	SOMAXCONN                         = 0x80
-	SO_ACCEPTCONN                     = 0x2
-	SO_ACCEPTFILTER                   = 0x1000
-	SO_BINTIME                        = 0x2000
-	SO_BROADCAST                      = 0x20
-	SO_DEBUG                          = 0x1
-	SO_DONTROUTE                      = 0x10
-	SO_ERROR                          = 0x1007
-	SO_KEEPALIVE                      = 0x8
-	SO_LABEL                          = 0x1009
-	SO_LINGER                         = 0x80
-	SO_LISTENINCQLEN                  = 0x1013
-	SO_LISTENQLEN                     = 0x1012
-	SO_LISTENQLIMIT                   = 0x1011
-	SO_NOSIGPIPE                      = 0x800
-	SO_NO_DDP                         = 0x8000
-	SO_NO_OFFLOAD                     = 0x4000
-	SO_OOBINLINE                      = 0x100
-	SO_PEERLABEL                      = 0x1010
-	SO_PROTOCOL                       = 0x1016
-	SO_PROTOTYPE                      = 0x1016
-	SO_RCVBUF                         = 0x1002
-	SO_RCVLOWAT                       = 0x1004
-	SO_RCVTIMEO                       = 0x1006
-	SO_REUSEADDR                      = 0x4
-	SO_REUSEPORT                      = 0x200
-	SO_SETFIB                         = 0x1014
-	SO_SNDBUF                         = 0x1001
-	SO_SNDLOWAT                       = 0x1003
-	SO_SNDTIMEO                       = 0x1005
-	SO_TIMESTAMP                      = 0x400
-	SO_TYPE                           = 0x1008
-	SO_USELOOPBACK                    = 0x40
-	SO_USER_COOKIE                    = 0x1015
-	SO_VENDOR                         = 0x80000000
-	TCIFLUSH                          = 0x1
-	TCIOFLUSH                         = 0x3
-	TCOFLUSH                          = 0x2
-	TCP_CA_NAME_MAX                   = 0x10
-	TCP_CONGESTION                    = 0x40
-	TCP_INFO                          = 0x20
-	TCP_KEEPCNT                       = 0x400
-	TCP_KEEPIDLE                      = 0x100
-	TCP_KEEPINIT                      = 0x80
-	TCP_KEEPINTVL                     = 0x200
-	TCP_MAXBURST                      = 0x4
-	TCP_MAXHLEN                       = 0x3c
-	TCP_MAXOLEN                       = 0x28
-	TCP_MAXSEG                        = 0x2
-	TCP_MAXWIN                        = 0xffff
-	TCP_MAX_SACK                      = 0x4
-	TCP_MAX_WINSHIFT                  = 0xe
-	TCP_MD5SIG                        = 0x10
-	TCP_MINMSS                        = 0xd8
-	TCP_MSS                           = 0x218
-	TCP_NODELAY                       = 0x1
-	TCP_NOOPT                         = 0x8
-	TCP_NOPUSH                        = 0x4
-	TCP_VENDOR                        = 0x80000000
-	TCSAFLUSH                         = 0x2
-	TIOCCBRK                          = 0x2000747a
-	TIOCCDTR                          = 0x20007478
-	TIOCCONS                          = 0x80047462
-	TIOCDRAIN                         = 0x2000745e
-	TIOCEXCL                          = 0x2000740d
-	TIOCEXT                           = 0x80047460
-	TIOCFLUSH                         = 0x80047410
-	TIOCGDRAINWAIT                    = 0x40047456
-	TIOCGETA                          = 0x402c7413
-	TIOCGETD                          = 0x4004741a
-	TIOCGPGRP                         = 0x40047477
-	TIOCGPTN                          = 0x4004740f
-	TIOCGSID                          = 0x40047463
-	TIOCGWINSZ                        = 0x40087468
-	TIOCMBIC                          = 0x8004746b
-	TIOCMBIS                          = 0x8004746c
-	TIOCMGDTRWAIT                     = 0x4004745a
-	TIOCMGET                          = 0x4004746a
-	TIOCMSDTRWAIT                     = 0x8004745b
-	TIOCMSET                          = 0x8004746d
-	TIOCM_CAR                         = 0x40
-	TIOCM_CD                          = 0x40
-	TIOCM_CTS                         = 0x20
-	TIOCM_DCD                         = 0x40
-	TIOCM_DSR                         = 0x100
-	TIOCM_DTR                         = 0x2
-	TIOCM_LE                          = 0x1
-	TIOCM_RI                          = 0x80
-	TIOCM_RNG                         = 0x80
-	TIOCM_RTS                         = 0x4
-	TIOCM_SR                          = 0x10
-	TIOCM_ST                          = 0x8
-	TIOCNOTTY                         = 0x20007471
-	TIOCNXCL                          = 0x2000740e
-	TIOCOUTQ                          = 0x40047473
-	TIOCPKT                           = 0x80047470
-	TIOCPKT_DATA                      = 0x0
-	TIOCPKT_DOSTOP                    = 0x20
-	TIOCPKT_FLUSHREAD                 = 0x1
-	TIOCPKT_FLUSHWRITE                = 0x2
-	TIOCPKT_IOCTL                     = 0x40
-	TIOCPKT_NOSTOP                    = 0x10
-	TIOCPKT_START                     = 0x8
-	TIOCPKT_STOP                      = 0x4
-	TIOCPTMASTER                      = 0x2000741c
-	TIOCSBRK                          = 0x2000747b
-	TIOCSCTTY                         = 0x20007461
-	TIOCSDRAINWAIT                    = 0x80047457
-	TIOCSDTR                          = 0x20007479
-	TIOCSETA                          = 0x802c7414
-	TIOCSETAF                         = 0x802c7416
-	TIOCSETAW                         = 0x802c7415
-	TIOCSETD                          = 0x8004741b
-	TIOCSIG                           = 0x2004745f
-	TIOCSPGRP                         = 0x80047476
-	TIOCSTART                         = 0x2000746e
-	TIOCSTAT                          = 0x20007465
-	TIOCSTI                           = 0x80017472
-	TIOCSTOP                          = 0x2000746f
-	TIOCSWINSZ                        = 0x80087467
-	TIOCTIMESTAMP                     = 0x40107459
-	TIOCUCNTL                         = 0x80047466
-	TOSTOP                            = 0x400000
-	VDISCARD                          = 0xf
-	VDSUSP                            = 0xb
-	VEOF                              = 0x0
-	VEOL                              = 0x1
-	VEOL2                             = 0x2
-	VERASE                            = 0x3
-	VERASE2                           = 0x7
-	VINTR                             = 0x8
-	VKILL                             = 0x5
-	VLNEXT                            = 0xe
-	VMIN                              = 0x10
-	VQUIT                             = 0x9
-	VREPRINT                          = 0x6
-	VSTART                            = 0xc
-	VSTATUS                           = 0x12
-	VSTOP                             = 0xd
-	VSUSP                             = 0xa
-	VTIME                             = 0x11
-	VWERASE                           = 0x4
-	WCONTINUED                        = 0x4
-	WCOREFLAG                         = 0x80
-	WEXITED                           = 0x10
-	WLINUXCLONE                       = 0x80000000
-	WNOHANG                           = 0x1
-	WNOWAIT                           = 0x8
-	WSTOPPED                          = 0x2
-	WTRAPPED                          = 0x20
-	WUNTRACED                         = 0x2
+	AF_APPLETALK                   = 0x10
+	AF_ARP                         = 0x23
+	AF_ATM                         = 0x1e
+	AF_BLUETOOTH                   = 0x24
+	AF_CCITT                       = 0xa
+	AF_CHAOS                       = 0x5
+	AF_CNT                         = 0x15
+	AF_COIP                        = 0x14
+	AF_DATAKIT                     = 0x9
+	AF_DECnet                      = 0xc
+	AF_DLI                         = 0xd
+	AF_E164                        = 0x1a
+	AF_ECMA                        = 0x8
+	AF_HYLINK                      = 0xf
+	AF_IEEE80211                   = 0x25
+	AF_IMPLINK                     = 0x3
+	AF_INET                        = 0x2
+	AF_INET6                       = 0x1c
+	AF_INET6_SDP                   = 0x2a
+	AF_INET_SDP                    = 0x28
+	AF_IPX                         = 0x17
+	AF_ISDN                        = 0x1a
+	AF_ISO                         = 0x7
+	AF_LAT                         = 0xe
+	AF_LINK                        = 0x12
+	AF_LOCAL                       = 0x1
+	AF_MAX                         = 0x2a
+	AF_NATM                        = 0x1d
+	AF_NETBIOS                     = 0x6
+	AF_NETGRAPH                    = 0x20
+	AF_OSI                         = 0x7
+	AF_PUP                         = 0x4
+	AF_ROUTE                       = 0x11
+	AF_SCLUSTER                    = 0x22
+	AF_SIP                         = 0x18
+	AF_SLOW                        = 0x21
+	AF_SNA                         = 0xb
+	AF_UNIX                        = 0x1
+	AF_UNSPEC                      = 0x0
+	AF_VENDOR00                    = 0x27
+	AF_VENDOR01                    = 0x29
+	AF_VENDOR02                    = 0x2b
+	AF_VENDOR03                    = 0x2d
+	AF_VENDOR04                    = 0x2f
+	AF_VENDOR05                    = 0x31
+	AF_VENDOR06                    = 0x33
+	AF_VENDOR07                    = 0x35
+	AF_VENDOR08                    = 0x37
+	AF_VENDOR09                    = 0x39
+	AF_VENDOR10                    = 0x3b
+	AF_VENDOR11                    = 0x3d
+	AF_VENDOR12                    = 0x3f
+	AF_VENDOR13                    = 0x41
+	AF_VENDOR14                    = 0x43
+	AF_VENDOR15                    = 0x45
+	AF_VENDOR16                    = 0x47
+	AF_VENDOR17                    = 0x49
+	AF_VENDOR18                    = 0x4b
+	AF_VENDOR19                    = 0x4d
+	AF_VENDOR20                    = 0x4f
+	AF_VENDOR21                    = 0x51
+	AF_VENDOR22                    = 0x53
+	AF_VENDOR23                    = 0x55
+	AF_VENDOR24                    = 0x57
+	AF_VENDOR25                    = 0x59
+	AF_VENDOR26                    = 0x5b
+	AF_VENDOR27                    = 0x5d
+	AF_VENDOR28                    = 0x5f
+	AF_VENDOR29                    = 0x61
+	AF_VENDOR30                    = 0x63
+	AF_VENDOR31                    = 0x65
+	AF_VENDOR32                    = 0x67
+	AF_VENDOR33                    = 0x69
+	AF_VENDOR34                    = 0x6b
+	AF_VENDOR35                    = 0x6d
+	AF_VENDOR36                    = 0x6f
+	AF_VENDOR37                    = 0x71
+	AF_VENDOR38                    = 0x73
+	AF_VENDOR39                    = 0x75
+	AF_VENDOR40                    = 0x77
+	AF_VENDOR41                    = 0x79
+	AF_VENDOR42                    = 0x7b
+	AF_VENDOR43                    = 0x7d
+	AF_VENDOR44                    = 0x7f
+	AF_VENDOR45                    = 0x81
+	AF_VENDOR46                    = 0x83
+	AF_VENDOR47                    = 0x85
+	ALTWERASE                      = 0x200
+	B0                             = 0x0
+	B110                           = 0x6e
+	B115200                        = 0x1c200
+	B1200                          = 0x4b0
+	B134                           = 0x86
+	B14400                         = 0x3840
+	B150                           = 0x96
+	B1800                          = 0x708
+	B19200                         = 0x4b00
+	B200                           = 0xc8
+	B230400                        = 0x38400
+	B2400                          = 0x960
+	B28800                         = 0x7080
+	B300                           = 0x12c
+	B38400                         = 0x9600
+	B460800                        = 0x70800
+	B4800                          = 0x12c0
+	B50                            = 0x32
+	B57600                         = 0xe100
+	B600                           = 0x258
+	B7200                          = 0x1c20
+	B75                            = 0x4b
+	B76800                         = 0x12c00
+	B921600                        = 0xe1000
+	B9600                          = 0x2580
+	BIOCFEEDBACK                   = 0x8004427c
+	BIOCFLUSH                      = 0x20004268
+	BIOCGBLEN                      = 0x40044266
+	BIOCGDIRECTION                 = 0x40044276
+	BIOCGDLT                       = 0x4004426a
+	BIOCGDLTLIST                   = 0xc0104279
+	BIOCGETBUFMODE                 = 0x4004427d
+	BIOCGETIF                      = 0x4020426b
+	BIOCGETZMAX                    = 0x4008427f
+	BIOCGHDRCMPLT                  = 0x40044274
+	BIOCGRSIG                      = 0x40044272
+	BIOCGRTIMEOUT                  = 0x4010426e
+	BIOCGSEESENT                   = 0x40044276
+	BIOCGSTATS                     = 0x4008426f
+	BIOCGTSTAMP                    = 0x40044283
+	BIOCIMMEDIATE                  = 0x80044270
+	BIOCLOCK                       = 0x2000427a
+	BIOCPROMISC                    = 0x20004269
+	BIOCROTZBUF                    = 0x40184280
+	BIOCSBLEN                      = 0xc0044266
+	BIOCSDIRECTION                 = 0x80044277
+	BIOCSDLT                       = 0x80044278
+	BIOCSETBUFMODE                 = 0x8004427e
+	BIOCSETF                       = 0x80104267
+	BIOCSETFNR                     = 0x80104282
+	BIOCSETIF                      = 0x8020426c
+	BIOCSETWF                      = 0x8010427b
+	BIOCSETZBUF                    = 0x80184281
+	BIOCSHDRCMPLT                  = 0x80044275
+	BIOCSRSIG                      = 0x80044273
+	BIOCSRTIMEOUT                  = 0x8010426d
+	BIOCSSEESENT                   = 0x80044277
+	BIOCSTSTAMP                    = 0x80044284
+	BIOCVERSION                    = 0x40044271
+	BPF_A                          = 0x10
+	BPF_ABS                        = 0x20
+	BPF_ADD                        = 0x0
+	BPF_ALIGNMENT                  = 0x8
+	BPF_ALU                        = 0x4
+	BPF_AND                        = 0x50
+	BPF_B                          = 0x10
+	BPF_BUFMODE_BUFFER             = 0x1
+	BPF_BUFMODE_ZBUF               = 0x2
+	BPF_DIV                        = 0x30
+	BPF_H                          = 0x8
+	BPF_IMM                        = 0x0
+	BPF_IND                        = 0x40
+	BPF_JA                         = 0x0
+	BPF_JEQ                        = 0x10
+	BPF_JGE                        = 0x30
+	BPF_JGT                        = 0x20
+	BPF_JMP                        = 0x5
+	BPF_JSET                       = 0x40
+	BPF_K                          = 0x0
+	BPF_LD                         = 0x0
+	BPF_LDX                        = 0x1
+	BPF_LEN                        = 0x80
+	BPF_LSH                        = 0x60
+	BPF_MAJOR_VERSION              = 0x1
+	BPF_MAXBUFSIZE                 = 0x80000
+	BPF_MAXINSNS                   = 0x200
+	BPF_MEM                        = 0x60
+	BPF_MEMWORDS                   = 0x10
+	BPF_MINBUFSIZE                 = 0x20
+	BPF_MINOR_VERSION              = 0x1
+	BPF_MISC                       = 0x7
+	BPF_MOD                        = 0x90
+	BPF_MSH                        = 0xa0
+	BPF_MUL                        = 0x20
+	BPF_NEG                        = 0x80
+	BPF_OR                         = 0x40
+	BPF_RELEASE                    = 0x30bb6
+	BPF_RET                        = 0x6
+	BPF_RSH                        = 0x70
+	BPF_ST                         = 0x2
+	BPF_STX                        = 0x3
+	BPF_SUB                        = 0x10
+	BPF_TAX                        = 0x0
+	BPF_TXA                        = 0x80
+	BPF_T_BINTIME                  = 0x2
+	BPF_T_BINTIME_FAST             = 0x102
+	BPF_T_BINTIME_MONOTONIC        = 0x202
+	BPF_T_BINTIME_MONOTONIC_FAST   = 0x302
+	BPF_T_FAST                     = 0x100
+	BPF_T_FLAG_MASK                = 0x300
+	BPF_T_FORMAT_MASK              = 0x3
+	BPF_T_MICROTIME                = 0x0
+	BPF_T_MICROTIME_FAST           = 0x100
+	BPF_T_MICROTIME_MONOTONIC      = 0x200
+	BPF_T_MICROTIME_MONOTONIC_FAST = 0x300
+	BPF_T_MONOTONIC                = 0x200
+	BPF_T_MONOTONIC_FAST           = 0x300
+	BPF_T_NANOTIME                 = 0x1
+	BPF_T_NANOTIME_FAST            = 0x101
+	BPF_T_NANOTIME_MONOTONIC       = 0x201
+	BPF_T_NANOTIME_MONOTONIC_FAST  = 0x301
+	BPF_T_NONE                     = 0x3
+	BPF_T_NORMAL                   = 0x0
+	BPF_W                          = 0x0
+	BPF_X                          = 0x8
+	BPF_XOR                        = 0xa0
+	BRKINT                         = 0x2
+	CAP_ACCEPT                     = 0x200000020000000
+	CAP_ACL_CHECK                  = 0x400000000010000
+	CAP_ACL_DELETE                 = 0x400000000020000
+	CAP_ACL_GET                    = 0x400000000040000
+	CAP_ACL_SET                    = 0x400000000080000
+	CAP_ALL0                       = 0x20007ffffffffff
+	CAP_ALL1                       = 0x4000000001fffff
+	CAP_BIND                       = 0x200000040000000
+	CAP_BINDAT                     = 0x200008000000400
+	CAP_CHFLAGSAT                  = 0x200000000001400
+	CAP_CONNECT                    = 0x200000080000000
+	CAP_CONNECTAT                  = 0x200010000000400
+	CAP_CREATE                     = 0x200000000000040
+	CAP_EVENT                      = 0x400000000000020
+	CAP_EXTATTR_DELETE             = 0x400000000001000
+	CAP_EXTATTR_GET                = 0x400000000002000
+	CAP_EXTATTR_LIST               = 0x400000000004000
+	CAP_EXTATTR_SET                = 0x400000000008000
+	CAP_FCHDIR                     = 0x200000000000800
+	CAP_FCHFLAGS                   = 0x200000000001000
+	CAP_FCHMOD                     = 0x200000000002000
+	CAP_FCHMODAT                   = 0x200000000002400
+	CAP_FCHOWN                     = 0x200000000004000
+	CAP_FCHOWNAT                   = 0x200000000004400
+	CAP_FCNTL                      = 0x200000000008000
+	CAP_FCNTL_ALL                  = 0x78
+	CAP_FCNTL_GETFL                = 0x8
+	CAP_FCNTL_GETOWN               = 0x20
+	CAP_FCNTL_SETFL                = 0x10
+	CAP_FCNTL_SETOWN               = 0x40
+	CAP_FEXECVE                    = 0x200000000000080
+	CAP_FLOCK                      = 0x200000000010000
+	CAP_FPATHCONF                  = 0x200000000020000
+	CAP_FSCK                       = 0x200000000040000
+	CAP_FSTAT                      = 0x200000000080000
+	CAP_FSTATAT                    = 0x200000000080400
+	CAP_FSTATFS                    = 0x200000000100000
+	CAP_FSYNC                      = 0x200000000000100
+	CAP_FTRUNCATE                  = 0x200000000000200
+	CAP_FUTIMES                    = 0x200000000200000
+	CAP_FUTIMESAT                  = 0x200000000200400
+	CAP_GETPEERNAME                = 0x200000100000000
+	CAP_GETSOCKNAME                = 0x200000200000000
+	CAP_GETSOCKOPT                 = 0x200000400000000
+	CAP_IOCTL                      = 0x400000000000080
+	CAP_IOCTLS_ALL                 = 0x7fffffffffffffff
+	CAP_KQUEUE                     = 0x400000000100040
+	CAP_KQUEUE_CHANGE              = 0x400000000100000
+	CAP_KQUEUE_EVENT               = 0x400000000000040
+	CAP_LINKAT_SOURCE              = 0x200020000000400
+	CAP_LINKAT_TARGET              = 0x200000000400400
+	CAP_LISTEN                     = 0x200000800000000
+	CAP_LOOKUP                     = 0x200000000000400
+	CAP_MAC_GET                    = 0x400000000000001
+	CAP_MAC_SET                    = 0x400000000000002
+	CAP_MKDIRAT                    = 0x200000000800400
+	CAP_MKFIFOAT                   = 0x200000001000400
+	CAP_MKNODAT                    = 0x200000002000400
+	CAP_MMAP                       = 0x200000000000010
+	CAP_MMAP_R                     = 0x20000000000001d
+	CAP_MMAP_RW                    = 0x20000000000001f
+	CAP_MMAP_RWX                   = 0x20000000000003f
+	CAP_MMAP_RX                    = 0x20000000000003d
+	CAP_MMAP_W                     = 0x20000000000001e
+	CAP_MMAP_WX                    = 0x20000000000003e
+	CAP_MMAP_X                     = 0x20000000000003c
+	CAP_PDGETPID                   = 0x400000000000200
+	CAP_PDKILL                     = 0x400000000000800
+	CAP_PDWAIT                     = 0x400000000000400
+	CAP_PEELOFF                    = 0x200001000000000
+	CAP_POLL_EVENT                 = 0x400000000000020
+	CAP_PREAD                      = 0x20000000000000d
+	CAP_PWRITE                     = 0x20000000000000e
+	CAP_READ                       = 0x200000000000001
+	CAP_RECV                       = 0x200000000000001
+	CAP_RENAMEAT_SOURCE            = 0x200000004000400
+	CAP_RENAMEAT_TARGET            = 0x200040000000400
+	CAP_RIGHTS_VERSION             = 0x0
+	CAP_RIGHTS_VERSION_00          = 0x0
+	CAP_SEEK                       = 0x20000000000000c
+	CAP_SEEK_TELL                  = 0x200000000000004
+	CAP_SEM_GETVALUE               = 0x400000000000004
+	CAP_SEM_POST                   = 0x400000000000008
+	CAP_SEM_WAIT                   = 0x400000000000010
+	CAP_SEND                       = 0x200000000000002
+	CAP_SETSOCKOPT                 = 0x200002000000000
+	CAP_SHUTDOWN                   = 0x200004000000000
+	CAP_SOCK_CLIENT                = 0x200007780000003
+	CAP_SOCK_SERVER                = 0x200007f60000003
+	CAP_SYMLINKAT                  = 0x200000008000400
+	CAP_TTYHOOK                    = 0x400000000000100
+	CAP_UNLINKAT                   = 0x200000010000400
+	CAP_UNUSED0_44                 = 0x200080000000000
+	CAP_UNUSED0_57                 = 0x300000000000000
+	CAP_UNUSED1_22                 = 0x400000000200000
+	CAP_UNUSED1_57                 = 0x500000000000000
+	CAP_WRITE                      = 0x200000000000002
+	CFLUSH                         = 0xf
+	CLOCAL                         = 0x8000
+	CLOCK_MONOTONIC                = 0x4
+	CLOCK_MONOTONIC_FAST           = 0xc
+	CLOCK_MONOTONIC_PRECISE        = 0xb
+	CLOCK_PROCESS_CPUTIME_ID       = 0xf
+	CLOCK_PROF                     = 0x2
+	CLOCK_REALTIME                 = 0x0
+	CLOCK_REALTIME_FAST            = 0xa
+	CLOCK_REALTIME_PRECISE         = 0x9
+	CLOCK_SECOND                   = 0xd
+	CLOCK_THREAD_CPUTIME_ID        = 0xe
+	CLOCK_UPTIME                   = 0x5
+	CLOCK_UPTIME_FAST              = 0x8
+	CLOCK_UPTIME_PRECISE           = 0x7
+	CLOCK_VIRTUAL                  = 0x1
+	CREAD                          = 0x800
+	CRTSCTS                        = 0x30000
+	CS5                            = 0x0
+	CS6                            = 0x100
+	CS7                            = 0x200
+	CS8                            = 0x300
+	CSIZE                          = 0x300
+	CSTART                         = 0x11
+	CSTATUS                        = 0x14
+	CSTOP                          = 0x13
+	CSTOPB                         = 0x400
+	CSUSP                          = 0x1a
+	CTL_MAXNAME                    = 0x18
+	CTL_NET                        = 0x4
+	DLT_A429                       = 0xb8
+	DLT_A653_ICM                   = 0xb9
+	DLT_AIRONET_HEADER             = 0x78
+	DLT_AOS                        = 0xde
+	DLT_APPLE_IP_OVER_IEEE1394     = 0x8a
+	DLT_ARCNET                     = 0x7
+	DLT_ARCNET_LINUX               = 0x81
+	DLT_ATM_CLIP                   = 0x13
+	DLT_ATM_RFC1483                = 0xb
+	DLT_AURORA                     = 0x7e
+	DLT_AX25                       = 0x3
+	DLT_AX25_KISS                  = 0xca
+	DLT_BACNET_MS_TP               = 0xa5
+	DLT_BLUETOOTH_BREDR_BB         = 0xff
+	DLT_BLUETOOTH_HCI_H4           = 0xbb
+	DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9
+	DLT_BLUETOOTH_LE_LL            = 0xfb
+	DLT_BLUETOOTH_LE_LL_WITH_PHDR  = 0x100
+	DLT_BLUETOOTH_LINUX_MONITOR    = 0xfe
+	DLT_CAN20B                     = 0xbe
+	DLT_CAN_SOCKETCAN              = 0xe3
+	DLT_CHAOS                      = 0x5
+	DLT_CHDLC                      = 0x68
+	DLT_CISCO_IOS                  = 0x76
+	DLT_C_HDLC                     = 0x68
+	DLT_C_HDLC_WITH_DIR            = 0xcd
+	DLT_DBUS                       = 0xe7
+	DLT_DECT                       = 0xdd
+	DLT_DOCSIS                     = 0x8f
+	DLT_DVB_CI                     = 0xeb
+	DLT_ECONET                     = 0x73
+	DLT_EN10MB                     = 0x1
+	DLT_EN3MB                      = 0x2
+	DLT_ENC                        = 0x6d
+	DLT_EPON                       = 0x103
+	DLT_ERF                        = 0xc5
+	DLT_ERF_ETH                    = 0xaf
+	DLT_ERF_POS                    = 0xb0
+	DLT_FC_2                       = 0xe0
+	DLT_FC_2_WITH_FRAME_DELIMS     = 0xe1
+	DLT_FDDI                       = 0xa
+	DLT_FLEXRAY                    = 0xd2
+	DLT_FRELAY                     = 0x6b
+	DLT_FRELAY_WITH_DIR            = 0xce
+	DLT_GCOM_SERIAL                = 0xad
+	DLT_GCOM_T1E1                  = 0xac
+	DLT_GPF_F                      = 0xab
+	DLT_GPF_T                      = 0xaa
+	DLT_GPRS_LLC                   = 0xa9
+	DLT_GSMTAP_ABIS                = 0xda
+	DLT_GSMTAP_UM                  = 0xd9
+	DLT_HHDLC                      = 0x79
+	DLT_IBM_SN                     = 0x92
+	DLT_IBM_SP                     = 0x91
+	DLT_IEEE802                    = 0x6
+	DLT_IEEE802_11                 = 0x69
+	DLT_IEEE802_11_RADIO           = 0x7f
+	DLT_IEEE802_11_RADIO_AVS       = 0xa3
+	DLT_IEEE802_15_4               = 0xc3
+	DLT_IEEE802_15_4_LINUX         = 0xbf
+	DLT_IEEE802_15_4_NOFCS         = 0xe6
+	DLT_IEEE802_15_4_NONASK_PHY    = 0xd7
+	DLT_IEEE802_16_MAC_CPS         = 0xbc
+	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
+	DLT_INFINIBAND                 = 0xf7
+	DLT_IPFILTER                   = 0x74
+	DLT_IPMB                       = 0xc7
+	DLT_IPMB_LINUX                 = 0xd1
+	DLT_IPMI_HPM_2                 = 0x104
+	DLT_IPNET                      = 0xe2
+	DLT_IPOIB                      = 0xf2
+	DLT_IPV4                       = 0xe4
+	DLT_IPV6                       = 0xe5
+	DLT_IP_OVER_FC                 = 0x7a
+	DLT_JUNIPER_ATM1               = 0x89
+	DLT_JUNIPER_ATM2               = 0x87
+	DLT_JUNIPER_ATM_CEMIC          = 0xee
+	DLT_JUNIPER_CHDLC              = 0xb5
+	DLT_JUNIPER_ES                 = 0x84
+	DLT_JUNIPER_ETHER              = 0xb2
+	DLT_JUNIPER_FIBRECHANNEL       = 0xea
+	DLT_JUNIPER_FRELAY             = 0xb4
+	DLT_JUNIPER_GGSN               = 0x85
+	DLT_JUNIPER_ISM                = 0xc2
+	DLT_JUNIPER_MFR                = 0x86
+	DLT_JUNIPER_MLFR               = 0x83
+	DLT_JUNIPER_MLPPP              = 0x82
+	DLT_JUNIPER_MONITOR            = 0xa4
+	DLT_JUNIPER_PIC_PEER           = 0xae
+	DLT_JUNIPER_PPP                = 0xb3
+	DLT_JUNIPER_PPPOE              = 0xa7
+	DLT_JUNIPER_PPPOE_ATM          = 0xa8
+	DLT_JUNIPER_SERVICES           = 0x88
+	DLT_JUNIPER_SRX_E2E            = 0xe9
+	DLT_JUNIPER_ST                 = 0xc8
+	DLT_JUNIPER_VP                 = 0xb7
+	DLT_JUNIPER_VS                 = 0xe8
+	DLT_LAPB_WITH_DIR              = 0xcf
+	DLT_LAPD                       = 0xcb
+	DLT_LIN                        = 0xd4
+	DLT_LINUX_EVDEV                = 0xd8
+	DLT_LINUX_IRDA                 = 0x90
+	DLT_LINUX_LAPD                 = 0xb1
+	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
+	DLT_LINUX_SLL                  = 0x71
+	DLT_LOOP                       = 0x6c
+	DLT_LTALK                      = 0x72
+	DLT_MATCHING_MAX               = 0x104
+	DLT_MATCHING_MIN               = 0x68
+	DLT_MFR                        = 0xb6
+	DLT_MOST                       = 0xd3
+	DLT_MPEG_2_TS                  = 0xf3
+	DLT_MPLS                       = 0xdb
+	DLT_MTP2                       = 0x8c
+	DLT_MTP2_WITH_PHDR             = 0x8b
+	DLT_MTP3                       = 0x8d
+	DLT_MUX27010                   = 0xec
+	DLT_NETANALYZER                = 0xf0
+	DLT_NETANALYZER_TRANSPARENT    = 0xf1
+	DLT_NETLINK                    = 0xfd
+	DLT_NFC_LLCP                   = 0xf5
+	DLT_NFLOG                      = 0xef
+	DLT_NG40                       = 0xf4
+	DLT_NULL                       = 0x0
+	DLT_PCI_EXP                    = 0x7d
+	DLT_PFLOG                      = 0x75
+	DLT_PFSYNC                     = 0x79
+	DLT_PKTAP                      = 0x102
+	DLT_PPI                        = 0xc0
+	DLT_PPP                        = 0x9
+	DLT_PPP_BSDOS                  = 0x10
+	DLT_PPP_ETHER                  = 0x33
+	DLT_PPP_PPPD                   = 0xa6
+	DLT_PPP_SERIAL                 = 0x32
+	DLT_PPP_WITH_DIR               = 0xcc
+	DLT_PPP_WITH_DIRECTION         = 0xa6
+	DLT_PRISM_HEADER               = 0x77
+	DLT_PROFIBUS_DL                = 0x101
+	DLT_PRONET                     = 0x4
+	DLT_RAIF1                      = 0xc6
+	DLT_RAW                        = 0xc
+	DLT_RIO                        = 0x7c
+	DLT_RTAC_SERIAL                = 0xfa
+	DLT_SCCP                       = 0x8e
+	DLT_SCTP                       = 0xf8
+	DLT_SITA                       = 0xc4
+	DLT_SLIP                       = 0x8
+	DLT_SLIP_BSDOS                 = 0xf
+	DLT_STANAG_5066_D_PDU          = 0xed
+	DLT_SUNATM                     = 0x7b
+	DLT_SYMANTEC_FIREWALL          = 0x63
+	DLT_TZSP                       = 0x80
+	DLT_USB                        = 0xba
+	DLT_USBPCAP                    = 0xf9
+	DLT_USB_LINUX                  = 0xbd
+	DLT_USB_LINUX_MMAPPED          = 0xdc
+	DLT_USER0                      = 0x93
+	DLT_USER1                      = 0x94
+	DLT_USER10                     = 0x9d
+	DLT_USER11                     = 0x9e
+	DLT_USER12                     = 0x9f
+	DLT_USER13                     = 0xa0
+	DLT_USER14                     = 0xa1
+	DLT_USER15                     = 0xa2
+	DLT_USER2                      = 0x95
+	DLT_USER3                      = 0x96
+	DLT_USER4                      = 0x97
+	DLT_USER5                      = 0x98
+	DLT_USER6                      = 0x99
+	DLT_USER7                      = 0x9a
+	DLT_USER8                      = 0x9b
+	DLT_USER9                      = 0x9c
+	DLT_WIHART                     = 0xdf
+	DLT_WIRESHARK_UPPER_PDU        = 0xfc
+	DLT_X2E_SERIAL                 = 0xd5
+	DLT_X2E_XORAYA                 = 0xd6
+	DT_BLK                         = 0x6
+	DT_CHR                         = 0x2
+	DT_DIR                         = 0x4
+	DT_FIFO                        = 0x1
+	DT_LNK                         = 0xa
+	DT_REG                         = 0x8
+	DT_SOCK                        = 0xc
+	DT_UNKNOWN                     = 0x0
+	DT_WHT                         = 0xe
+	ECHO                           = 0x8
+	ECHOCTL                        = 0x40
+	ECHOE                          = 0x2
+	ECHOK                          = 0x4
+	ECHOKE                         = 0x1
+	ECHONL                         = 0x10
+	ECHOPRT                        = 0x20
+	EVFILT_AIO                     = -0x3
+	EVFILT_FS                      = -0x9
+	EVFILT_LIO                     = -0xa
+	EVFILT_PROC                    = -0x5
+	EVFILT_PROCDESC                = -0x8
+	EVFILT_READ                    = -0x1
+	EVFILT_SENDFILE                = -0xc
+	EVFILT_SIGNAL                  = -0x6
+	EVFILT_SYSCOUNT                = 0xc
+	EVFILT_TIMER                   = -0x7
+	EVFILT_USER                    = -0xb
+	EVFILT_VNODE                   = -0x4
+	EVFILT_WRITE                   = -0x2
+	EV_ADD                         = 0x1
+	EV_CLEAR                       = 0x20
+	EV_DELETE                      = 0x2
+	EV_DISABLE                     = 0x8
+	EV_DISPATCH                    = 0x80
+	EV_DROP                        = 0x1000
+	EV_ENABLE                      = 0x4
+	EV_EOF                         = 0x8000
+	EV_ERROR                       = 0x4000
+	EV_FLAG1                       = 0x2000
+	EV_FLAG2                       = 0x4000
+	EV_FORCEONESHOT                = 0x100
+	EV_ONESHOT                     = 0x10
+	EV_RECEIPT                     = 0x40
+	EV_SYSFLAGS                    = 0xf000
+	EXTA                           = 0x4b00
+	EXTATTR_NAMESPACE_EMPTY        = 0x0
+	EXTATTR_NAMESPACE_SYSTEM       = 0x2
+	EXTATTR_NAMESPACE_USER         = 0x1
+	EXTB                           = 0x9600
+	EXTPROC                        = 0x800
+	FD_CLOEXEC                     = 0x1
+	FD_SETSIZE                     = 0x400
+	FLUSHO                         = 0x800000
+	F_CANCEL                       = 0x5
+	F_DUP2FD                       = 0xa
+	F_DUP2FD_CLOEXEC               = 0x12
+	F_DUPFD                        = 0x0
+	F_DUPFD_CLOEXEC                = 0x11
+	F_GETFD                        = 0x1
+	F_GETFL                        = 0x3
+	F_GETLK                        = 0xb
+	F_GETOWN                       = 0x5
+	F_OGETLK                       = 0x7
+	F_OK                           = 0x0
+	F_OSETLK                       = 0x8
+	F_OSETLKW                      = 0x9
+	F_RDAHEAD                      = 0x10
+	F_RDLCK                        = 0x1
+	F_READAHEAD                    = 0xf
+	F_SETFD                        = 0x2
+	F_SETFL                        = 0x4
+	F_SETLK                        = 0xc
+	F_SETLKW                       = 0xd
+	F_SETLK_REMOTE                 = 0xe
+	F_SETOWN                       = 0x6
+	F_UNLCK                        = 0x2
+	F_UNLCKSYS                     = 0x4
+	F_WRLCK                        = 0x3
+	HUPCL                          = 0x4000
+	ICANON                         = 0x100
+	ICMP6_FILTER                   = 0x12
+	ICRNL                          = 0x100
+	IEXTEN                         = 0x400
+	IFAN_ARRIVAL                   = 0x0
+	IFAN_DEPARTURE                 = 0x1
+	IFF_ALLMULTI                   = 0x200
+	IFF_ALTPHYS                    = 0x4000
+	IFF_BROADCAST                  = 0x2
+	IFF_CANTCHANGE                 = 0x218f52
+	IFF_CANTCONFIG                 = 0x10000
+	IFF_DEBUG                      = 0x4
+	IFF_DRV_OACTIVE                = 0x400
+	IFF_DRV_RUNNING                = 0x40
+	IFF_DYING                      = 0x200000
+	IFF_LINK0                      = 0x1000
+	IFF_LINK1                      = 0x2000
+	IFF_LINK2                      = 0x4000
+	IFF_LOOPBACK                   = 0x8
+	IFF_MONITOR                    = 0x40000
+	IFF_MULTICAST                  = 0x8000
+	IFF_NOARP                      = 0x80
+	IFF_OACTIVE                    = 0x400
+	IFF_POINTOPOINT                = 0x10
+	IFF_PPROMISC                   = 0x20000
+	IFF_PROMISC                    = 0x100
+	IFF_RENAMING                   = 0x400000
+	IFF_RUNNING                    = 0x40
+	IFF_SIMPLEX                    = 0x800
+	IFF_STATICARP                  = 0x80000
+	IFF_UP                         = 0x1
+	IFNAMSIZ                       = 0x10
+	IFT_BRIDGE                     = 0xd1
+	IFT_CARP                       = 0xf8
+	IFT_IEEE1394                   = 0x90
+	IFT_INFINIBAND                 = 0xc7
+	IFT_L2VLAN                     = 0x87
+	IFT_L3IPVLAN                   = 0x88
+	IFT_PPP                        = 0x17
+	IFT_PROPVIRTUAL                = 0x35
+	IGNBRK                         = 0x1
+	IGNCR                          = 0x80
+	IGNPAR                         = 0x4
+	IMAXBEL                        = 0x2000
+	INLCR                          = 0x40
+	INPCK                          = 0x10
+	IN_CLASSA_HOST                 = 0xffffff
+	IN_CLASSA_MAX                  = 0x80
+	IN_CLASSA_NET                  = 0xff000000
+	IN_CLASSA_NSHIFT               = 0x18
+	IN_CLASSB_HOST                 = 0xffff
+	IN_CLASSB_MAX                  = 0x10000
+	IN_CLASSB_NET                  = 0xffff0000
+	IN_CLASSB_NSHIFT               = 0x10
+	IN_CLASSC_HOST                 = 0xff
+	IN_CLASSC_NET                  = 0xffffff00
+	IN_CLASSC_NSHIFT               = 0x8
+	IN_CLASSD_HOST                 = 0xfffffff
+	IN_CLASSD_NET                  = 0xf0000000
+	IN_CLASSD_NSHIFT               = 0x1c
+	IN_LOOPBACKNET                 = 0x7f
+	IN_RFC3021_MASK                = 0xfffffffe
+	IPPROTO_3PC                    = 0x22
+	IPPROTO_ADFS                   = 0x44
+	IPPROTO_AH                     = 0x33
+	IPPROTO_AHIP                   = 0x3d
+	IPPROTO_APES                   = 0x63
+	IPPROTO_ARGUS                  = 0xd
+	IPPROTO_AX25                   = 0x5d
+	IPPROTO_BHA                    = 0x31
+	IPPROTO_BLT                    = 0x1e
+	IPPROTO_BRSATMON               = 0x4c
+	IPPROTO_CARP                   = 0x70
+	IPPROTO_CFTP                   = 0x3e
+	IPPROTO_CHAOS                  = 0x10
+	IPPROTO_CMTP                   = 0x26
+	IPPROTO_CPHB                   = 0x49
+	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DDP                    = 0x25
+	IPPROTO_DGP                    = 0x56
+	IPPROTO_DIVERT                 = 0x102
+	IPPROTO_DONE                   = 0x101
+	IPPROTO_DSTOPTS                = 0x3c
+	IPPROTO_EGP                    = 0x8
+	IPPROTO_EMCON                  = 0xe
+	IPPROTO_ENCAP                  = 0x62
+	IPPROTO_EON                    = 0x50
+	IPPROTO_ESP                    = 0x32
+	IPPROTO_ETHERIP                = 0x61
+	IPPROTO_FRAGMENT               = 0x2c
+	IPPROTO_GGP                    = 0x3
+	IPPROTO_GMTP                   = 0x64
+	IPPROTO_GRE                    = 0x2f
+	IPPROTO_HELLO                  = 0x3f
+	IPPROTO_HIP                    = 0x8b
+	IPPROTO_HMP                    = 0x14
+	IPPROTO_HOPOPTS                = 0x0
+	IPPROTO_ICMP                   = 0x1
+	IPPROTO_ICMPV6                 = 0x3a
+	IPPROTO_IDP                    = 0x16
+	IPPROTO_IDPR                   = 0x23
+	IPPROTO_IDRP                   = 0x2d
+	IPPROTO_IGMP                   = 0x2
+	IPPROTO_IGP                    = 0x55
+	IPPROTO_IGRP                   = 0x58
+	IPPROTO_IL                     = 0x28
+	IPPROTO_INLSP                  = 0x34
+	IPPROTO_INP                    = 0x20
+	IPPROTO_IP                     = 0x0
+	IPPROTO_IPCOMP                 = 0x6c
+	IPPROTO_IPCV                   = 0x47
+	IPPROTO_IPEIP                  = 0x5e
+	IPPROTO_IPIP                   = 0x4
+	IPPROTO_IPPC                   = 0x43
+	IPPROTO_IPV4                   = 0x4
+	IPPROTO_IPV6                   = 0x29
+	IPPROTO_IRTP                   = 0x1c
+	IPPROTO_KRYPTOLAN              = 0x41
+	IPPROTO_LARP                   = 0x5b
+	IPPROTO_LEAF1                  = 0x19
+	IPPROTO_LEAF2                  = 0x1a
+	IPPROTO_MAX                    = 0x100
+	IPPROTO_MEAS                   = 0x13
+	IPPROTO_MH                     = 0x87
+	IPPROTO_MHRP                   = 0x30
+	IPPROTO_MICP                   = 0x5f
+	IPPROTO_MOBILE                 = 0x37
+	IPPROTO_MPLS                   = 0x89
+	IPPROTO_MTP                    = 0x5c
+	IPPROTO_MUX                    = 0x12
+	IPPROTO_ND                     = 0x4d
+	IPPROTO_NHRP                   = 0x36
+	IPPROTO_NONE                   = 0x3b
+	IPPROTO_NSP                    = 0x1f
+	IPPROTO_NVPII                  = 0xb
+	IPPROTO_OLD_DIVERT             = 0xfe
+	IPPROTO_OSPFIGP                = 0x59
+	IPPROTO_PFSYNC                 = 0xf0
+	IPPROTO_PGM                    = 0x71
+	IPPROTO_PIGP                   = 0x9
+	IPPROTO_PIM                    = 0x67
+	IPPROTO_PRM                    = 0x15
+	IPPROTO_PUP                    = 0xc
+	IPPROTO_PVP                    = 0x4b
+	IPPROTO_RAW                    = 0xff
+	IPPROTO_RCCMON                 = 0xa
+	IPPROTO_RDP                    = 0x1b
+	IPPROTO_RESERVED_253           = 0xfd
+	IPPROTO_RESERVED_254           = 0xfe
+	IPPROTO_ROUTING                = 0x2b
+	IPPROTO_RSVP                   = 0x2e
+	IPPROTO_RVD                    = 0x42
+	IPPROTO_SATEXPAK               = 0x40
+	IPPROTO_SATMON                 = 0x45
+	IPPROTO_SCCSP                  = 0x60
+	IPPROTO_SCTP                   = 0x84
+	IPPROTO_SDRP                   = 0x2a
+	IPPROTO_SEND                   = 0x103
+	IPPROTO_SEP                    = 0x21
+	IPPROTO_SHIM6                  = 0x8c
+	IPPROTO_SKIP                   = 0x39
+	IPPROTO_SPACER                 = 0x7fff
+	IPPROTO_SRPC                   = 0x5a
+	IPPROTO_ST                     = 0x7
+	IPPROTO_SVMTP                  = 0x52
+	IPPROTO_SWIPE                  = 0x35
+	IPPROTO_TCF                    = 0x57
+	IPPROTO_TCP                    = 0x6
+	IPPROTO_TLSP                   = 0x38
+	IPPROTO_TP                     = 0x1d
+	IPPROTO_TPXX                   = 0x27
+	IPPROTO_TRUNK1                 = 0x17
+	IPPROTO_TRUNK2                 = 0x18
+	IPPROTO_TTP                    = 0x54
+	IPPROTO_UDP                    = 0x11
+	IPPROTO_UDPLITE                = 0x88
+	IPPROTO_VINES                  = 0x53
+	IPPROTO_VISA                   = 0x46
+	IPPROTO_VMTP                   = 0x51
+	IPPROTO_WBEXPAK                = 0x4f
+	IPPROTO_WBMON                  = 0x4e
+	IPPROTO_WSN                    = 0x4a
+	IPPROTO_XNET                   = 0xf
+	IPPROTO_XTP                    = 0x24
+	IPV6_AUTOFLOWLABEL             = 0x3b
+	IPV6_BINDANY                   = 0x40
+	IPV6_BINDMULTI                 = 0x41
+	IPV6_BINDV6ONLY                = 0x1b
+	IPV6_CHECKSUM                  = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS    = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP    = 0x1
+	IPV6_DEFHLIM                   = 0x40
+	IPV6_DONTFRAG                  = 0x3e
+	IPV6_DSTOPTS                   = 0x32
+	IPV6_FLOWID                    = 0x43
+	IPV6_FLOWINFO_MASK             = 0xffffff0f
+	IPV6_FLOWLABEL_MASK            = 0xffff0f00
+	IPV6_FLOWTYPE                  = 0x44
+	IPV6_FRAGTTL                   = 0x78
+	IPV6_FW_ADD                    = 0x1e
+	IPV6_FW_DEL                    = 0x1f
+	IPV6_FW_FLUSH                  = 0x20
+	IPV6_FW_GET                    = 0x22
+	IPV6_FW_ZERO                   = 0x21
+	IPV6_HLIMDEC                   = 0x1
+	IPV6_HOPLIMIT                  = 0x2f
+	IPV6_HOPOPTS                   = 0x31
+	IPV6_IPSEC_POLICY              = 0x1c
+	IPV6_JOIN_GROUP                = 0xc
+	IPV6_LEAVE_GROUP               = 0xd
+	IPV6_MAXHLIM                   = 0xff
+	IPV6_MAXOPTHDR                 = 0x800
+	IPV6_MAXPACKET                 = 0xffff
+	IPV6_MAX_GROUP_SRC_FILTER      = 0x200
+	IPV6_MAX_MEMBERSHIPS           = 0xfff
+	IPV6_MAX_SOCK_SRC_FILTER       = 0x80
+	IPV6_MIN_MEMBERSHIPS           = 0x1f
+	IPV6_MMTU                      = 0x500
+	IPV6_MSFILTER                  = 0x4a
+	IPV6_MULTICAST_HOPS            = 0xa
+	IPV6_MULTICAST_IF              = 0x9
+	IPV6_MULTICAST_LOOP            = 0xb
+	IPV6_NEXTHOP                   = 0x30
+	IPV6_PATHMTU                   = 0x2c
+	IPV6_PKTINFO                   = 0x2e
+	IPV6_PORTRANGE                 = 0xe
+	IPV6_PORTRANGE_DEFAULT         = 0x0
+	IPV6_PORTRANGE_HIGH            = 0x1
+	IPV6_PORTRANGE_LOW             = 0x2
+	IPV6_PREFER_TEMPADDR           = 0x3f
+	IPV6_RECVDSTOPTS               = 0x28
+	IPV6_RECVFLOWID                = 0x46
+	IPV6_RECVHOPLIMIT              = 0x25
+	IPV6_RECVHOPOPTS               = 0x27
+	IPV6_RECVPATHMTU               = 0x2b
+	IPV6_RECVPKTINFO               = 0x24
+	IPV6_RECVRSSBUCKETID           = 0x47
+	IPV6_RECVRTHDR                 = 0x26
+	IPV6_RECVTCLASS                = 0x39
+	IPV6_RSSBUCKETID               = 0x45
+	IPV6_RSS_LISTEN_BUCKET         = 0x42
+	IPV6_RTHDR                     = 0x33
+	IPV6_RTHDRDSTOPTS              = 0x23
+	IPV6_RTHDR_LOOSE               = 0x0
+	IPV6_RTHDR_STRICT              = 0x1
+	IPV6_RTHDR_TYPE_0              = 0x0
+	IPV6_SOCKOPT_RESERVED1         = 0x3
+	IPV6_TCLASS                    = 0x3d
+	IPV6_UNICAST_HOPS              = 0x4
+	IPV6_USE_MIN_MTU               = 0x2a
+	IPV6_V6ONLY                    = 0x1b
+	IPV6_VERSION                   = 0x60
+	IPV6_VERSION_MASK              = 0xf0
+	IP_ADD_MEMBERSHIP              = 0xc
+	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
+	IP_BINDANY                     = 0x18
+	IP_BINDMULTI                   = 0x19
+	IP_BLOCK_SOURCE                = 0x48
+	IP_DEFAULT_MULTICAST_LOOP      = 0x1
+	IP_DEFAULT_MULTICAST_TTL       = 0x1
+	IP_DF                          = 0x4000
+	IP_DONTFRAG                    = 0x43
+	IP_DROP_MEMBERSHIP             = 0xd
+	IP_DROP_SOURCE_MEMBERSHIP      = 0x47
+	IP_DUMMYNET3                   = 0x31
+	IP_DUMMYNET_CONFIGURE          = 0x3c
+	IP_DUMMYNET_DEL                = 0x3d
+	IP_DUMMYNET_FLUSH              = 0x3e
+	IP_DUMMYNET_GET                = 0x40
+	IP_FLOWID                      = 0x5a
+	IP_FLOWTYPE                    = 0x5b
+	IP_FW3                         = 0x30
+	IP_FW_ADD                      = 0x32
+	IP_FW_DEL                      = 0x33
+	IP_FW_FLUSH                    = 0x34
+	IP_FW_GET                      = 0x36
+	IP_FW_NAT_CFG                  = 0x38
+	IP_FW_NAT_DEL                  = 0x39
+	IP_FW_NAT_GET_CONFIG           = 0x3a
+	IP_FW_NAT_GET_LOG              = 0x3b
+	IP_FW_RESETLOG                 = 0x37
+	IP_FW_TABLE_ADD                = 0x28
+	IP_FW_TABLE_DEL                = 0x29
+	IP_FW_TABLE_FLUSH              = 0x2a
+	IP_FW_TABLE_GETSIZE            = 0x2b
+	IP_FW_TABLE_LIST               = 0x2c
+	IP_FW_ZERO                     = 0x35
+	IP_HDRINCL                     = 0x2
+	IP_IPSEC_POLICY                = 0x15
+	IP_MAXPACKET                   = 0xffff
+	IP_MAX_GROUP_SRC_FILTER        = 0x200
+	IP_MAX_MEMBERSHIPS             = 0xfff
+	IP_MAX_SOCK_MUTE_FILTER        = 0x80
+	IP_MAX_SOCK_SRC_FILTER         = 0x80
+	IP_MAX_SOURCE_FILTER           = 0x400
+	IP_MF                          = 0x2000
+	IP_MINTTL                      = 0x42
+	IP_MIN_MEMBERSHIPS             = 0x1f
+	IP_MSFILTER                    = 0x4a
+	IP_MSS                         = 0x240
+	IP_MULTICAST_IF                = 0x9
+	IP_MULTICAST_LOOP              = 0xb
+	IP_MULTICAST_TTL               = 0xa
+	IP_MULTICAST_VIF               = 0xe
+	IP_OFFMASK                     = 0x1fff
+	IP_ONESBCAST                   = 0x17
+	IP_OPTIONS                     = 0x1
+	IP_PORTRANGE                   = 0x13
+	IP_PORTRANGE_DEFAULT           = 0x0
+	IP_PORTRANGE_HIGH              = 0x1
+	IP_PORTRANGE_LOW               = 0x2
+	IP_RECVDSTADDR                 = 0x7
+	IP_RECVFLOWID                  = 0x5d
+	IP_RECVIF                      = 0x14
+	IP_RECVOPTS                    = 0x5
+	IP_RECVRETOPTS                 = 0x6
+	IP_RECVRSSBUCKETID             = 0x5e
+	IP_RECVTOS                     = 0x44
+	IP_RECVTTL                     = 0x41
+	IP_RETOPTS                     = 0x8
+	IP_RF                          = 0x8000
+	IP_RSSBUCKETID                 = 0x5c
+	IP_RSS_LISTEN_BUCKET           = 0x1a
+	IP_RSVP_OFF                    = 0x10
+	IP_RSVP_ON                     = 0xf
+	IP_RSVP_VIF_OFF                = 0x12
+	IP_RSVP_VIF_ON                 = 0x11
+	IP_SENDSRCADDR                 = 0x7
+	IP_TOS                         = 0x3
+	IP_TTL                         = 0x4
+	IP_UNBLOCK_SOURCE              = 0x49
+	ISIG                           = 0x80
+	ISTRIP                         = 0x20
+	IXANY                          = 0x800
+	IXOFF                          = 0x400
+	IXON                           = 0x200
+	LOCK_EX                        = 0x2
+	LOCK_NB                        = 0x4
+	LOCK_SH                        = 0x1
+	LOCK_UN                        = 0x8
+	MADV_AUTOSYNC                  = 0x7
+	MADV_CORE                      = 0x9
+	MADV_DONTNEED                  = 0x4
+	MADV_FREE                      = 0x5
+	MADV_NOCORE                    = 0x8
+	MADV_NORMAL                    = 0x0
+	MADV_NOSYNC                    = 0x6
+	MADV_PROTECT                   = 0xa
+	MADV_RANDOM                    = 0x1
+	MADV_SEQUENTIAL                = 0x2
+	MADV_WILLNEED                  = 0x3
+	MAP_32BIT                      = 0x80000
+	MAP_ALIGNED_SUPER              = 0x1000000
+	MAP_ALIGNMENT_MASK             = -0x1000000
+	MAP_ALIGNMENT_SHIFT            = 0x18
+	MAP_ANON                       = 0x1000
+	MAP_ANONYMOUS                  = 0x1000
+	MAP_COPY                       = 0x2
+	MAP_EXCL                       = 0x4000
+	MAP_FILE                       = 0x0
+	MAP_FIXED                      = 0x10
+	MAP_HASSEMAPHORE               = 0x200
+	MAP_NOCORE                     = 0x20000
+	MAP_NOSYNC                     = 0x800
+	MAP_PREFAULT_READ              = 0x40000
+	MAP_PRIVATE                    = 0x2
+	MAP_RESERVED0020               = 0x20
+	MAP_RESERVED0040               = 0x40
+	MAP_RESERVED0080               = 0x80
+	MAP_RESERVED0100               = 0x100
+	MAP_SHARED                     = 0x1
+	MAP_STACK                      = 0x400
+	MCL_CURRENT                    = 0x1
+	MCL_FUTURE                     = 0x2
+	MSG_CMSG_CLOEXEC               = 0x40000
+	MSG_COMPAT                     = 0x8000
+	MSG_CTRUNC                     = 0x20
+	MSG_DONTROUTE                  = 0x4
+	MSG_DONTWAIT                   = 0x80
+	MSG_EOF                        = 0x100
+	MSG_EOR                        = 0x8
+	MSG_NBIO                       = 0x4000
+	MSG_NOSIGNAL                   = 0x20000
+	MSG_NOTIFICATION               = 0x2000
+	MSG_OOB                        = 0x1
+	MSG_PEEK                       = 0x2
+	MSG_TRUNC                      = 0x10
+	MSG_WAITALL                    = 0x40
+	MSG_WAITFORONE                 = 0x80000
+	MS_ASYNC                       = 0x1
+	MS_INVALIDATE                  = 0x2
+	MS_SYNC                        = 0x0
+	NAME_MAX                       = 0xff
+	NET_RT_DUMP                    = 0x1
+	NET_RT_FLAGS                   = 0x2
+	NET_RT_IFLIST                  = 0x3
+	NET_RT_IFLISTL                 = 0x5
+	NET_RT_IFMALIST                = 0x4
+	NOFLSH                         = 0x80000000
+	NOKERNINFO                     = 0x2000000
+	NOTE_ATTRIB                    = 0x8
+	NOTE_CHILD                     = 0x4
+	NOTE_CLOSE                     = 0x100
+	NOTE_CLOSE_WRITE               = 0x200
+	NOTE_DELETE                    = 0x1
+	NOTE_EXEC                      = 0x20000000
+	NOTE_EXIT                      = 0x80000000
+	NOTE_EXTEND                    = 0x4
+	NOTE_FFAND                     = 0x40000000
+	NOTE_FFCOPY                    = 0xc0000000
+	NOTE_FFCTRLMASK                = 0xc0000000
+	NOTE_FFLAGSMASK                = 0xffffff
+	NOTE_FFNOP                     = 0x0
+	NOTE_FFOR                      = 0x80000000
+	NOTE_FILE_POLL                 = 0x2
+	NOTE_FORK                      = 0x40000000
+	NOTE_LINK                      = 0x10
+	NOTE_LOWAT                     = 0x1
+	NOTE_MSECONDS                  = 0x2
+	NOTE_NSECONDS                  = 0x8
+	NOTE_OPEN                      = 0x80
+	NOTE_PCTRLMASK                 = 0xf0000000
+	NOTE_PDATAMASK                 = 0xfffff
+	NOTE_READ                      = 0x400
+	NOTE_RENAME                    = 0x20
+	NOTE_REVOKE                    = 0x40
+	NOTE_SECONDS                   = 0x1
+	NOTE_TRACK                     = 0x1
+	NOTE_TRACKERR                  = 0x2
+	NOTE_TRIGGER                   = 0x1000000
+	NOTE_USECONDS                  = 0x4
+	NOTE_WRITE                     = 0x2
+	OCRNL                          = 0x10
+	ONLCR                          = 0x2
+	ONLRET                         = 0x40
+	ONOCR                          = 0x20
+	ONOEOT                         = 0x8
+	OPOST                          = 0x1
+	OXTABS                         = 0x4
+	O_ACCMODE                      = 0x3
+	O_APPEND                       = 0x8
+	O_ASYNC                        = 0x40
+	O_CLOEXEC                      = 0x100000
+	O_CREAT                        = 0x200
+	O_DIRECT                       = 0x10000
+	O_DIRECTORY                    = 0x20000
+	O_EXCL                         = 0x800
+	O_EXEC                         = 0x40000
+	O_EXLOCK                       = 0x20
+	O_FSYNC                        = 0x80
+	O_NDELAY                       = 0x4
+	O_NOCTTY                       = 0x8000
+	O_NOFOLLOW                     = 0x100
+	O_NONBLOCK                     = 0x4
+	O_RDONLY                       = 0x0
+	O_RDWR                         = 0x2
+	O_SHLOCK                       = 0x10
+	O_SYNC                         = 0x80
+	O_TRUNC                        = 0x400
+	O_TTY_INIT                     = 0x80000
+	O_VERIFY                       = 0x200000
+	O_WRONLY                       = 0x1
+	PARENB                         = 0x1000
+	PARMRK                         = 0x8
+	PARODD                         = 0x2000
+	PENDIN                         = 0x20000000
+	PRIO_PGRP                      = 0x1
+	PRIO_PROCESS                   = 0x0
+	PRIO_USER                      = 0x2
+	PROT_EXEC                      = 0x4
+	PROT_NONE                      = 0x0
+	PROT_READ                      = 0x1
+	PROT_WRITE                     = 0x2
+	RLIMIT_AS                      = 0xa
+	RLIMIT_CORE                    = 0x4
+	RLIMIT_CPU                     = 0x0
+	RLIMIT_DATA                    = 0x2
+	RLIMIT_FSIZE                   = 0x1
+	RLIMIT_MEMLOCK                 = 0x6
+	RLIMIT_NOFILE                  = 0x8
+	RLIMIT_NPROC                   = 0x7
+	RLIMIT_RSS                     = 0x5
+	RLIMIT_STACK                   = 0x3
+	RLIM_INFINITY                  = 0x7fffffffffffffff
+	RTAX_AUTHOR                    = 0x6
+	RTAX_BRD                       = 0x7
+	RTAX_DST                       = 0x0
+	RTAX_GATEWAY                   = 0x1
+	RTAX_GENMASK                   = 0x3
+	RTAX_IFA                       = 0x5
+	RTAX_IFP                       = 0x4
+	RTAX_MAX                       = 0x8
+	RTAX_NETMASK                   = 0x2
+	RTA_AUTHOR                     = 0x40
+	RTA_BRD                        = 0x80
+	RTA_DST                        = 0x1
+	RTA_GATEWAY                    = 0x2
+	RTA_GENMASK                    = 0x8
+	RTA_IFA                        = 0x20
+	RTA_IFP                        = 0x10
+	RTA_NETMASK                    = 0x4
+	RTF_BLACKHOLE                  = 0x1000
+	RTF_BROADCAST                  = 0x400000
+	RTF_DONE                       = 0x40
+	RTF_DYNAMIC                    = 0x10
+	RTF_FIXEDMTU                   = 0x80000
+	RTF_FMASK                      = 0x1004d808
+	RTF_GATEWAY                    = 0x2
+	RTF_GWFLAG_COMPAT              = 0x80000000
+	RTF_HOST                       = 0x4
+	RTF_LLDATA                     = 0x400
+	RTF_LLINFO                     = 0x400
+	RTF_LOCAL                      = 0x200000
+	RTF_MODIFIED                   = 0x20
+	RTF_MULTICAST                  = 0x800000
+	RTF_PINNED                     = 0x100000
+	RTF_PROTO1                     = 0x8000
+	RTF_PROTO2                     = 0x4000
+	RTF_PROTO3                     = 0x40000
+	RTF_REJECT                     = 0x8
+	RTF_RNH_LOCKED                 = 0x40000000
+	RTF_STATIC                     = 0x800
+	RTF_STICKY                     = 0x10000000
+	RTF_UP                         = 0x1
+	RTF_XRESOLVE                   = 0x200
+	RTM_ADD                        = 0x1
+	RTM_CHANGE                     = 0x3
+	RTM_DELADDR                    = 0xd
+	RTM_DELETE                     = 0x2
+	RTM_DELMADDR                   = 0x10
+	RTM_GET                        = 0x4
+	RTM_IEEE80211                  = 0x12
+	RTM_IFANNOUNCE                 = 0x11
+	RTM_IFINFO                     = 0xe
+	RTM_LOCK                       = 0x8
+	RTM_LOSING                     = 0x5
+	RTM_MISS                       = 0x7
+	RTM_NEWADDR                    = 0xc
+	RTM_NEWMADDR                   = 0xf
+	RTM_REDIRECT                   = 0x6
+	RTM_RESOLVE                    = 0xb
+	RTM_RTTUNIT                    = 0xf4240
+	RTM_VERSION                    = 0x5
+	RTV_EXPIRE                     = 0x4
+	RTV_HOPCOUNT                   = 0x2
+	RTV_MTU                        = 0x1
+	RTV_RPIPE                      = 0x8
+	RTV_RTT                        = 0x40
+	RTV_RTTVAR                     = 0x80
+	RTV_SPIPE                      = 0x10
+	RTV_SSTHRESH                   = 0x20
+	RTV_WEIGHT                     = 0x100
+	RT_ALL_FIBS                    = -0x1
+	RT_BLACKHOLE                   = 0x40
+	RT_CACHING_CONTEXT             = 0x1
+	RT_DEFAULT_FIB                 = 0x0
+	RT_HAS_GW                      = 0x80
+	RT_HAS_HEADER                  = 0x10
+	RT_HAS_HEADER_BIT              = 0x4
+	RT_L2_ME                       = 0x4
+	RT_L2_ME_BIT                   = 0x2
+	RT_LLE_CACHE                   = 0x100
+	RT_MAY_LOOP                    = 0x8
+	RT_MAY_LOOP_BIT                = 0x3
+	RT_NORTREF                     = 0x2
+	RT_REJECT                      = 0x20
+	RUSAGE_CHILDREN                = -0x1
+	RUSAGE_SELF                    = 0x0
+	RUSAGE_THREAD                  = 0x1
+	SCM_BINTIME                    = 0x4
+	SCM_CREDS                      = 0x3
+	SCM_RIGHTS                     = 0x1
+	SCM_TIMESTAMP                  = 0x2
+	SHUT_RD                        = 0x0
+	SHUT_RDWR                      = 0x2
+	SHUT_WR                        = 0x1
+	SIOCADDMULTI                   = 0x80206931
+	SIOCAIFADDR                    = 0x8040691a
+	SIOCAIFGROUP                   = 0x80286987
+	SIOCATMARK                     = 0x40047307
+	SIOCDELMULTI                   = 0x80206932
+	SIOCDIFADDR                    = 0x80206919
+	SIOCDIFGROUP                   = 0x80286989
+	SIOCDIFPHYADDR                 = 0x80206949
+	SIOCGDRVSPEC                   = 0xc028697b
+	SIOCGETSGCNT                   = 0xc0207210
+	SIOCGETVIFCNT                  = 0xc028720f
+	SIOCGHIWAT                     = 0x40047301
+	SIOCGI2C                       = 0xc020693d
+	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFBRDADDR                 = 0xc0206923
+	SIOCGIFCAP                     = 0xc020691f
+	SIOCGIFCONF                    = 0xc0106924
+	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDSTADDR                 = 0xc0206922
+	SIOCGIFFIB                     = 0xc020695c
+	SIOCGIFFLAGS                   = 0xc0206911
+	SIOCGIFGENERIC                 = 0xc020693a
+	SIOCGIFGMEMB                   = 0xc028698a
+	SIOCGIFGROUP                   = 0xc0286988
+	SIOCGIFINDEX                   = 0xc0206920
+	SIOCGIFMAC                     = 0xc0206926
+	SIOCGIFMEDIA                   = 0xc0306938
+	SIOCGIFMETRIC                  = 0xc0206917
+	SIOCGIFMTU                     = 0xc0206933
+	SIOCGIFNETMASK                 = 0xc0206925
+	SIOCGIFPDSTADDR                = 0xc0206948
+	SIOCGIFPHYS                    = 0xc0206935
+	SIOCGIFPSRCADDR                = 0xc0206947
+	SIOCGIFSTATUS                  = 0xc331693b
+	SIOCGIFXMEDIA                  = 0xc030698b
+	SIOCGLOWAT                     = 0x40047303
+	SIOCGPGRP                      = 0x40047309
+	SIOCGPRIVATE_0                 = 0xc0206950
+	SIOCGPRIVATE_1                 = 0xc0206951
+	SIOCGTUNFIB                    = 0xc020695e
+	SIOCIFCREATE                   = 0xc020697a
+	SIOCIFCREATE2                  = 0xc020697c
+	SIOCIFDESTROY                  = 0x80206979
+	SIOCIFGCLONERS                 = 0xc0106978
+	SIOCSDRVSPEC                   = 0x8028697b
+	SIOCSHIWAT                     = 0x80047300
+	SIOCSIFADDR                    = 0x8020690c
+	SIOCSIFBRDADDR                 = 0x80206913
+	SIOCSIFCAP                     = 0x8020691e
+	SIOCSIFDESCR                   = 0x80206929
+	SIOCSIFDSTADDR                 = 0x8020690e
+	SIOCSIFFIB                     = 0x8020695d
+	SIOCSIFFLAGS                   = 0x80206910
+	SIOCSIFGENERIC                 = 0x80206939
+	SIOCSIFLLADDR                  = 0x8020693c
+	SIOCSIFMAC                     = 0x80206927
+	SIOCSIFMEDIA                   = 0xc0206937
+	SIOCSIFMETRIC                  = 0x80206918
+	SIOCSIFMTU                     = 0x80206934
+	SIOCSIFNAME                    = 0x80206928
+	SIOCSIFNETMASK                 = 0x80206916
+	SIOCSIFPHYADDR                 = 0x80406946
+	SIOCSIFPHYS                    = 0x80206936
+	SIOCSIFRVNET                   = 0xc020695b
+	SIOCSIFVNET                    = 0xc020695a
+	SIOCSLOWAT                     = 0x80047302
+	SIOCSPGRP                      = 0x80047308
+	SIOCSTUNFIB                    = 0x8020695f
+	SOCK_CLOEXEC                   = 0x10000000
+	SOCK_DGRAM                     = 0x2
+	SOCK_MAXADDRLEN                = 0xff
+	SOCK_NONBLOCK                  = 0x20000000
+	SOCK_RAW                       = 0x3
+	SOCK_RDM                       = 0x4
+	SOCK_SEQPACKET                 = 0x5
+	SOCK_STREAM                    = 0x1
+	SOL_SOCKET                     = 0xffff
+	SOMAXCONN                      = 0x80
+	SO_ACCEPTCONN                  = 0x2
+	SO_ACCEPTFILTER                = 0x1000
+	SO_BINTIME                     = 0x2000
+	SO_BROADCAST                   = 0x20
+	SO_DEBUG                       = 0x1
+	SO_DONTROUTE                   = 0x10
+	SO_ERROR                       = 0x1007
+	SO_KEEPALIVE                   = 0x8
+	SO_LABEL                       = 0x1009
+	SO_LINGER                      = 0x80
+	SO_LISTENINCQLEN               = 0x1013
+	SO_LISTENQLEN                  = 0x1012
+	SO_LISTENQLIMIT                = 0x1011
+	SO_NOSIGPIPE                   = 0x800
+	SO_NO_DDP                      = 0x8000
+	SO_NO_OFFLOAD                  = 0x4000
+	SO_OOBINLINE                   = 0x100
+	SO_PEERLABEL                   = 0x1010
+	SO_PROTOCOL                    = 0x1016
+	SO_PROTOTYPE                   = 0x1016
+	SO_RCVBUF                      = 0x1002
+	SO_RCVLOWAT                    = 0x1004
+	SO_RCVTIMEO                    = 0x1006
+	SO_REUSEADDR                   = 0x4
+	SO_REUSEPORT                   = 0x200
+	SO_SETFIB                      = 0x1014
+	SO_SNDBUF                      = 0x1001
+	SO_SNDLOWAT                    = 0x1003
+	SO_SNDTIMEO                    = 0x1005
+	SO_TIMESTAMP                   = 0x400
+	SO_TYPE                        = 0x1008
+	SO_USELOOPBACK                 = 0x40
+	SO_USER_COOKIE                 = 0x1015
+	SO_VENDOR                      = 0x80000000
+	TAB0                           = 0x0
+	TAB3                           = 0x4
+	TABDLY                         = 0x4
+	TCIFLUSH                       = 0x1
+	TCIOFF                         = 0x3
+	TCIOFLUSH                      = 0x3
+	TCION                          = 0x4
+	TCOFLUSH                       = 0x2
+	TCOOFF                         = 0x1
+	TCOON                          = 0x2
+	TCP_CA_NAME_MAX                = 0x10
+	TCP_CCALGOOPT                  = 0x41
+	TCP_CONGESTION                 = 0x40
+	TCP_FASTOPEN                   = 0x401
+	TCP_FUNCTION_BLK               = 0x2000
+	TCP_FUNCTION_NAME_LEN_MAX      = 0x20
+	TCP_INFO                       = 0x20
+	TCP_KEEPCNT                    = 0x400
+	TCP_KEEPIDLE                   = 0x100
+	TCP_KEEPINIT                   = 0x80
+	TCP_KEEPINTVL                  = 0x200
+	TCP_MAXBURST                   = 0x4
+	TCP_MAXHLEN                    = 0x3c
+	TCP_MAXOLEN                    = 0x28
+	TCP_MAXSEG                     = 0x2
+	TCP_MAXWIN                     = 0xffff
+	TCP_MAX_SACK                   = 0x4
+	TCP_MAX_WINSHIFT               = 0xe
+	TCP_MD5SIG                     = 0x10
+	TCP_MINMSS                     = 0xd8
+	TCP_MSS                        = 0x218
+	TCP_NODELAY                    = 0x1
+	TCP_NOOPT                      = 0x8
+	TCP_NOPUSH                     = 0x4
+	TCP_PCAP_IN                    = 0x1000
+	TCP_PCAP_OUT                   = 0x800
+	TCP_VENDOR                     = 0x80000000
+	TCSAFLUSH                      = 0x2
+	TIOCCBRK                       = 0x2000747a
+	TIOCCDTR                       = 0x20007478
+	TIOCCONS                       = 0x80047462
+	TIOCDRAIN                      = 0x2000745e
+	TIOCEXCL                       = 0x2000740d
+	TIOCEXT                        = 0x80047460
+	TIOCFLUSH                      = 0x80047410
+	TIOCGDRAINWAIT                 = 0x40047456
+	TIOCGETA                       = 0x402c7413
+	TIOCGETD                       = 0x4004741a
+	TIOCGPGRP                      = 0x40047477
+	TIOCGPTN                       = 0x4004740f
+	TIOCGSID                       = 0x40047463
+	TIOCGWINSZ                     = 0x40087468
+	TIOCMBIC                       = 0x8004746b
+	TIOCMBIS                       = 0x8004746c
+	TIOCMGDTRWAIT                  = 0x4004745a
+	TIOCMGET                       = 0x4004746a
+	TIOCMSDTRWAIT                  = 0x8004745b
+	TIOCMSET                       = 0x8004746d
+	TIOCM_CAR                      = 0x40
+	TIOCM_CD                       = 0x40
+	TIOCM_CTS                      = 0x20
+	TIOCM_DCD                      = 0x40
+	TIOCM_DSR                      = 0x100
+	TIOCM_DTR                      = 0x2
+	TIOCM_LE                       = 0x1
+	TIOCM_RI                       = 0x80
+	TIOCM_RNG                      = 0x80
+	TIOCM_RTS                      = 0x4
+	TIOCM_SR                       = 0x10
+	TIOCM_ST                       = 0x8
+	TIOCNOTTY                      = 0x20007471
+	TIOCNXCL                       = 0x2000740e
+	TIOCOUTQ                       = 0x40047473
+	TIOCPKT                        = 0x80047470
+	TIOCPKT_DATA                   = 0x0
+	TIOCPKT_DOSTOP                 = 0x20
+	TIOCPKT_FLUSHREAD              = 0x1
+	TIOCPKT_FLUSHWRITE             = 0x2
+	TIOCPKT_IOCTL                  = 0x40
+	TIOCPKT_NOSTOP                 = 0x10
+	TIOCPKT_START                  = 0x8
+	TIOCPKT_STOP                   = 0x4
+	TIOCPTMASTER                   = 0x2000741c
+	TIOCSBRK                       = 0x2000747b
+	TIOCSCTTY                      = 0x20007461
+	TIOCSDRAINWAIT                 = 0x80047457
+	TIOCSDTR                       = 0x20007479
+	TIOCSETA                       = 0x802c7414
+	TIOCSETAF                      = 0x802c7416
+	TIOCSETAW                      = 0x802c7415
+	TIOCSETD                       = 0x8004741b
+	TIOCSIG                        = 0x2004745f
+	TIOCSPGRP                      = 0x80047476
+	TIOCSTART                      = 0x2000746e
+	TIOCSTAT                       = 0x20007465
+	TIOCSTI                        = 0x80017472
+	TIOCSTOP                       = 0x2000746f
+	TIOCSWINSZ                     = 0x80087467
+	TIOCTIMESTAMP                  = 0x40107459
+	TIOCUCNTL                      = 0x80047466
+	TOSTOP                         = 0x400000
+	VDISCARD                       = 0xf
+	VDSUSP                         = 0xb
+	VEOF                           = 0x0
+	VEOL                           = 0x1
+	VEOL2                          = 0x2
+	VERASE                         = 0x3
+	VERASE2                        = 0x7
+	VINTR                          = 0x8
+	VKILL                          = 0x5
+	VLNEXT                         = 0xe
+	VMIN                           = 0x10
+	VQUIT                          = 0x9
+	VREPRINT                       = 0x6
+	VSTART                         = 0xc
+	VSTATUS                        = 0x12
+	VSTOP                          = 0xd
+	VSUSP                          = 0xa
+	VTIME                          = 0x11
+	VWERASE                        = 0x4
+	WCONTINUED                     = 0x4
+	WCOREFLAG                      = 0x80
+	WEXITED                        = 0x10
+	WLINUXCLONE                    = 0x80000000
+	WNOHANG                        = 0x1
+	WNOWAIT                        = 0x8
+	WSTOPPED                       = 0x2
+	WTRAPPED                       = 0x20
+	WUNTRACED                      = 0x2
 )
 
 // Errors
diff --git a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
index 2afbe2d..c5c6f13 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
@@ -1,5 +1,5 @@
 // mkerrors.sh
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build arm,freebsd
 
@@ -11,1442 +11,1428 @@
 import "syscall"
 
 const (
-	AF_APPLETALK                      = 0x10
-	AF_ARP                            = 0x23
-	AF_ATM                            = 0x1e
-	AF_BLUETOOTH                      = 0x24
-	AF_CCITT                          = 0xa
-	AF_CHAOS                          = 0x5
-	AF_CNT                            = 0x15
-	AF_COIP                           = 0x14
-	AF_DATAKIT                        = 0x9
-	AF_DECnet                         = 0xc
-	AF_DLI                            = 0xd
-	AF_E164                           = 0x1a
-	AF_ECMA                           = 0x8
-	AF_HYLINK                         = 0xf
-	AF_IEEE80211                      = 0x25
-	AF_IMPLINK                        = 0x3
-	AF_INET                           = 0x2
-	AF_INET6                          = 0x1c
-	AF_INET6_SDP                      = 0x2a
-	AF_INET_SDP                       = 0x28
-	AF_IPX                            = 0x17
-	AF_ISDN                           = 0x1a
-	AF_ISO                            = 0x7
-	AF_LAT                            = 0xe
-	AF_LINK                           = 0x12
-	AF_LOCAL                          = 0x1
-	AF_MAX                            = 0x2a
-	AF_NATM                           = 0x1d
-	AF_NETBIOS                        = 0x6
-	AF_NETGRAPH                       = 0x20
-	AF_OSI                            = 0x7
-	AF_PUP                            = 0x4
-	AF_ROUTE                          = 0x11
-	AF_SCLUSTER                       = 0x22
-	AF_SIP                            = 0x18
-	AF_SLOW                           = 0x21
-	AF_SNA                            = 0xb
-	AF_UNIX                           = 0x1
-	AF_UNSPEC                         = 0x0
-	AF_VENDOR00                       = 0x27
-	AF_VENDOR01                       = 0x29
-	AF_VENDOR02                       = 0x2b
-	AF_VENDOR03                       = 0x2d
-	AF_VENDOR04                       = 0x2f
-	AF_VENDOR05                       = 0x31
-	AF_VENDOR06                       = 0x33
-	AF_VENDOR07                       = 0x35
-	AF_VENDOR08                       = 0x37
-	AF_VENDOR09                       = 0x39
-	AF_VENDOR10                       = 0x3b
-	AF_VENDOR11                       = 0x3d
-	AF_VENDOR12                       = 0x3f
-	AF_VENDOR13                       = 0x41
-	AF_VENDOR14                       = 0x43
-	AF_VENDOR15                       = 0x45
-	AF_VENDOR16                       = 0x47
-	AF_VENDOR17                       = 0x49
-	AF_VENDOR18                       = 0x4b
-	AF_VENDOR19                       = 0x4d
-	AF_VENDOR20                       = 0x4f
-	AF_VENDOR21                       = 0x51
-	AF_VENDOR22                       = 0x53
-	AF_VENDOR23                       = 0x55
-	AF_VENDOR24                       = 0x57
-	AF_VENDOR25                       = 0x59
-	AF_VENDOR26                       = 0x5b
-	AF_VENDOR27                       = 0x5d
-	AF_VENDOR28                       = 0x5f
-	AF_VENDOR29                       = 0x61
-	AF_VENDOR30                       = 0x63
-	AF_VENDOR31                       = 0x65
-	AF_VENDOR32                       = 0x67
-	AF_VENDOR33                       = 0x69
-	AF_VENDOR34                       = 0x6b
-	AF_VENDOR35                       = 0x6d
-	AF_VENDOR36                       = 0x6f
-	AF_VENDOR37                       = 0x71
-	AF_VENDOR38                       = 0x73
-	AF_VENDOR39                       = 0x75
-	AF_VENDOR40                       = 0x77
-	AF_VENDOR41                       = 0x79
-	AF_VENDOR42                       = 0x7b
-	AF_VENDOR43                       = 0x7d
-	AF_VENDOR44                       = 0x7f
-	AF_VENDOR45                       = 0x81
-	AF_VENDOR46                       = 0x83
-	AF_VENDOR47                       = 0x85
-	B0                                = 0x0
-	B110                              = 0x6e
-	B115200                           = 0x1c200
-	B1200                             = 0x4b0
-	B134                              = 0x86
-	B14400                            = 0x3840
-	B150                              = 0x96
-	B1800                             = 0x708
-	B19200                            = 0x4b00
-	B200                              = 0xc8
-	B230400                           = 0x38400
-	B2400                             = 0x960
-	B28800                            = 0x7080
-	B300                              = 0x12c
-	B38400                            = 0x9600
-	B460800                           = 0x70800
-	B4800                             = 0x12c0
-	B50                               = 0x32
-	B57600                            = 0xe100
-	B600                              = 0x258
-	B7200                             = 0x1c20
-	B75                               = 0x4b
-	B76800                            = 0x12c00
-	B921600                           = 0xe1000
-	B9600                             = 0x2580
-	BIOCFEEDBACK                      = 0x8004427c
-	BIOCFLUSH                         = 0x20004268
-	BIOCGBLEN                         = 0x40044266
-	BIOCGDIRECTION                    = 0x40044276
-	BIOCGDLT                          = 0x4004426a
-	BIOCGDLTLIST                      = 0xc0084279
-	BIOCGETBUFMODE                    = 0x4004427d
-	BIOCGETIF                         = 0x4020426b
-	BIOCGETZMAX                       = 0x4004427f
-	BIOCGHDRCMPLT                     = 0x40044274
-	BIOCGRSIG                         = 0x40044272
-	BIOCGRTIMEOUT                     = 0x4008426e
-	BIOCGSEESENT                      = 0x40044276
-	BIOCGSTATS                        = 0x4008426f
-	BIOCGTSTAMP                       = 0x40044283
-	BIOCIMMEDIATE                     = 0x80044270
-	BIOCLOCK                          = 0x2000427a
-	BIOCPROMISC                       = 0x20004269
-	BIOCROTZBUF                       = 0x400c4280
-	BIOCSBLEN                         = 0xc0044266
-	BIOCSDIRECTION                    = 0x80044277
-	BIOCSDLT                          = 0x80044278
-	BIOCSETBUFMODE                    = 0x8004427e
-	BIOCSETF                          = 0x80084267
-	BIOCSETFNR                        = 0x80084282
-	BIOCSETIF                         = 0x8020426c
-	BIOCSETWF                         = 0x8008427b
-	BIOCSETZBUF                       = 0x800c4281
-	BIOCSHDRCMPLT                     = 0x80044275
-	BIOCSRSIG                         = 0x80044273
-	BIOCSRTIMEOUT                     = 0x8008426d
-	BIOCSSEESENT                      = 0x80044277
-	BIOCSTSTAMP                       = 0x80044284
-	BIOCVERSION                       = 0x40044271
-	BPF_A                             = 0x10
-	BPF_ABS                           = 0x20
-	BPF_ADD                           = 0x0
-	BPF_ALIGNMENT                     = 0x4
-	BPF_ALU                           = 0x4
-	BPF_AND                           = 0x50
-	BPF_B                             = 0x10
-	BPF_BUFMODE_BUFFER                = 0x1
-	BPF_BUFMODE_ZBUF                  = 0x2
-	BPF_DIV                           = 0x30
-	BPF_H                             = 0x8
-	BPF_IMM                           = 0x0
-	BPF_IND                           = 0x40
-	BPF_JA                            = 0x0
-	BPF_JEQ                           = 0x10
-	BPF_JGE                           = 0x30
-	BPF_JGT                           = 0x20
-	BPF_JMP                           = 0x5
-	BPF_JSET                          = 0x40
-	BPF_K                             = 0x0
-	BPF_LD                            = 0x0
-	BPF_LDX                           = 0x1
-	BPF_LEN                           = 0x80
-	BPF_LSH                           = 0x60
-	BPF_MAJOR_VERSION                 = 0x1
-	BPF_MAXBUFSIZE                    = 0x80000
-	BPF_MAXINSNS                      = 0x200
-	BPF_MEM                           = 0x60
-	BPF_MEMWORDS                      = 0x10
-	BPF_MINBUFSIZE                    = 0x20
-	BPF_MINOR_VERSION                 = 0x1
-	BPF_MISC                          = 0x7
-	BPF_MSH                           = 0xa0
-	BPF_MUL                           = 0x20
-	BPF_NEG                           = 0x80
-	BPF_OR                            = 0x40
-	BPF_RELEASE                       = 0x30bb6
-	BPF_RET                           = 0x6
-	BPF_RSH                           = 0x70
-	BPF_ST                            = 0x2
-	BPF_STX                           = 0x3
-	BPF_SUB                           = 0x10
-	BPF_TAX                           = 0x0
-	BPF_TXA                           = 0x80
-	BPF_T_BINTIME                     = 0x2
-	BPF_T_BINTIME_FAST                = 0x102
-	BPF_T_BINTIME_MONOTONIC           = 0x202
-	BPF_T_BINTIME_MONOTONIC_FAST      = 0x302
-	BPF_T_FAST                        = 0x100
-	BPF_T_FLAG_MASK                   = 0x300
-	BPF_T_FORMAT_MASK                 = 0x3
-	BPF_T_MICROTIME                   = 0x0
-	BPF_T_MICROTIME_FAST              = 0x100
-	BPF_T_MICROTIME_MONOTONIC         = 0x200
-	BPF_T_MICROTIME_MONOTONIC_FAST    = 0x300
-	BPF_T_MONOTONIC                   = 0x200
-	BPF_T_MONOTONIC_FAST              = 0x300
-	BPF_T_NANOTIME                    = 0x1
-	BPF_T_NANOTIME_FAST               = 0x101
-	BPF_T_NANOTIME_MONOTONIC          = 0x201
-	BPF_T_NANOTIME_MONOTONIC_FAST     = 0x301
-	BPF_T_NONE                        = 0x3
-	BPF_T_NORMAL                      = 0x0
-	BPF_W                             = 0x0
-	BPF_X                             = 0x8
-	BRKINT                            = 0x2
-	CFLUSH                            = 0xf
-	CLOCAL                            = 0x8000
-	CREAD                             = 0x800
-	CS5                               = 0x0
-	CS6                               = 0x100
-	CS7                               = 0x200
-	CS8                               = 0x300
-	CSIZE                             = 0x300
-	CSTART                            = 0x11
-	CSTATUS                           = 0x14
-	CSTOP                             = 0x13
-	CSTOPB                            = 0x400
-	CSUSP                             = 0x1a
-	CTL_MAXNAME                       = 0x18
-	CTL_NET                           = 0x4
-	DLT_A429                          = 0xb8
-	DLT_A653_ICM                      = 0xb9
-	DLT_AIRONET_HEADER                = 0x78
-	DLT_AOS                           = 0xde
-	DLT_APPLE_IP_OVER_IEEE1394        = 0x8a
-	DLT_ARCNET                        = 0x7
-	DLT_ARCNET_LINUX                  = 0x81
-	DLT_ATM_CLIP                      = 0x13
-	DLT_ATM_RFC1483                   = 0xb
-	DLT_AURORA                        = 0x7e
-	DLT_AX25                          = 0x3
-	DLT_AX25_KISS                     = 0xca
-	DLT_BACNET_MS_TP                  = 0xa5
-	DLT_BLUETOOTH_HCI_H4              = 0xbb
-	DLT_BLUETOOTH_HCI_H4_WITH_PHDR    = 0xc9
-	DLT_CAN20B                        = 0xbe
-	DLT_CAN_SOCKETCAN                 = 0xe3
-	DLT_CHAOS                         = 0x5
-	DLT_CHDLC                         = 0x68
-	DLT_CISCO_IOS                     = 0x76
-	DLT_C_HDLC                        = 0x68
-	DLT_C_HDLC_WITH_DIR               = 0xcd
-	DLT_DBUS                          = 0xe7
-	DLT_DECT                          = 0xdd
-	DLT_DOCSIS                        = 0x8f
-	DLT_DVB_CI                        = 0xeb
-	DLT_ECONET                        = 0x73
-	DLT_EN10MB                        = 0x1
-	DLT_EN3MB                         = 0x2
-	DLT_ENC                           = 0x6d
-	DLT_ERF                           = 0xc5
-	DLT_ERF_ETH                       = 0xaf
-	DLT_ERF_POS                       = 0xb0
-	DLT_FC_2                          = 0xe0
-	DLT_FC_2_WITH_FRAME_DELIMS        = 0xe1
-	DLT_FDDI                          = 0xa
-	DLT_FLEXRAY                       = 0xd2
-	DLT_FRELAY                        = 0x6b
-	DLT_FRELAY_WITH_DIR               = 0xce
-	DLT_GCOM_SERIAL                   = 0xad
-	DLT_GCOM_T1E1                     = 0xac
-	DLT_GPF_F                         = 0xab
-	DLT_GPF_T                         = 0xaa
-	DLT_GPRS_LLC                      = 0xa9
-	DLT_GSMTAP_ABIS                   = 0xda
-	DLT_GSMTAP_UM                     = 0xd9
-	DLT_HHDLC                         = 0x79
-	DLT_IBM_SN                        = 0x92
-	DLT_IBM_SP                        = 0x91
-	DLT_IEEE802                       = 0x6
-	DLT_IEEE802_11                    = 0x69
-	DLT_IEEE802_11_RADIO              = 0x7f
-	DLT_IEEE802_11_RADIO_AVS          = 0xa3
-	DLT_IEEE802_15_4                  = 0xc3
-	DLT_IEEE802_15_4_LINUX            = 0xbf
-	DLT_IEEE802_15_4_NOFCS            = 0xe6
-	DLT_IEEE802_15_4_NONASK_PHY       = 0xd7
-	DLT_IEEE802_16_MAC_CPS            = 0xbc
-	DLT_IEEE802_16_MAC_CPS_RADIO      = 0xc1
-	DLT_IPFILTER                      = 0x74
-	DLT_IPMB                          = 0xc7
-	DLT_IPMB_LINUX                    = 0xd1
-	DLT_IPNET                         = 0xe2
-	DLT_IPOIB                         = 0xf2
-	DLT_IPV4                          = 0xe4
-	DLT_IPV6                          = 0xe5
-	DLT_IP_OVER_FC                    = 0x7a
-	DLT_JUNIPER_ATM1                  = 0x89
-	DLT_JUNIPER_ATM2                  = 0x87
-	DLT_JUNIPER_ATM_CEMIC             = 0xee
-	DLT_JUNIPER_CHDLC                 = 0xb5
-	DLT_JUNIPER_ES                    = 0x84
-	DLT_JUNIPER_ETHER                 = 0xb2
-	DLT_JUNIPER_FIBRECHANNEL          = 0xea
-	DLT_JUNIPER_FRELAY                = 0xb4
-	DLT_JUNIPER_GGSN                  = 0x85
-	DLT_JUNIPER_ISM                   = 0xc2
-	DLT_JUNIPER_MFR                   = 0x86
-	DLT_JUNIPER_MLFR                  = 0x83
-	DLT_JUNIPER_MLPPP                 = 0x82
-	DLT_JUNIPER_MONITOR               = 0xa4
-	DLT_JUNIPER_PIC_PEER              = 0xae
-	DLT_JUNIPER_PPP                   = 0xb3
-	DLT_JUNIPER_PPPOE                 = 0xa7
-	DLT_JUNIPER_PPPOE_ATM             = 0xa8
-	DLT_JUNIPER_SERVICES              = 0x88
-	DLT_JUNIPER_SRX_E2E               = 0xe9
-	DLT_JUNIPER_ST                    = 0xc8
-	DLT_JUNIPER_VP                    = 0xb7
-	DLT_JUNIPER_VS                    = 0xe8
-	DLT_LAPB_WITH_DIR                 = 0xcf
-	DLT_LAPD                          = 0xcb
-	DLT_LIN                           = 0xd4
-	DLT_LINUX_EVDEV                   = 0xd8
-	DLT_LINUX_IRDA                    = 0x90
-	DLT_LINUX_LAPD                    = 0xb1
-	DLT_LINUX_PPP_WITHDIRECTION       = 0xa6
-	DLT_LINUX_SLL                     = 0x71
-	DLT_LOOP                          = 0x6c
-	DLT_LTALK                         = 0x72
-	DLT_MATCHING_MAX                  = 0xf6
-	DLT_MATCHING_MIN                  = 0x68
-	DLT_MFR                           = 0xb6
-	DLT_MOST                          = 0xd3
-	DLT_MPEG_2_TS                     = 0xf3
-	DLT_MPLS                          = 0xdb
-	DLT_MTP2                          = 0x8c
-	DLT_MTP2_WITH_PHDR                = 0x8b
-	DLT_MTP3                          = 0x8d
-	DLT_MUX27010                      = 0xec
-	DLT_NETANALYZER                   = 0xf0
-	DLT_NETANALYZER_TRANSPARENT       = 0xf1
-	DLT_NFC_LLCP                      = 0xf5
-	DLT_NFLOG                         = 0xef
-	DLT_NG40                          = 0xf4
-	DLT_NULL                          = 0x0
-	DLT_PCI_EXP                       = 0x7d
-	DLT_PFLOG                         = 0x75
-	DLT_PFSYNC                        = 0x79
-	DLT_PPI                           = 0xc0
-	DLT_PPP                           = 0x9
-	DLT_PPP_BSDOS                     = 0x10
-	DLT_PPP_ETHER                     = 0x33
-	DLT_PPP_PPPD                      = 0xa6
-	DLT_PPP_SERIAL                    = 0x32
-	DLT_PPP_WITH_DIR                  = 0xcc
-	DLT_PPP_WITH_DIRECTION            = 0xa6
-	DLT_PRISM_HEADER                  = 0x77
-	DLT_PRONET                        = 0x4
-	DLT_RAIF1                         = 0xc6
-	DLT_RAW                           = 0xc
-	DLT_RIO                           = 0x7c
-	DLT_SCCP                          = 0x8e
-	DLT_SITA                          = 0xc4
-	DLT_SLIP                          = 0x8
-	DLT_SLIP_BSDOS                    = 0xf
-	DLT_STANAG_5066_D_PDU             = 0xed
-	DLT_SUNATM                        = 0x7b
-	DLT_SYMANTEC_FIREWALL             = 0x63
-	DLT_TZSP                          = 0x80
-	DLT_USB                           = 0xba
-	DLT_USB_LINUX                     = 0xbd
-	DLT_USB_LINUX_MMAPPED             = 0xdc
-	DLT_USER0                         = 0x93
-	DLT_USER1                         = 0x94
-	DLT_USER10                        = 0x9d
-	DLT_USER11                        = 0x9e
-	DLT_USER12                        = 0x9f
-	DLT_USER13                        = 0xa0
-	DLT_USER14                        = 0xa1
-	DLT_USER15                        = 0xa2
-	DLT_USER2                         = 0x95
-	DLT_USER3                         = 0x96
-	DLT_USER4                         = 0x97
-	DLT_USER5                         = 0x98
-	DLT_USER6                         = 0x99
-	DLT_USER7                         = 0x9a
-	DLT_USER8                         = 0x9b
-	DLT_USER9                         = 0x9c
-	DLT_WIHART                        = 0xdf
-	DLT_X2E_SERIAL                    = 0xd5
-	DLT_X2E_XORAYA                    = 0xd6
-	DT_BLK                            = 0x6
-	DT_CHR                            = 0x2
-	DT_DIR                            = 0x4
-	DT_FIFO                           = 0x1
-	DT_LNK                            = 0xa
-	DT_REG                            = 0x8
-	DT_SOCK                           = 0xc
-	DT_UNKNOWN                        = 0x0
-	DT_WHT                            = 0xe
-	ECHO                              = 0x8
-	ECHOCTL                           = 0x40
-	ECHOE                             = 0x2
-	ECHOK                             = 0x4
-	ECHOKE                            = 0x1
-	ECHONL                            = 0x10
-	ECHOPRT                           = 0x20
-	EVFILT_AIO                        = -0x3
-	EVFILT_FS                         = -0x9
-	EVFILT_LIO                        = -0xa
-	EVFILT_PROC                       = -0x5
-	EVFILT_READ                       = -0x1
-	EVFILT_SIGNAL                     = -0x6
-	EVFILT_SYSCOUNT                   = 0xb
-	EVFILT_TIMER                      = -0x7
-	EVFILT_USER                       = -0xb
-	EVFILT_VNODE                      = -0x4
-	EVFILT_WRITE                      = -0x2
-	EV_ADD                            = 0x1
-	EV_CLEAR                          = 0x20
-	EV_DELETE                         = 0x2
-	EV_DISABLE                        = 0x8
-	EV_DISPATCH                       = 0x80
-	EV_DROP                           = 0x1000
-	EV_ENABLE                         = 0x4
-	EV_EOF                            = 0x8000
-	EV_ERROR                          = 0x4000
-	EV_FLAG1                          = 0x2000
-	EV_ONESHOT                        = 0x10
-	EV_RECEIPT                        = 0x40
-	EV_SYSFLAGS                       = 0xf000
-	EXTA                              = 0x4b00
-	EXTATTR_NAMESPACE_EMPTY           = 0x0
-	EXTATTR_NAMESPACE_SYSTEM          = 0x2
-	EXTATTR_NAMESPACE_USER            = 0x1
-	EXTB                              = 0x9600
-	EXTPROC                           = 0x800
-	FD_CLOEXEC                        = 0x1
-	FD_SETSIZE                        = 0x400
-	FLUSHO                            = 0x800000
-	F_CANCEL                          = 0x5
-	F_DUP2FD                          = 0xa
-	F_DUP2FD_CLOEXEC                  = 0x12
-	F_DUPFD                           = 0x0
-	F_DUPFD_CLOEXEC                   = 0x11
-	F_GETFD                           = 0x1
-	F_GETFL                           = 0x3
-	F_GETLK                           = 0xb
-	F_GETOWN                          = 0x5
-	F_OGETLK                          = 0x7
-	F_OK                              = 0x0
-	F_OSETLK                          = 0x8
-	F_OSETLKW                         = 0x9
-	F_RDAHEAD                         = 0x10
-	F_RDLCK                           = 0x1
-	F_READAHEAD                       = 0xf
-	F_SETFD                           = 0x2
-	F_SETFL                           = 0x4
-	F_SETLK                           = 0xc
-	F_SETLKW                          = 0xd
-	F_SETLK_REMOTE                    = 0xe
-	F_SETOWN                          = 0x6
-	F_UNLCK                           = 0x2
-	F_UNLCKSYS                        = 0x4
-	F_WRLCK                           = 0x3
-	HUPCL                             = 0x4000
-	ICANON                            = 0x100
-	ICMP6_FILTER                      = 0x12
-	ICRNL                             = 0x100
-	IEXTEN                            = 0x400
-	IFAN_ARRIVAL                      = 0x0
-	IFAN_DEPARTURE                    = 0x1
-	IFF_ALLMULTI                      = 0x200
-	IFF_ALTPHYS                       = 0x4000
-	IFF_BROADCAST                     = 0x2
-	IFF_CANTCHANGE                    = 0x218f72
-	IFF_CANTCONFIG                    = 0x10000
-	IFF_DEBUG                         = 0x4
-	IFF_DRV_OACTIVE                   = 0x400
-	IFF_DRV_RUNNING                   = 0x40
-	IFF_DYING                         = 0x200000
-	IFF_LINK0                         = 0x1000
-	IFF_LINK1                         = 0x2000
-	IFF_LINK2                         = 0x4000
-	IFF_LOOPBACK                      = 0x8
-	IFF_MONITOR                       = 0x40000
-	IFF_MULTICAST                     = 0x8000
-	IFF_NOARP                         = 0x80
-	IFF_OACTIVE                       = 0x400
-	IFF_POINTOPOINT                   = 0x10
-	IFF_PPROMISC                      = 0x20000
-	IFF_PROMISC                       = 0x100
-	IFF_RENAMING                      = 0x400000
-	IFF_RUNNING                       = 0x40
-	IFF_SIMPLEX                       = 0x800
-	IFF_SMART                         = 0x20
-	IFF_STATICARP                     = 0x80000
-	IFF_UP                            = 0x1
-	IFNAMSIZ                          = 0x10
-	IFT_1822                          = 0x2
-	IFT_A12MPPSWITCH                  = 0x82
-	IFT_AAL2                          = 0xbb
-	IFT_AAL5                          = 0x31
-	IFT_ADSL                          = 0x5e
-	IFT_AFLANE8023                    = 0x3b
-	IFT_AFLANE8025                    = 0x3c
-	IFT_ARAP                          = 0x58
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ASYNC                         = 0x54
-	IFT_ATM                           = 0x25
-	IFT_ATMDXI                        = 0x69
-	IFT_ATMFUNI                       = 0x6a
-	IFT_ATMIMA                        = 0x6b
-	IFT_ATMLOGICAL                    = 0x50
-	IFT_ATMRADIO                      = 0xbd
-	IFT_ATMSUBINTERFACE               = 0x86
-	IFT_ATMVCIENDPT                   = 0xc2
-	IFT_ATMVIRTUAL                    = 0x95
-	IFT_BGPPOLICYACCOUNTING           = 0xa2
-	IFT_BRIDGE                        = 0xd1
-	IFT_BSC                           = 0x53
-	IFT_CARP                          = 0xf8
-	IFT_CCTEMUL                       = 0x3d
-	IFT_CEPT                          = 0x13
-	IFT_CES                           = 0x85
-	IFT_CHANNEL                       = 0x46
-	IFT_CNR                           = 0x55
-	IFT_COFFEE                        = 0x84
-	IFT_COMPOSITELINK                 = 0x9b
-	IFT_DCN                           = 0x8d
-	IFT_DIGITALPOWERLINE              = 0x8a
-	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
-	IFT_DLSW                          = 0x4a
-	IFT_DOCSCABLEDOWNSTREAM           = 0x80
-	IFT_DOCSCABLEMACLAYER             = 0x7f
-	IFT_DOCSCABLEUPSTREAM             = 0x81
-	IFT_DS0                           = 0x51
-	IFT_DS0BUNDLE                     = 0x52
-	IFT_DS1FDL                        = 0xaa
-	IFT_DS3                           = 0x1e
-	IFT_DTM                           = 0x8c
-	IFT_DVBASILN                      = 0xac
-	IFT_DVBASIOUT                     = 0xad
-	IFT_DVBRCCDOWNSTREAM              = 0x93
-	IFT_DVBRCCMACLAYER                = 0x92
-	IFT_DVBRCCUPSTREAM                = 0x94
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_EPLRS                         = 0x57
-	IFT_ESCON                         = 0x49
-	IFT_ETHER                         = 0x6
-	IFT_FAITH                         = 0xf2
-	IFT_FAST                          = 0x7d
-	IFT_FASTETHER                     = 0x3e
-	IFT_FASTETHERFX                   = 0x45
-	IFT_FDDI                          = 0xf
-	IFT_FIBRECHANNEL                  = 0x38
-	IFT_FRAMERELAYINTERCONNECT        = 0x3a
-	IFT_FRAMERELAYMPI                 = 0x5c
-	IFT_FRDLCIENDPT                   = 0xc1
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_FRF16MFRBUNDLE                = 0xa3
-	IFT_FRFORWARD                     = 0x9e
-	IFT_G703AT2MB                     = 0x43
-	IFT_G703AT64K                     = 0x42
-	IFT_GIF                           = 0xf0
-	IFT_GIGABITETHERNET               = 0x75
-	IFT_GR303IDT                      = 0xb2
-	IFT_GR303RDT                      = 0xb1
-	IFT_H323GATEKEEPER                = 0xa4
-	IFT_H323PROXY                     = 0xa5
-	IFT_HDH1822                       = 0x3
-	IFT_HDLC                          = 0x76
-	IFT_HDSL2                         = 0xa8
-	IFT_HIPERLAN2                     = 0xb7
-	IFT_HIPPI                         = 0x2f
-	IFT_HIPPIINTERFACE                = 0x39
-	IFT_HOSTPAD                       = 0x5a
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IBM370PARCHAN                 = 0x48
-	IFT_IDSL                          = 0x9a
-	IFT_IEEE1394                      = 0x90
-	IFT_IEEE80211                     = 0x47
-	IFT_IEEE80212                     = 0x37
-	IFT_IEEE8023ADLAG                 = 0xa1
-	IFT_IFGSN                         = 0x91
-	IFT_IMT                           = 0xbe
-	IFT_INFINIBAND                    = 0xc7
-	IFT_INTERLEAVE                    = 0x7c
-	IFT_IP                            = 0x7e
-	IFT_IPFORWARD                     = 0x8e
-	IFT_IPOVERATM                     = 0x72
-	IFT_IPOVERCDLC                    = 0x6d
-	IFT_IPOVERCLAW                    = 0x6e
-	IFT_IPSWITCH                      = 0x4e
-	IFT_IPXIP                         = 0xf9
-	IFT_ISDN                          = 0x3f
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISDNS                         = 0x4b
-	IFT_ISDNU                         = 0x4c
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88025CRFPINT               = 0x62
-	IFT_ISO88025DTR                   = 0x56
-	IFT_ISO88025FIBER                 = 0x73
-	IFT_ISO88026                      = 0xa
-	IFT_ISUP                          = 0xb3
-	IFT_L2VLAN                        = 0x87
-	IFT_L3IPVLAN                      = 0x88
-	IFT_L3IPXVLAN                     = 0x89
-	IFT_LAPB                          = 0x10
-	IFT_LAPD                          = 0x4d
-	IFT_LAPF                          = 0x77
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MEDIAMAILOVERIP               = 0x8b
-	IFT_MFSIGLINK                     = 0xa7
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_MPC                           = 0x71
-	IFT_MPLS                          = 0xa6
-	IFT_MPLSTUNNEL                    = 0x96
-	IFT_MSDSL                         = 0x8f
-	IFT_MVL                           = 0xbf
-	IFT_MYRINET                       = 0x63
-	IFT_NFAS                          = 0xaf
-	IFT_NSIP                          = 0x1b
-	IFT_OPTICALCHANNEL                = 0xc3
-	IFT_OPTICALTRANSPORT              = 0xc4
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PFLOG                         = 0xf6
-	IFT_PFSYNC                        = 0xf7
-	IFT_PLC                           = 0xae
-	IFT_POS                           = 0xab
-	IFT_PPP                           = 0x17
-	IFT_PPPMULTILINKBUNDLE            = 0x6c
-	IFT_PROPBWAP2MP                   = 0xb8
-	IFT_PROPCNLS                      = 0x59
-	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
-	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
-	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPVIRTUAL                   = 0x35
-	IFT_PROPWIRELESSP2P               = 0x9d
-	IFT_PTPSERIAL                     = 0x16
-	IFT_PVC                           = 0xf1
-	IFT_QLLC                          = 0x44
-	IFT_RADIOMAC                      = 0xbc
-	IFT_RADSL                         = 0x5f
-	IFT_REACHDSL                      = 0xc0
-	IFT_RFC1483                       = 0x9f
-	IFT_RS232                         = 0x21
-	IFT_RSRB                          = 0x4f
-	IFT_SDLC                          = 0x11
-	IFT_SDSL                          = 0x60
-	IFT_SHDSL                         = 0xa9
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETOVERHEADCHANNEL          = 0xb9
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_SRP                           = 0x97
-	IFT_SS7SIGLINK                    = 0x9c
-	IFT_STACKTOSTACK                  = 0x6f
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0xd7
-	IFT_T1                            = 0x12
-	IFT_TDLC                          = 0x74
-	IFT_TERMPAD                       = 0x5b
-	IFT_TR008                         = 0xb0
-	IFT_TRANSPHDLC                    = 0x7b
-	IFT_TUNNEL                        = 0x83
-	IFT_ULTRA                         = 0x1d
-	IFT_USB                           = 0xa0
-	IFT_V11                           = 0x40
-	IFT_V35                           = 0x2d
-	IFT_V36                           = 0x41
-	IFT_V37                           = 0x78
-	IFT_VDSL                          = 0x61
-	IFT_VIRTUALIPADDRESS              = 0x70
-	IFT_VOICEEM                       = 0x64
-	IFT_VOICEENCAP                    = 0x67
-	IFT_VOICEFXO                      = 0x65
-	IFT_VOICEFXS                      = 0x66
-	IFT_VOICEOVERATM                  = 0x98
-	IFT_VOICEOVERFRAMERELAY           = 0x99
-	IFT_VOICEOVERIP                   = 0x68
-	IFT_X213                          = 0x5d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25HUNTGROUP                  = 0x7a
-	IFT_X25MLP                        = 0x79
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-	IGNBRK                            = 0x1
-	IGNCR                             = 0x80
-	IGNPAR                            = 0x4
-	IMAXBEL                           = 0x2000
-	INLCR                             = 0x40
-	INPCK                             = 0x10
-	IN_CLASSA_HOST                    = 0xffffff
-	IN_CLASSA_MAX                     = 0x80
-	IN_CLASSA_NET                     = 0xff000000
-	IN_CLASSA_NSHIFT                  = 0x18
-	IN_CLASSB_HOST                    = 0xffff
-	IN_CLASSB_MAX                     = 0x10000
-	IN_CLASSB_NET                     = 0xffff0000
-	IN_CLASSB_NSHIFT                  = 0x10
-	IN_CLASSC_HOST                    = 0xff
-	IN_CLASSC_NET                     = 0xffffff00
-	IN_CLASSC_NSHIFT                  = 0x8
-	IN_CLASSD_HOST                    = 0xfffffff
-	IN_CLASSD_NET                     = 0xf0000000
-	IN_CLASSD_NSHIFT                  = 0x1c
-	IN_LOOPBACKNET                    = 0x7f
-	IN_RFC3021_MASK                   = 0xfffffffe
-	IPPROTO_3PC                       = 0x22
-	IPPROTO_ADFS                      = 0x44
-	IPPROTO_AH                        = 0x33
-	IPPROTO_AHIP                      = 0x3d
-	IPPROTO_APES                      = 0x63
-	IPPROTO_ARGUS                     = 0xd
-	IPPROTO_AX25                      = 0x5d
-	IPPROTO_BHA                       = 0x31
-	IPPROTO_BLT                       = 0x1e
-	IPPROTO_BRSATMON                  = 0x4c
-	IPPROTO_CARP                      = 0x70
-	IPPROTO_CFTP                      = 0x3e
-	IPPROTO_CHAOS                     = 0x10
-	IPPROTO_CMTP                      = 0x26
-	IPPROTO_CPHB                      = 0x49
-	IPPROTO_CPNX                      = 0x48
-	IPPROTO_DDP                       = 0x25
-	IPPROTO_DGP                       = 0x56
-	IPPROTO_DIVERT                    = 0x102
-	IPPROTO_DONE                      = 0x101
-	IPPROTO_DSTOPTS                   = 0x3c
-	IPPROTO_EGP                       = 0x8
-	IPPROTO_EMCON                     = 0xe
-	IPPROTO_ENCAP                     = 0x62
-	IPPROTO_EON                       = 0x50
-	IPPROTO_ESP                       = 0x32
-	IPPROTO_ETHERIP                   = 0x61
-	IPPROTO_FRAGMENT                  = 0x2c
-	IPPROTO_GGP                       = 0x3
-	IPPROTO_GMTP                      = 0x64
-	IPPROTO_GRE                       = 0x2f
-	IPPROTO_HELLO                     = 0x3f
-	IPPROTO_HIP                       = 0x8b
-	IPPROTO_HMP                       = 0x14
-	IPPROTO_HOPOPTS                   = 0x0
-	IPPROTO_ICMP                      = 0x1
-	IPPROTO_ICMPV6                    = 0x3a
-	IPPROTO_IDP                       = 0x16
-	IPPROTO_IDPR                      = 0x23
-	IPPROTO_IDRP                      = 0x2d
-	IPPROTO_IGMP                      = 0x2
-	IPPROTO_IGP                       = 0x55
-	IPPROTO_IGRP                      = 0x58
-	IPPROTO_IL                        = 0x28
-	IPPROTO_INLSP                     = 0x34
-	IPPROTO_INP                       = 0x20
-	IPPROTO_IP                        = 0x0
-	IPPROTO_IPCOMP                    = 0x6c
-	IPPROTO_IPCV                      = 0x47
-	IPPROTO_IPEIP                     = 0x5e
-	IPPROTO_IPIP                      = 0x4
-	IPPROTO_IPPC                      = 0x43
-	IPPROTO_IPV4                      = 0x4
-	IPPROTO_IPV6                      = 0x29
-	IPPROTO_IRTP                      = 0x1c
-	IPPROTO_KRYPTOLAN                 = 0x41
-	IPPROTO_LARP                      = 0x5b
-	IPPROTO_LEAF1                     = 0x19
-	IPPROTO_LEAF2                     = 0x1a
-	IPPROTO_MAX                       = 0x100
-	IPPROTO_MAXID                     = 0x34
-	IPPROTO_MEAS                      = 0x13
-	IPPROTO_MH                        = 0x87
-	IPPROTO_MHRP                      = 0x30
-	IPPROTO_MICP                      = 0x5f
-	IPPROTO_MOBILE                    = 0x37
-	IPPROTO_MPLS                      = 0x89
-	IPPROTO_MTP                       = 0x5c
-	IPPROTO_MUX                       = 0x12
-	IPPROTO_ND                        = 0x4d
-	IPPROTO_NHRP                      = 0x36
-	IPPROTO_NONE                      = 0x3b
-	IPPROTO_NSP                       = 0x1f
-	IPPROTO_NVPII                     = 0xb
-	IPPROTO_OLD_DIVERT                = 0xfe
-	IPPROTO_OSPFIGP                   = 0x59
-	IPPROTO_PFSYNC                    = 0xf0
-	IPPROTO_PGM                       = 0x71
-	IPPROTO_PIGP                      = 0x9
-	IPPROTO_PIM                       = 0x67
-	IPPROTO_PRM                       = 0x15
-	IPPROTO_PUP                       = 0xc
-	IPPROTO_PVP                       = 0x4b
-	IPPROTO_RAW                       = 0xff
-	IPPROTO_RCCMON                    = 0xa
-	IPPROTO_RDP                       = 0x1b
-	IPPROTO_RESERVED_253              = 0xfd
-	IPPROTO_RESERVED_254              = 0xfe
-	IPPROTO_ROUTING                   = 0x2b
-	IPPROTO_RSVP                      = 0x2e
-	IPPROTO_RVD                       = 0x42
-	IPPROTO_SATEXPAK                  = 0x40
-	IPPROTO_SATMON                    = 0x45
-	IPPROTO_SCCSP                     = 0x60
-	IPPROTO_SCTP                      = 0x84
-	IPPROTO_SDRP                      = 0x2a
-	IPPROTO_SEND                      = 0x103
-	IPPROTO_SEP                       = 0x21
-	IPPROTO_SHIM6                     = 0x8c
-	IPPROTO_SKIP                      = 0x39
-	IPPROTO_SPACER                    = 0x7fff
-	IPPROTO_SRPC                      = 0x5a
-	IPPROTO_ST                        = 0x7
-	IPPROTO_SVMTP                     = 0x52
-	IPPROTO_SWIPE                     = 0x35
-	IPPROTO_TCF                       = 0x57
-	IPPROTO_TCP                       = 0x6
-	IPPROTO_TLSP                      = 0x38
-	IPPROTO_TP                        = 0x1d
-	IPPROTO_TPXX                      = 0x27
-	IPPROTO_TRUNK1                    = 0x17
-	IPPROTO_TRUNK2                    = 0x18
-	IPPROTO_TTP                       = 0x54
-	IPPROTO_UDP                       = 0x11
-	IPPROTO_UDPLITE                   = 0x88
-	IPPROTO_VINES                     = 0x53
-	IPPROTO_VISA                      = 0x46
-	IPPROTO_VMTP                      = 0x51
-	IPPROTO_WBEXPAK                   = 0x4f
-	IPPROTO_WBMON                     = 0x4e
-	IPPROTO_WSN                       = 0x4a
-	IPPROTO_XNET                      = 0xf
-	IPPROTO_XTP                       = 0x24
-	IPV6_AUTOFLOWLABEL                = 0x3b
-	IPV6_BINDANY                      = 0x40
-	IPV6_BINDV6ONLY                   = 0x1b
-	IPV6_CHECKSUM                     = 0x1a
-	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
-	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
-	IPV6_DEFHLIM                      = 0x40
-	IPV6_DONTFRAG                     = 0x3e
-	IPV6_DSTOPTS                      = 0x32
-	IPV6_FAITH                        = 0x1d
-	IPV6_FLOWINFO_MASK                = 0xffffff0f
-	IPV6_FLOWLABEL_MASK               = 0xffff0f00
-	IPV6_FRAGTTL                      = 0x78
-	IPV6_FW_ADD                       = 0x1e
-	IPV6_FW_DEL                       = 0x1f
-	IPV6_FW_FLUSH                     = 0x20
-	IPV6_FW_GET                       = 0x22
-	IPV6_FW_ZERO                      = 0x21
-	IPV6_HLIMDEC                      = 0x1
-	IPV6_HOPLIMIT                     = 0x2f
-	IPV6_HOPOPTS                      = 0x31
-	IPV6_IPSEC_POLICY                 = 0x1c
-	IPV6_JOIN_GROUP                   = 0xc
-	IPV6_LEAVE_GROUP                  = 0xd
-	IPV6_MAXHLIM                      = 0xff
-	IPV6_MAXOPTHDR                    = 0x800
-	IPV6_MAXPACKET                    = 0xffff
-	IPV6_MAX_GROUP_SRC_FILTER         = 0x200
-	IPV6_MAX_MEMBERSHIPS              = 0xfff
-	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
-	IPV6_MIN_MEMBERSHIPS              = 0x1f
-	IPV6_MMTU                         = 0x500
-	IPV6_MSFILTER                     = 0x4a
-	IPV6_MULTICAST_HOPS               = 0xa
-	IPV6_MULTICAST_IF                 = 0x9
-	IPV6_MULTICAST_LOOP               = 0xb
-	IPV6_NEXTHOP                      = 0x30
-	IPV6_PATHMTU                      = 0x2c
-	IPV6_PKTINFO                      = 0x2e
-	IPV6_PORTRANGE                    = 0xe
-	IPV6_PORTRANGE_DEFAULT            = 0x0
-	IPV6_PORTRANGE_HIGH               = 0x1
-	IPV6_PORTRANGE_LOW                = 0x2
-	IPV6_PREFER_TEMPADDR              = 0x3f
-	IPV6_RECVDSTOPTS                  = 0x28
-	IPV6_RECVHOPLIMIT                 = 0x25
-	IPV6_RECVHOPOPTS                  = 0x27
-	IPV6_RECVPATHMTU                  = 0x2b
-	IPV6_RECVPKTINFO                  = 0x24
-	IPV6_RECVRTHDR                    = 0x26
-	IPV6_RECVTCLASS                   = 0x39
-	IPV6_RTHDR                        = 0x33
-	IPV6_RTHDRDSTOPTS                 = 0x23
-	IPV6_RTHDR_LOOSE                  = 0x0
-	IPV6_RTHDR_STRICT                 = 0x1
-	IPV6_RTHDR_TYPE_0                 = 0x0
-	IPV6_SOCKOPT_RESERVED1            = 0x3
-	IPV6_TCLASS                       = 0x3d
-	IPV6_UNICAST_HOPS                 = 0x4
-	IPV6_USE_MIN_MTU                  = 0x2a
-	IPV6_V6ONLY                       = 0x1b
-	IPV6_VERSION                      = 0x60
-	IPV6_VERSION_MASK                 = 0xf0
-	IP_ADD_MEMBERSHIP                 = 0xc
-	IP_ADD_SOURCE_MEMBERSHIP          = 0x46
-	IP_BINDANY                        = 0x18
-	IP_BLOCK_SOURCE                   = 0x48
-	IP_DEFAULT_MULTICAST_LOOP         = 0x1
-	IP_DEFAULT_MULTICAST_TTL          = 0x1
-	IP_DF                             = 0x4000
-	IP_DONTFRAG                       = 0x43
-	IP_DROP_MEMBERSHIP                = 0xd
-	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
-	IP_DUMMYNET3                      = 0x31
-	IP_DUMMYNET_CONFIGURE             = 0x3c
-	IP_DUMMYNET_DEL                   = 0x3d
-	IP_DUMMYNET_FLUSH                 = 0x3e
-	IP_DUMMYNET_GET                   = 0x40
-	IP_FAITH                          = 0x16
-	IP_FW3                            = 0x30
-	IP_FW_ADD                         = 0x32
-	IP_FW_DEL                         = 0x33
-	IP_FW_FLUSH                       = 0x34
-	IP_FW_GET                         = 0x36
-	IP_FW_NAT_CFG                     = 0x38
-	IP_FW_NAT_DEL                     = 0x39
-	IP_FW_NAT_GET_CONFIG              = 0x3a
-	IP_FW_NAT_GET_LOG                 = 0x3b
-	IP_FW_RESETLOG                    = 0x37
-	IP_FW_TABLE_ADD                   = 0x28
-	IP_FW_TABLE_DEL                   = 0x29
-	IP_FW_TABLE_FLUSH                 = 0x2a
-	IP_FW_TABLE_GETSIZE               = 0x2b
-	IP_FW_TABLE_LIST                  = 0x2c
-	IP_FW_ZERO                        = 0x35
-	IP_HDRINCL                        = 0x2
-	IP_IPSEC_POLICY                   = 0x15
-	IP_MAXPACKET                      = 0xffff
-	IP_MAX_GROUP_SRC_FILTER           = 0x200
-	IP_MAX_MEMBERSHIPS                = 0xfff
-	IP_MAX_SOCK_MUTE_FILTER           = 0x80
-	IP_MAX_SOCK_SRC_FILTER            = 0x80
-	IP_MAX_SOURCE_FILTER              = 0x400
-	IP_MF                             = 0x2000
-	IP_MINTTL                         = 0x42
-	IP_MIN_MEMBERSHIPS                = 0x1f
-	IP_MSFILTER                       = 0x4a
-	IP_MSS                            = 0x240
-	IP_MULTICAST_IF                   = 0x9
-	IP_MULTICAST_LOOP                 = 0xb
-	IP_MULTICAST_TTL                  = 0xa
-	IP_MULTICAST_VIF                  = 0xe
-	IP_OFFMASK                        = 0x1fff
-	IP_ONESBCAST                      = 0x17
-	IP_OPTIONS                        = 0x1
-	IP_PORTRANGE                      = 0x13
-	IP_PORTRANGE_DEFAULT              = 0x0
-	IP_PORTRANGE_HIGH                 = 0x1
-	IP_PORTRANGE_LOW                  = 0x2
-	IP_RECVDSTADDR                    = 0x7
-	IP_RECVIF                         = 0x14
-	IP_RECVOPTS                       = 0x5
-	IP_RECVRETOPTS                    = 0x6
-	IP_RECVTOS                        = 0x44
-	IP_RECVTTL                        = 0x41
-	IP_RETOPTS                        = 0x8
-	IP_RF                             = 0x8000
-	IP_RSVP_OFF                       = 0x10
-	IP_RSVP_ON                        = 0xf
-	IP_RSVP_VIF_OFF                   = 0x12
-	IP_RSVP_VIF_ON                    = 0x11
-	IP_SENDSRCADDR                    = 0x7
-	IP_TOS                            = 0x3
-	IP_TTL                            = 0x4
-	IP_UNBLOCK_SOURCE                 = 0x49
-	ISIG                              = 0x80
-	ISTRIP                            = 0x20
-	IXANY                             = 0x800
-	IXOFF                             = 0x400
-	IXON                              = 0x200
-	LOCK_EX                           = 0x2
-	LOCK_NB                           = 0x4
-	LOCK_SH                           = 0x1
-	LOCK_UN                           = 0x8
-	MADV_AUTOSYNC                     = 0x7
-	MADV_CORE                         = 0x9
-	MADV_DONTNEED                     = 0x4
-	MADV_FREE                         = 0x5
-	MADV_NOCORE                       = 0x8
-	MADV_NORMAL                       = 0x0
-	MADV_NOSYNC                       = 0x6
-	MADV_PROTECT                      = 0xa
-	MADV_RANDOM                       = 0x1
-	MADV_SEQUENTIAL                   = 0x2
-	MADV_WILLNEED                     = 0x3
-	MAP_ALIGNED_SUPER                 = 0x1000000
-	MAP_ALIGNMENT_MASK                = -0x1000000
-	MAP_ALIGNMENT_SHIFT               = 0x18
-	MAP_ANON                          = 0x1000
-	MAP_ANONYMOUS                     = 0x1000
-	MAP_COPY                          = 0x2
-	MAP_EXCL                          = 0x4000
-	MAP_FILE                          = 0x0
-	MAP_FIXED                         = 0x10
-	MAP_HASSEMAPHORE                  = 0x200
-	MAP_NOCORE                        = 0x20000
-	MAP_NORESERVE                     = 0x40
-	MAP_NOSYNC                        = 0x800
-	MAP_PREFAULT_READ                 = 0x40000
-	MAP_PRIVATE                       = 0x2
-	MAP_RENAME                        = 0x20
-	MAP_RESERVED0080                  = 0x80
-	MAP_RESERVED0100                  = 0x100
-	MAP_SHARED                        = 0x1
-	MAP_STACK                         = 0x400
-	MCL_CURRENT                       = 0x1
-	MCL_FUTURE                        = 0x2
-	MSG_CMSG_CLOEXEC                  = 0x40000
-	MSG_COMPAT                        = 0x8000
-	MSG_CTRUNC                        = 0x20
-	MSG_DONTROUTE                     = 0x4
-	MSG_DONTWAIT                      = 0x80
-	MSG_EOF                           = 0x100
-	MSG_EOR                           = 0x8
-	MSG_NBIO                          = 0x4000
-	MSG_NOSIGNAL                      = 0x20000
-	MSG_NOTIFICATION                  = 0x2000
-	MSG_OOB                           = 0x1
-	MSG_PEEK                          = 0x2
-	MSG_TRUNC                         = 0x10
-	MSG_WAITALL                       = 0x40
-	MS_ASYNC                          = 0x1
-	MS_INVALIDATE                     = 0x2
-	MS_SYNC                           = 0x0
-	NAME_MAX                          = 0xff
-	NET_RT_DUMP                       = 0x1
-	NET_RT_FLAGS                      = 0x2
-	NET_RT_IFLIST                     = 0x3
-	NET_RT_IFLISTL                    = 0x5
-	NET_RT_IFMALIST                   = 0x4
-	NET_RT_MAXID                      = 0x6
-	NOFLSH                            = 0x80000000
-	NOTE_ATTRIB                       = 0x8
-	NOTE_CHILD                        = 0x4
-	NOTE_DELETE                       = 0x1
-	NOTE_EXEC                         = 0x20000000
-	NOTE_EXIT                         = 0x80000000
-	NOTE_EXTEND                       = 0x4
-	NOTE_FFAND                        = 0x40000000
-	NOTE_FFCOPY                       = 0xc0000000
-	NOTE_FFCTRLMASK                   = 0xc0000000
-	NOTE_FFLAGSMASK                   = 0xffffff
-	NOTE_FFNOP                        = 0x0
-	NOTE_FFOR                         = 0x80000000
-	NOTE_FORK                         = 0x40000000
-	NOTE_LINK                         = 0x10
-	NOTE_LOWAT                        = 0x1
-	NOTE_PCTRLMASK                    = 0xf0000000
-	NOTE_PDATAMASK                    = 0xfffff
-	NOTE_RENAME                       = 0x20
-	NOTE_REVOKE                       = 0x40
-	NOTE_TRACK                        = 0x1
-	NOTE_TRACKERR                     = 0x2
-	NOTE_TRIGGER                      = 0x1000000
-	NOTE_WRITE                        = 0x2
-	OCRNL                             = 0x10
-	ONLCR                             = 0x2
-	ONLRET                            = 0x40
-	ONOCR                             = 0x20
-	ONOEOT                            = 0x8
-	OPOST                             = 0x1
-	O_ACCMODE                         = 0x3
-	O_APPEND                          = 0x8
-	O_ASYNC                           = 0x40
-	O_CLOEXEC                         = 0x100000
-	O_CREAT                           = 0x200
-	O_DIRECT                          = 0x10000
-	O_DIRECTORY                       = 0x20000
-	O_EXCL                            = 0x800
-	O_EXEC                            = 0x40000
-	O_EXLOCK                          = 0x20
-	O_FSYNC                           = 0x80
-	O_NDELAY                          = 0x4
-	O_NOCTTY                          = 0x8000
-	O_NOFOLLOW                        = 0x100
-	O_NONBLOCK                        = 0x4
-	O_RDONLY                          = 0x0
-	O_RDWR                            = 0x2
-	O_SHLOCK                          = 0x10
-	O_SYNC                            = 0x80
-	O_TRUNC                           = 0x400
-	O_TTY_INIT                        = 0x80000
-	O_WRONLY                          = 0x1
-	PARENB                            = 0x1000
-	PARMRK                            = 0x8
-	PARODD                            = 0x2000
-	PENDIN                            = 0x20000000
-	PRIO_PGRP                         = 0x1
-	PRIO_PROCESS                      = 0x0
-	PRIO_USER                         = 0x2
-	PROT_EXEC                         = 0x4
-	PROT_NONE                         = 0x0
-	PROT_READ                         = 0x1
-	PROT_WRITE                        = 0x2
-	RLIMIT_AS                         = 0xa
-	RLIMIT_CORE                       = 0x4
-	RLIMIT_CPU                        = 0x0
-	RLIMIT_DATA                       = 0x2
-	RLIMIT_FSIZE                      = 0x1
-	RLIMIT_NOFILE                     = 0x8
-	RLIMIT_STACK                      = 0x3
-	RLIM_INFINITY                     = 0x7fffffffffffffff
-	RTAX_AUTHOR                       = 0x6
-	RTAX_BRD                          = 0x7
-	RTAX_DST                          = 0x0
-	RTAX_GATEWAY                      = 0x1
-	RTAX_GENMASK                      = 0x3
-	RTAX_IFA                          = 0x5
-	RTAX_IFP                          = 0x4
-	RTAX_MAX                          = 0x8
-	RTAX_NETMASK                      = 0x2
-	RTA_AUTHOR                        = 0x40
-	RTA_BRD                           = 0x80
-	RTA_DST                           = 0x1
-	RTA_GATEWAY                       = 0x2
-	RTA_GENMASK                       = 0x8
-	RTA_IFA                           = 0x20
-	RTA_IFP                           = 0x10
-	RTA_NETMASK                       = 0x4
-	RTF_BLACKHOLE                     = 0x1000
-	RTF_BROADCAST                     = 0x400000
-	RTF_DONE                          = 0x40
-	RTF_DYNAMIC                       = 0x10
-	RTF_FMASK                         = 0x1004d808
-	RTF_GATEWAY                       = 0x2
-	RTF_GWFLAG_COMPAT                 = 0x80000000
-	RTF_HOST                          = 0x4
-	RTF_LLDATA                        = 0x400
-	RTF_LLINFO                        = 0x400
-	RTF_LOCAL                         = 0x200000
-	RTF_MODIFIED                      = 0x20
-	RTF_MULTICAST                     = 0x800000
-	RTF_PINNED                        = 0x100000
-	RTF_PRCLONING                     = 0x10000
-	RTF_PROTO1                        = 0x8000
-	RTF_PROTO2                        = 0x4000
-	RTF_PROTO3                        = 0x40000
-	RTF_REJECT                        = 0x8
-	RTF_RNH_LOCKED                    = 0x40000000
-	RTF_STATIC                        = 0x800
-	RTF_STICKY                        = 0x10000000
-	RTF_UP                            = 0x1
-	RTF_XRESOLVE                      = 0x200
-	RTM_ADD                           = 0x1
-	RTM_CHANGE                        = 0x3
-	RTM_DELADDR                       = 0xd
-	RTM_DELETE                        = 0x2
-	RTM_DELMADDR                      = 0x10
-	RTM_GET                           = 0x4
-	RTM_IEEE80211                     = 0x12
-	RTM_IFANNOUNCE                    = 0x11
-	RTM_IFINFO                        = 0xe
-	RTM_LOCK                          = 0x8
-	RTM_LOSING                        = 0x5
-	RTM_MISS                          = 0x7
-	RTM_NEWADDR                       = 0xc
-	RTM_NEWMADDR                      = 0xf
-	RTM_OLDADD                        = 0x9
-	RTM_OLDDEL                        = 0xa
-	RTM_REDIRECT                      = 0x6
-	RTM_RESOLVE                       = 0xb
-	RTM_RTTUNIT                       = 0xf4240
-	RTM_VERSION                       = 0x5
-	RTV_EXPIRE                        = 0x4
-	RTV_HOPCOUNT                      = 0x2
-	RTV_MTU                           = 0x1
-	RTV_RPIPE                         = 0x8
-	RTV_RTT                           = 0x40
-	RTV_RTTVAR                        = 0x80
-	RTV_SPIPE                         = 0x10
-	RTV_SSTHRESH                      = 0x20
-	RTV_WEIGHT                        = 0x100
-	RT_ALL_FIBS                       = -0x1
-	RT_CACHING_CONTEXT                = 0x1
-	RT_DEFAULT_FIB                    = 0x0
-	RT_NORTREF                        = 0x2
-	RUSAGE_CHILDREN                   = -0x1
-	RUSAGE_SELF                       = 0x0
-	RUSAGE_THREAD                     = 0x1
-	SCM_BINTIME                       = 0x4
-	SCM_CREDS                         = 0x3
-	SCM_RIGHTS                        = 0x1
-	SCM_TIMESTAMP                     = 0x2
-	SHUT_RD                           = 0x0
-	SHUT_RDWR                         = 0x2
-	SHUT_WR                           = 0x1
-	SIOCADDMULTI                      = 0x80206931
-	SIOCADDRT                         = 0x8030720a
-	SIOCAIFADDR                       = 0x8040691a
-	SIOCAIFGROUP                      = 0x80246987
-	SIOCALIFADDR                      = 0x8118691b
-	SIOCATMARK                        = 0x40047307
-	SIOCDELMULTI                      = 0x80206932
-	SIOCDELRT                         = 0x8030720b
-	SIOCDIFADDR                       = 0x80206919
-	SIOCDIFGROUP                      = 0x80246989
-	SIOCDIFPHYADDR                    = 0x80206949
-	SIOCDLIFADDR                      = 0x8118691d
-	SIOCGDRVSPEC                      = 0xc01c697b
-	SIOCGETSGCNT                      = 0xc0147210
-	SIOCGETVIFCNT                     = 0xc014720f
-	SIOCGHIWAT                        = 0x40047301
-	SIOCGIFADDR                       = 0xc0206921
-	SIOCGIFBRDADDR                    = 0xc0206923
-	SIOCGIFCAP                        = 0xc020691f
-	SIOCGIFCONF                       = 0xc0086924
-	SIOCGIFDESCR                      = 0xc020692a
-	SIOCGIFDSTADDR                    = 0xc0206922
-	SIOCGIFFIB                        = 0xc020695c
-	SIOCGIFFLAGS                      = 0xc0206911
-	SIOCGIFGENERIC                    = 0xc020693a
-	SIOCGIFGMEMB                      = 0xc024698a
-	SIOCGIFGROUP                      = 0xc0246988
-	SIOCGIFINDEX                      = 0xc0206920
-	SIOCGIFMAC                        = 0xc0206926
-	SIOCGIFMEDIA                      = 0xc0286938
-	SIOCGIFMETRIC                     = 0xc0206917
-	SIOCGIFMTU                        = 0xc0206933
-	SIOCGIFNETMASK                    = 0xc0206925
-	SIOCGIFPDSTADDR                   = 0xc0206948
-	SIOCGIFPHYS                       = 0xc0206935
-	SIOCGIFPSRCADDR                   = 0xc0206947
-	SIOCGIFSTATUS                     = 0xc331693b
-	SIOCGLIFADDR                      = 0xc118691c
-	SIOCGLIFPHYADDR                   = 0xc118694b
-	SIOCGLOWAT                        = 0x40047303
-	SIOCGPGRP                         = 0x40047309
-	SIOCGPRIVATE_0                    = 0xc0206950
-	SIOCGPRIVATE_1                    = 0xc0206951
-	SIOCIFCREATE                      = 0xc020697a
-	SIOCIFCREATE2                     = 0xc020697c
-	SIOCIFDESTROY                     = 0x80206979
-	SIOCIFGCLONERS                    = 0xc00c6978
-	SIOCSDRVSPEC                      = 0x801c697b
-	SIOCSHIWAT                        = 0x80047300
-	SIOCSIFADDR                       = 0x8020690c
-	SIOCSIFBRDADDR                    = 0x80206913
-	SIOCSIFCAP                        = 0x8020691e
-	SIOCSIFDESCR                      = 0x80206929
-	SIOCSIFDSTADDR                    = 0x8020690e
-	SIOCSIFFIB                        = 0x8020695d
-	SIOCSIFFLAGS                      = 0x80206910
-	SIOCSIFGENERIC                    = 0x80206939
-	SIOCSIFLLADDR                     = 0x8020693c
-	SIOCSIFMAC                        = 0x80206927
-	SIOCSIFMEDIA                      = 0xc0206937
-	SIOCSIFMETRIC                     = 0x80206918
-	SIOCSIFMTU                        = 0x80206934
-	SIOCSIFNAME                       = 0x80206928
-	SIOCSIFNETMASK                    = 0x80206916
-	SIOCSIFPHYADDR                    = 0x80406946
-	SIOCSIFPHYS                       = 0x80206936
-	SIOCSIFRVNET                      = 0xc020695b
-	SIOCSIFVNET                       = 0xc020695a
-	SIOCSLIFPHYADDR                   = 0x8118694a
-	SIOCSLOWAT                        = 0x80047302
-	SIOCSPGRP                         = 0x80047308
-	SOCK_CLOEXEC                      = 0x10000000
-	SOCK_DGRAM                        = 0x2
-	SOCK_MAXADDRLEN                   = 0xff
-	SOCK_NONBLOCK                     = 0x20000000
-	SOCK_RAW                          = 0x3
-	SOCK_RDM                          = 0x4
-	SOCK_SEQPACKET                    = 0x5
-	SOCK_STREAM                       = 0x1
-	SOL_SOCKET                        = 0xffff
-	SOMAXCONN                         = 0x80
-	SO_ACCEPTCONN                     = 0x2
-	SO_ACCEPTFILTER                   = 0x1000
-	SO_BINTIME                        = 0x2000
-	SO_BROADCAST                      = 0x20
-	SO_DEBUG                          = 0x1
-	SO_DONTROUTE                      = 0x10
-	SO_ERROR                          = 0x1007
-	SO_KEEPALIVE                      = 0x8
-	SO_LABEL                          = 0x1009
-	SO_LINGER                         = 0x80
-	SO_LISTENINCQLEN                  = 0x1013
-	SO_LISTENQLEN                     = 0x1012
-	SO_LISTENQLIMIT                   = 0x1011
-	SO_NOSIGPIPE                      = 0x800
-	SO_NO_DDP                         = 0x8000
-	SO_NO_OFFLOAD                     = 0x4000
-	SO_OOBINLINE                      = 0x100
-	SO_PEERLABEL                      = 0x1010
-	SO_PROTOCOL                       = 0x1016
-	SO_PROTOTYPE                      = 0x1016
-	SO_RCVBUF                         = 0x1002
-	SO_RCVLOWAT                       = 0x1004
-	SO_RCVTIMEO                       = 0x1006
-	SO_REUSEADDR                      = 0x4
-	SO_REUSEPORT                      = 0x200
-	SO_SETFIB                         = 0x1014
-	SO_SNDBUF                         = 0x1001
-	SO_SNDLOWAT                       = 0x1003
-	SO_SNDTIMEO                       = 0x1005
-	SO_TIMESTAMP                      = 0x400
-	SO_TYPE                           = 0x1008
-	SO_USELOOPBACK                    = 0x40
-	SO_USER_COOKIE                    = 0x1015
-	SO_VENDOR                         = 0x80000000
-	TCIFLUSH                          = 0x1
-	TCIOFLUSH                         = 0x3
-	TCOFLUSH                          = 0x2
-	TCP_CA_NAME_MAX                   = 0x10
-	TCP_CONGESTION                    = 0x40
-	TCP_INFO                          = 0x20
-	TCP_KEEPCNT                       = 0x400
-	TCP_KEEPIDLE                      = 0x100
-	TCP_KEEPINIT                      = 0x80
-	TCP_KEEPINTVL                     = 0x200
-	TCP_MAXBURST                      = 0x4
-	TCP_MAXHLEN                       = 0x3c
-	TCP_MAXOLEN                       = 0x28
-	TCP_MAXSEG                        = 0x2
-	TCP_MAXWIN                        = 0xffff
-	TCP_MAX_SACK                      = 0x4
-	TCP_MAX_WINSHIFT                  = 0xe
-	TCP_MD5SIG                        = 0x10
-	TCP_MINMSS                        = 0xd8
-	TCP_MSS                           = 0x218
-	TCP_NODELAY                       = 0x1
-	TCP_NOOPT                         = 0x8
-	TCP_NOPUSH                        = 0x4
-	TCP_VENDOR                        = 0x80000000
-	TCSAFLUSH                         = 0x2
-	TIOCCBRK                          = 0x2000747a
-	TIOCCDTR                          = 0x20007478
-	TIOCCONS                          = 0x80047462
-	TIOCDRAIN                         = 0x2000745e
-	TIOCEXCL                          = 0x2000740d
-	TIOCEXT                           = 0x80047460
-	TIOCFLUSH                         = 0x80047410
-	TIOCGDRAINWAIT                    = 0x40047456
-	TIOCGETA                          = 0x402c7413
-	TIOCGETD                          = 0x4004741a
-	TIOCGPGRP                         = 0x40047477
-	TIOCGPTN                          = 0x4004740f
-	TIOCGSID                          = 0x40047463
-	TIOCGWINSZ                        = 0x40087468
-	TIOCMBIC                          = 0x8004746b
-	TIOCMBIS                          = 0x8004746c
-	TIOCMGDTRWAIT                     = 0x4004745a
-	TIOCMGET                          = 0x4004746a
-	TIOCMSDTRWAIT                     = 0x8004745b
-	TIOCMSET                          = 0x8004746d
-	TIOCM_CAR                         = 0x40
-	TIOCM_CD                          = 0x40
-	TIOCM_CTS                         = 0x20
-	TIOCM_DCD                         = 0x40
-	TIOCM_DSR                         = 0x100
-	TIOCM_DTR                         = 0x2
-	TIOCM_LE                          = 0x1
-	TIOCM_RI                          = 0x80
-	TIOCM_RNG                         = 0x80
-	TIOCM_RTS                         = 0x4
-	TIOCM_SR                          = 0x10
-	TIOCM_ST                          = 0x8
-	TIOCNOTTY                         = 0x20007471
-	TIOCNXCL                          = 0x2000740e
-	TIOCOUTQ                          = 0x40047473
-	TIOCPKT                           = 0x80047470
-	TIOCPKT_DATA                      = 0x0
-	TIOCPKT_DOSTOP                    = 0x20
-	TIOCPKT_FLUSHREAD                 = 0x1
-	TIOCPKT_FLUSHWRITE                = 0x2
-	TIOCPKT_IOCTL                     = 0x40
-	TIOCPKT_NOSTOP                    = 0x10
-	TIOCPKT_START                     = 0x8
-	TIOCPKT_STOP                      = 0x4
-	TIOCPTMASTER                      = 0x2000741c
-	TIOCSBRK                          = 0x2000747b
-	TIOCSCTTY                         = 0x20007461
-	TIOCSDRAINWAIT                    = 0x80047457
-	TIOCSDTR                          = 0x20007479
-	TIOCSETA                          = 0x802c7414
-	TIOCSETAF                         = 0x802c7416
-	TIOCSETAW                         = 0x802c7415
-	TIOCSETD                          = 0x8004741b
-	TIOCSIG                           = 0x2004745f
-	TIOCSPGRP                         = 0x80047476
-	TIOCSTART                         = 0x2000746e
-	TIOCSTAT                          = 0x20007465
-	TIOCSTI                           = 0x80017472
-	TIOCSTOP                          = 0x2000746f
-	TIOCSWINSZ                        = 0x80087467
-	TIOCTIMESTAMP                     = 0x40087459
-	TIOCUCNTL                         = 0x80047466
-	TOSTOP                            = 0x400000
-	VDISCARD                          = 0xf
-	VDSUSP                            = 0xb
-	VEOF                              = 0x0
-	VEOL                              = 0x1
-	VEOL2                             = 0x2
-	VERASE                            = 0x3
-	VERASE2                           = 0x7
-	VINTR                             = 0x8
-	VKILL                             = 0x5
-	VLNEXT                            = 0xe
-	VMIN                              = 0x10
-	VQUIT                             = 0x9
-	VREPRINT                          = 0x6
-	VSTART                            = 0xc
-	VSTATUS                           = 0x12
-	VSTOP                             = 0xd
-	VSUSP                             = 0xa
-	VTIME                             = 0x11
-	VWERASE                           = 0x4
-	WCONTINUED                        = 0x4
-	WCOREFLAG                         = 0x80
-	WEXITED                           = 0x10
-	WLINUXCLONE                       = 0x80000000
-	WNOHANG                           = 0x1
-	WNOWAIT                           = 0x8
-	WSTOPPED                          = 0x2
-	WTRAPPED                          = 0x20
-	WUNTRACED                         = 0x2
+	AF_APPLETALK                   = 0x10
+	AF_ARP                         = 0x23
+	AF_ATM                         = 0x1e
+	AF_BLUETOOTH                   = 0x24
+	AF_CCITT                       = 0xa
+	AF_CHAOS                       = 0x5
+	AF_CNT                         = 0x15
+	AF_COIP                        = 0x14
+	AF_DATAKIT                     = 0x9
+	AF_DECnet                      = 0xc
+	AF_DLI                         = 0xd
+	AF_E164                        = 0x1a
+	AF_ECMA                        = 0x8
+	AF_HYLINK                      = 0xf
+	AF_IEEE80211                   = 0x25
+	AF_IMPLINK                     = 0x3
+	AF_INET                        = 0x2
+	AF_INET6                       = 0x1c
+	AF_INET6_SDP                   = 0x2a
+	AF_INET_SDP                    = 0x28
+	AF_IPX                         = 0x17
+	AF_ISDN                        = 0x1a
+	AF_ISO                         = 0x7
+	AF_LAT                         = 0xe
+	AF_LINK                        = 0x12
+	AF_LOCAL                       = 0x1
+	AF_MAX                         = 0x2a
+	AF_NATM                        = 0x1d
+	AF_NETBIOS                     = 0x6
+	AF_NETGRAPH                    = 0x20
+	AF_OSI                         = 0x7
+	AF_PUP                         = 0x4
+	AF_ROUTE                       = 0x11
+	AF_SCLUSTER                    = 0x22
+	AF_SIP                         = 0x18
+	AF_SLOW                        = 0x21
+	AF_SNA                         = 0xb
+	AF_UNIX                        = 0x1
+	AF_UNSPEC                      = 0x0
+	AF_VENDOR00                    = 0x27
+	AF_VENDOR01                    = 0x29
+	AF_VENDOR02                    = 0x2b
+	AF_VENDOR03                    = 0x2d
+	AF_VENDOR04                    = 0x2f
+	AF_VENDOR05                    = 0x31
+	AF_VENDOR06                    = 0x33
+	AF_VENDOR07                    = 0x35
+	AF_VENDOR08                    = 0x37
+	AF_VENDOR09                    = 0x39
+	AF_VENDOR10                    = 0x3b
+	AF_VENDOR11                    = 0x3d
+	AF_VENDOR12                    = 0x3f
+	AF_VENDOR13                    = 0x41
+	AF_VENDOR14                    = 0x43
+	AF_VENDOR15                    = 0x45
+	AF_VENDOR16                    = 0x47
+	AF_VENDOR17                    = 0x49
+	AF_VENDOR18                    = 0x4b
+	AF_VENDOR19                    = 0x4d
+	AF_VENDOR20                    = 0x4f
+	AF_VENDOR21                    = 0x51
+	AF_VENDOR22                    = 0x53
+	AF_VENDOR23                    = 0x55
+	AF_VENDOR24                    = 0x57
+	AF_VENDOR25                    = 0x59
+	AF_VENDOR26                    = 0x5b
+	AF_VENDOR27                    = 0x5d
+	AF_VENDOR28                    = 0x5f
+	AF_VENDOR29                    = 0x61
+	AF_VENDOR30                    = 0x63
+	AF_VENDOR31                    = 0x65
+	AF_VENDOR32                    = 0x67
+	AF_VENDOR33                    = 0x69
+	AF_VENDOR34                    = 0x6b
+	AF_VENDOR35                    = 0x6d
+	AF_VENDOR36                    = 0x6f
+	AF_VENDOR37                    = 0x71
+	AF_VENDOR38                    = 0x73
+	AF_VENDOR39                    = 0x75
+	AF_VENDOR40                    = 0x77
+	AF_VENDOR41                    = 0x79
+	AF_VENDOR42                    = 0x7b
+	AF_VENDOR43                    = 0x7d
+	AF_VENDOR44                    = 0x7f
+	AF_VENDOR45                    = 0x81
+	AF_VENDOR46                    = 0x83
+	AF_VENDOR47                    = 0x85
+	ALTWERASE                      = 0x200
+	B0                             = 0x0
+	B110                           = 0x6e
+	B115200                        = 0x1c200
+	B1200                          = 0x4b0
+	B134                           = 0x86
+	B14400                         = 0x3840
+	B150                           = 0x96
+	B1800                          = 0x708
+	B19200                         = 0x4b00
+	B200                           = 0xc8
+	B230400                        = 0x38400
+	B2400                          = 0x960
+	B28800                         = 0x7080
+	B300                           = 0x12c
+	B38400                         = 0x9600
+	B460800                        = 0x70800
+	B4800                          = 0x12c0
+	B50                            = 0x32
+	B57600                         = 0xe100
+	B600                           = 0x258
+	B7200                          = 0x1c20
+	B75                            = 0x4b
+	B76800                         = 0x12c00
+	B921600                        = 0xe1000
+	B9600                          = 0x2580
+	BIOCFEEDBACK                   = 0x8004427c
+	BIOCFLUSH                      = 0x20004268
+	BIOCGBLEN                      = 0x40044266
+	BIOCGDIRECTION                 = 0x40044276
+	BIOCGDLT                       = 0x4004426a
+	BIOCGDLTLIST                   = 0xc0084279
+	BIOCGETBUFMODE                 = 0x4004427d
+	BIOCGETIF                      = 0x4020426b
+	BIOCGETZMAX                    = 0x4004427f
+	BIOCGHDRCMPLT                  = 0x40044274
+	BIOCGRSIG                      = 0x40044272
+	BIOCGRTIMEOUT                  = 0x4010426e
+	BIOCGSEESENT                   = 0x40044276
+	BIOCGSTATS                     = 0x4008426f
+	BIOCGTSTAMP                    = 0x40044283
+	BIOCIMMEDIATE                  = 0x80044270
+	BIOCLOCK                       = 0x2000427a
+	BIOCPROMISC                    = 0x20004269
+	BIOCROTZBUF                    = 0x400c4280
+	BIOCSBLEN                      = 0xc0044266
+	BIOCSDIRECTION                 = 0x80044277
+	BIOCSDLT                       = 0x80044278
+	BIOCSETBUFMODE                 = 0x8004427e
+	BIOCSETF                       = 0x80084267
+	BIOCSETFNR                     = 0x80084282
+	BIOCSETIF                      = 0x8020426c
+	BIOCSETWF                      = 0x8008427b
+	BIOCSETZBUF                    = 0x800c4281
+	BIOCSHDRCMPLT                  = 0x80044275
+	BIOCSRSIG                      = 0x80044273
+	BIOCSRTIMEOUT                  = 0x8010426d
+	BIOCSSEESENT                   = 0x80044277
+	BIOCSTSTAMP                    = 0x80044284
+	BIOCVERSION                    = 0x40044271
+	BPF_A                          = 0x10
+	BPF_ABS                        = 0x20
+	BPF_ADD                        = 0x0
+	BPF_ALIGNMENT                  = 0x4
+	BPF_ALU                        = 0x4
+	BPF_AND                        = 0x50
+	BPF_B                          = 0x10
+	BPF_BUFMODE_BUFFER             = 0x1
+	BPF_BUFMODE_ZBUF               = 0x2
+	BPF_DIV                        = 0x30
+	BPF_H                          = 0x8
+	BPF_IMM                        = 0x0
+	BPF_IND                        = 0x40
+	BPF_JA                         = 0x0
+	BPF_JEQ                        = 0x10
+	BPF_JGE                        = 0x30
+	BPF_JGT                        = 0x20
+	BPF_JMP                        = 0x5
+	BPF_JSET                       = 0x40
+	BPF_K                          = 0x0
+	BPF_LD                         = 0x0
+	BPF_LDX                        = 0x1
+	BPF_LEN                        = 0x80
+	BPF_LSH                        = 0x60
+	BPF_MAJOR_VERSION              = 0x1
+	BPF_MAXBUFSIZE                 = 0x80000
+	BPF_MAXINSNS                   = 0x200
+	BPF_MEM                        = 0x60
+	BPF_MEMWORDS                   = 0x10
+	BPF_MINBUFSIZE                 = 0x20
+	BPF_MINOR_VERSION              = 0x1
+	BPF_MISC                       = 0x7
+	BPF_MOD                        = 0x90
+	BPF_MSH                        = 0xa0
+	BPF_MUL                        = 0x20
+	BPF_NEG                        = 0x80
+	BPF_OR                         = 0x40
+	BPF_RELEASE                    = 0x30bb6
+	BPF_RET                        = 0x6
+	BPF_RSH                        = 0x70
+	BPF_ST                         = 0x2
+	BPF_STX                        = 0x3
+	BPF_SUB                        = 0x10
+	BPF_TAX                        = 0x0
+	BPF_TXA                        = 0x80
+	BPF_T_BINTIME                  = 0x2
+	BPF_T_BINTIME_FAST             = 0x102
+	BPF_T_BINTIME_MONOTONIC        = 0x202
+	BPF_T_BINTIME_MONOTONIC_FAST   = 0x302
+	BPF_T_FAST                     = 0x100
+	BPF_T_FLAG_MASK                = 0x300
+	BPF_T_FORMAT_MASK              = 0x3
+	BPF_T_MICROTIME                = 0x0
+	BPF_T_MICROTIME_FAST           = 0x100
+	BPF_T_MICROTIME_MONOTONIC      = 0x200
+	BPF_T_MICROTIME_MONOTONIC_FAST = 0x300
+	BPF_T_MONOTONIC                = 0x200
+	BPF_T_MONOTONIC_FAST           = 0x300
+	BPF_T_NANOTIME                 = 0x1
+	BPF_T_NANOTIME_FAST            = 0x101
+	BPF_T_NANOTIME_MONOTONIC       = 0x201
+	BPF_T_NANOTIME_MONOTONIC_FAST  = 0x301
+	BPF_T_NONE                     = 0x3
+	BPF_T_NORMAL                   = 0x0
+	BPF_W                          = 0x0
+	BPF_X                          = 0x8
+	BPF_XOR                        = 0xa0
+	BRKINT                         = 0x2
+	CAP_ACCEPT                     = 0x200000020000000
+	CAP_ACL_CHECK                  = 0x400000000010000
+	CAP_ACL_DELETE                 = 0x400000000020000
+	CAP_ACL_GET                    = 0x400000000040000
+	CAP_ACL_SET                    = 0x400000000080000
+	CAP_ALL0                       = 0x20007ffffffffff
+	CAP_ALL1                       = 0x4000000001fffff
+	CAP_BIND                       = 0x200000040000000
+	CAP_BINDAT                     = 0x200008000000400
+	CAP_CHFLAGSAT                  = 0x200000000001400
+	CAP_CONNECT                    = 0x200000080000000
+	CAP_CONNECTAT                  = 0x200010000000400
+	CAP_CREATE                     = 0x200000000000040
+	CAP_EVENT                      = 0x400000000000020
+	CAP_EXTATTR_DELETE             = 0x400000000001000
+	CAP_EXTATTR_GET                = 0x400000000002000
+	CAP_EXTATTR_LIST               = 0x400000000004000
+	CAP_EXTATTR_SET                = 0x400000000008000
+	CAP_FCHDIR                     = 0x200000000000800
+	CAP_FCHFLAGS                   = 0x200000000001000
+	CAP_FCHMOD                     = 0x200000000002000
+	CAP_FCHMODAT                   = 0x200000000002400
+	CAP_FCHOWN                     = 0x200000000004000
+	CAP_FCHOWNAT                   = 0x200000000004400
+	CAP_FCNTL                      = 0x200000000008000
+	CAP_FCNTL_ALL                  = 0x78
+	CAP_FCNTL_GETFL                = 0x8
+	CAP_FCNTL_GETOWN               = 0x20
+	CAP_FCNTL_SETFL                = 0x10
+	CAP_FCNTL_SETOWN               = 0x40
+	CAP_FEXECVE                    = 0x200000000000080
+	CAP_FLOCK                      = 0x200000000010000
+	CAP_FPATHCONF                  = 0x200000000020000
+	CAP_FSCK                       = 0x200000000040000
+	CAP_FSTAT                      = 0x200000000080000
+	CAP_FSTATAT                    = 0x200000000080400
+	CAP_FSTATFS                    = 0x200000000100000
+	CAP_FSYNC                      = 0x200000000000100
+	CAP_FTRUNCATE                  = 0x200000000000200
+	CAP_FUTIMES                    = 0x200000000200000
+	CAP_FUTIMESAT                  = 0x200000000200400
+	CAP_GETPEERNAME                = 0x200000100000000
+	CAP_GETSOCKNAME                = 0x200000200000000
+	CAP_GETSOCKOPT                 = 0x200000400000000
+	CAP_IOCTL                      = 0x400000000000080
+	CAP_IOCTLS_ALL                 = 0x7fffffff
+	CAP_KQUEUE                     = 0x400000000100040
+	CAP_KQUEUE_CHANGE              = 0x400000000100000
+	CAP_KQUEUE_EVENT               = 0x400000000000040
+	CAP_LINKAT_SOURCE              = 0x200020000000400
+	CAP_LINKAT_TARGET              = 0x200000000400400
+	CAP_LISTEN                     = 0x200000800000000
+	CAP_LOOKUP                     = 0x200000000000400
+	CAP_MAC_GET                    = 0x400000000000001
+	CAP_MAC_SET                    = 0x400000000000002
+	CAP_MKDIRAT                    = 0x200000000800400
+	CAP_MKFIFOAT                   = 0x200000001000400
+	CAP_MKNODAT                    = 0x200000002000400
+	CAP_MMAP                       = 0x200000000000010
+	CAP_MMAP_R                     = 0x20000000000001d
+	CAP_MMAP_RW                    = 0x20000000000001f
+	CAP_MMAP_RWX                   = 0x20000000000003f
+	CAP_MMAP_RX                    = 0x20000000000003d
+	CAP_MMAP_W                     = 0x20000000000001e
+	CAP_MMAP_WX                    = 0x20000000000003e
+	CAP_MMAP_X                     = 0x20000000000003c
+	CAP_PDGETPID                   = 0x400000000000200
+	CAP_PDKILL                     = 0x400000000000800
+	CAP_PDWAIT                     = 0x400000000000400
+	CAP_PEELOFF                    = 0x200001000000000
+	CAP_POLL_EVENT                 = 0x400000000000020
+	CAP_PREAD                      = 0x20000000000000d
+	CAP_PWRITE                     = 0x20000000000000e
+	CAP_READ                       = 0x200000000000001
+	CAP_RECV                       = 0x200000000000001
+	CAP_RENAMEAT_SOURCE            = 0x200000004000400
+	CAP_RENAMEAT_TARGET            = 0x200040000000400
+	CAP_RIGHTS_VERSION             = 0x0
+	CAP_RIGHTS_VERSION_00          = 0x0
+	CAP_SEEK                       = 0x20000000000000c
+	CAP_SEEK_TELL                  = 0x200000000000004
+	CAP_SEM_GETVALUE               = 0x400000000000004
+	CAP_SEM_POST                   = 0x400000000000008
+	CAP_SEM_WAIT                   = 0x400000000000010
+	CAP_SEND                       = 0x200000000000002
+	CAP_SETSOCKOPT                 = 0x200002000000000
+	CAP_SHUTDOWN                   = 0x200004000000000
+	CAP_SOCK_CLIENT                = 0x200007780000003
+	CAP_SOCK_SERVER                = 0x200007f60000003
+	CAP_SYMLINKAT                  = 0x200000008000400
+	CAP_TTYHOOK                    = 0x400000000000100
+	CAP_UNLINKAT                   = 0x200000010000400
+	CAP_UNUSED0_44                 = 0x200080000000000
+	CAP_UNUSED0_57                 = 0x300000000000000
+	CAP_UNUSED1_22                 = 0x400000000200000
+	CAP_UNUSED1_57                 = 0x500000000000000
+	CAP_WRITE                      = 0x200000000000002
+	CFLUSH                         = 0xf
+	CLOCAL                         = 0x8000
+	CLOCK_MONOTONIC                = 0x4
+	CLOCK_MONOTONIC_FAST           = 0xc
+	CLOCK_MONOTONIC_PRECISE        = 0xb
+	CLOCK_PROCESS_CPUTIME_ID       = 0xf
+	CLOCK_PROF                     = 0x2
+	CLOCK_REALTIME                 = 0x0
+	CLOCK_REALTIME_FAST            = 0xa
+	CLOCK_REALTIME_PRECISE         = 0x9
+	CLOCK_SECOND                   = 0xd
+	CLOCK_THREAD_CPUTIME_ID        = 0xe
+	CLOCK_UPTIME                   = 0x5
+	CLOCK_UPTIME_FAST              = 0x8
+	CLOCK_UPTIME_PRECISE           = 0x7
+	CLOCK_VIRTUAL                  = 0x1
+	CREAD                          = 0x800
+	CRTSCTS                        = 0x30000
+	CS5                            = 0x0
+	CS6                            = 0x100
+	CS7                            = 0x200
+	CS8                            = 0x300
+	CSIZE                          = 0x300
+	CSTART                         = 0x11
+	CSTATUS                        = 0x14
+	CSTOP                          = 0x13
+	CSTOPB                         = 0x400
+	CSUSP                          = 0x1a
+	CTL_MAXNAME                    = 0x18
+	CTL_NET                        = 0x4
+	DLT_A429                       = 0xb8
+	DLT_A653_ICM                   = 0xb9
+	DLT_AIRONET_HEADER             = 0x78
+	DLT_AOS                        = 0xde
+	DLT_APPLE_IP_OVER_IEEE1394     = 0x8a
+	DLT_ARCNET                     = 0x7
+	DLT_ARCNET_LINUX               = 0x81
+	DLT_ATM_CLIP                   = 0x13
+	DLT_ATM_RFC1483                = 0xb
+	DLT_AURORA                     = 0x7e
+	DLT_AX25                       = 0x3
+	DLT_AX25_KISS                  = 0xca
+	DLT_BACNET_MS_TP               = 0xa5
+	DLT_BLUETOOTH_BREDR_BB         = 0xff
+	DLT_BLUETOOTH_HCI_H4           = 0xbb
+	DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9
+	DLT_BLUETOOTH_LE_LL            = 0xfb
+	DLT_BLUETOOTH_LE_LL_WITH_PHDR  = 0x100
+	DLT_BLUETOOTH_LINUX_MONITOR    = 0xfe
+	DLT_CAN20B                     = 0xbe
+	DLT_CAN_SOCKETCAN              = 0xe3
+	DLT_CHAOS                      = 0x5
+	DLT_CHDLC                      = 0x68
+	DLT_CISCO_IOS                  = 0x76
+	DLT_CLASS_NETBSD_RAWAF         = 0x2240000
+	DLT_C_HDLC                     = 0x68
+	DLT_C_HDLC_WITH_DIR            = 0xcd
+	DLT_DBUS                       = 0xe7
+	DLT_DECT                       = 0xdd
+	DLT_DOCSIS                     = 0x8f
+	DLT_DVB_CI                     = 0xeb
+	DLT_ECONET                     = 0x73
+	DLT_EN10MB                     = 0x1
+	DLT_EN3MB                      = 0x2
+	DLT_ENC                        = 0x6d
+	DLT_EPON                       = 0x103
+	DLT_ERF                        = 0xc5
+	DLT_ERF_ETH                    = 0xaf
+	DLT_ERF_POS                    = 0xb0
+	DLT_FC_2                       = 0xe0
+	DLT_FC_2_WITH_FRAME_DELIMS     = 0xe1
+	DLT_FDDI                       = 0xa
+	DLT_FLEXRAY                    = 0xd2
+	DLT_FRELAY                     = 0x6b
+	DLT_FRELAY_WITH_DIR            = 0xce
+	DLT_GCOM_SERIAL                = 0xad
+	DLT_GCOM_T1E1                  = 0xac
+	DLT_GPF_F                      = 0xab
+	DLT_GPF_T                      = 0xaa
+	DLT_GPRS_LLC                   = 0xa9
+	DLT_GSMTAP_ABIS                = 0xda
+	DLT_GSMTAP_UM                  = 0xd9
+	DLT_IBM_SN                     = 0x92
+	DLT_IBM_SP                     = 0x91
+	DLT_IEEE802                    = 0x6
+	DLT_IEEE802_11                 = 0x69
+	DLT_IEEE802_11_RADIO           = 0x7f
+	DLT_IEEE802_11_RADIO_AVS       = 0xa3
+	DLT_IEEE802_15_4               = 0xc3
+	DLT_IEEE802_15_4_LINUX         = 0xbf
+	DLT_IEEE802_15_4_NOFCS         = 0xe6
+	DLT_IEEE802_15_4_NONASK_PHY    = 0xd7
+	DLT_IEEE802_16_MAC_CPS         = 0xbc
+	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
+	DLT_INFINIBAND                 = 0xf7
+	DLT_IPFILTER                   = 0x74
+	DLT_IPMB                       = 0xc7
+	DLT_IPMB_LINUX                 = 0xd1
+	DLT_IPMI_HPM_2                 = 0x104
+	DLT_IPNET                      = 0xe2
+	DLT_IPOIB                      = 0xf2
+	DLT_IPV4                       = 0xe4
+	DLT_IPV6                       = 0xe5
+	DLT_IP_OVER_FC                 = 0x7a
+	DLT_ISO_14443                  = 0x108
+	DLT_JUNIPER_ATM1               = 0x89
+	DLT_JUNIPER_ATM2               = 0x87
+	DLT_JUNIPER_ATM_CEMIC          = 0xee
+	DLT_JUNIPER_CHDLC              = 0xb5
+	DLT_JUNIPER_ES                 = 0x84
+	DLT_JUNIPER_ETHER              = 0xb2
+	DLT_JUNIPER_FIBRECHANNEL       = 0xea
+	DLT_JUNIPER_FRELAY             = 0xb4
+	DLT_JUNIPER_GGSN               = 0x85
+	DLT_JUNIPER_ISM                = 0xc2
+	DLT_JUNIPER_MFR                = 0x86
+	DLT_JUNIPER_MLFR               = 0x83
+	DLT_JUNIPER_MLPPP              = 0x82
+	DLT_JUNIPER_MONITOR            = 0xa4
+	DLT_JUNIPER_PIC_PEER           = 0xae
+	DLT_JUNIPER_PPP                = 0xb3
+	DLT_JUNIPER_PPPOE              = 0xa7
+	DLT_JUNIPER_PPPOE_ATM          = 0xa8
+	DLT_JUNIPER_SERVICES           = 0x88
+	DLT_JUNIPER_SRX_E2E            = 0xe9
+	DLT_JUNIPER_ST                 = 0xc8
+	DLT_JUNIPER_VP                 = 0xb7
+	DLT_JUNIPER_VS                 = 0xe8
+	DLT_LAPB_WITH_DIR              = 0xcf
+	DLT_LAPD                       = 0xcb
+	DLT_LIN                        = 0xd4
+	DLT_LINUX_EVDEV                = 0xd8
+	DLT_LINUX_IRDA                 = 0x90
+	DLT_LINUX_LAPD                 = 0xb1
+	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
+	DLT_LINUX_SLL                  = 0x71
+	DLT_LOOP                       = 0x6c
+	DLT_LTALK                      = 0x72
+	DLT_MATCHING_MAX               = 0x109
+	DLT_MATCHING_MIN               = 0x68
+	DLT_MFR                        = 0xb6
+	DLT_MOST                       = 0xd3
+	DLT_MPEG_2_TS                  = 0xf3
+	DLT_MPLS                       = 0xdb
+	DLT_MTP2                       = 0x8c
+	DLT_MTP2_WITH_PHDR             = 0x8b
+	DLT_MTP3                       = 0x8d
+	DLT_MUX27010                   = 0xec
+	DLT_NETANALYZER                = 0xf0
+	DLT_NETANALYZER_TRANSPARENT    = 0xf1
+	DLT_NETLINK                    = 0xfd
+	DLT_NFC_LLCP                   = 0xf5
+	DLT_NFLOG                      = 0xef
+	DLT_NG40                       = 0xf4
+	DLT_NULL                       = 0x0
+	DLT_PCI_EXP                    = 0x7d
+	DLT_PFLOG                      = 0x75
+	DLT_PFSYNC                     = 0x79
+	DLT_PKTAP                      = 0x102
+	DLT_PPI                        = 0xc0
+	DLT_PPP                        = 0x9
+	DLT_PPP_BSDOS                  = 0xe
+	DLT_PPP_ETHER                  = 0x33
+	DLT_PPP_PPPD                   = 0xa6
+	DLT_PPP_SERIAL                 = 0x32
+	DLT_PPP_WITH_DIR               = 0xcc
+	DLT_PPP_WITH_DIRECTION         = 0xa6
+	DLT_PRISM_HEADER               = 0x77
+	DLT_PROFIBUS_DL                = 0x101
+	DLT_PRONET                     = 0x4
+	DLT_RAIF1                      = 0xc6
+	DLT_RAW                        = 0xc
+	DLT_RDS                        = 0x109
+	DLT_REDBACK_SMARTEDGE          = 0x20
+	DLT_RIO                        = 0x7c
+	DLT_RTAC_SERIAL                = 0xfa
+	DLT_SCCP                       = 0x8e
+	DLT_SCTP                       = 0xf8
+	DLT_SITA                       = 0xc4
+	DLT_SLIP                       = 0x8
+	DLT_SLIP_BSDOS                 = 0xd
+	DLT_STANAG_5066_D_PDU          = 0xed
+	DLT_SUNATM                     = 0x7b
+	DLT_SYMANTEC_FIREWALL          = 0x63
+	DLT_TZSP                       = 0x80
+	DLT_USB                        = 0xba
+	DLT_USBPCAP                    = 0xf9
+	DLT_USB_FREEBSD                = 0xba
+	DLT_USB_LINUX                  = 0xbd
+	DLT_USB_LINUX_MMAPPED          = 0xdc
+	DLT_USER0                      = 0x93
+	DLT_USER1                      = 0x94
+	DLT_USER10                     = 0x9d
+	DLT_USER11                     = 0x9e
+	DLT_USER12                     = 0x9f
+	DLT_USER13                     = 0xa0
+	DLT_USER14                     = 0xa1
+	DLT_USER15                     = 0xa2
+	DLT_USER2                      = 0x95
+	DLT_USER3                      = 0x96
+	DLT_USER4                      = 0x97
+	DLT_USER5                      = 0x98
+	DLT_USER6                      = 0x99
+	DLT_USER7                      = 0x9a
+	DLT_USER8                      = 0x9b
+	DLT_USER9                      = 0x9c
+	DLT_WATTSTOPPER_DLM            = 0x107
+	DLT_WIHART                     = 0xdf
+	DLT_WIRESHARK_UPPER_PDU        = 0xfc
+	DLT_X2E_SERIAL                 = 0xd5
+	DLT_X2E_XORAYA                 = 0xd6
+	DLT_ZWAVE_R1_R2                = 0x105
+	DLT_ZWAVE_R3                   = 0x106
+	DT_BLK                         = 0x6
+	DT_CHR                         = 0x2
+	DT_DIR                         = 0x4
+	DT_FIFO                        = 0x1
+	DT_LNK                         = 0xa
+	DT_REG                         = 0x8
+	DT_SOCK                        = 0xc
+	DT_UNKNOWN                     = 0x0
+	DT_WHT                         = 0xe
+	ECHO                           = 0x8
+	ECHOCTL                        = 0x40
+	ECHOE                          = 0x2
+	ECHOK                          = 0x4
+	ECHOKE                         = 0x1
+	ECHONL                         = 0x10
+	ECHOPRT                        = 0x20
+	EVFILT_AIO                     = -0x3
+	EVFILT_FS                      = -0x9
+	EVFILT_LIO                     = -0xa
+	EVFILT_PROC                    = -0x5
+	EVFILT_PROCDESC                = -0x8
+	EVFILT_READ                    = -0x1
+	EVFILT_SENDFILE                = -0xc
+	EVFILT_SIGNAL                  = -0x6
+	EVFILT_SYSCOUNT                = 0xc
+	EVFILT_TIMER                   = -0x7
+	EVFILT_USER                    = -0xb
+	EVFILT_VNODE                   = -0x4
+	EVFILT_WRITE                   = -0x2
+	EV_ADD                         = 0x1
+	EV_CLEAR                       = 0x20
+	EV_DELETE                      = 0x2
+	EV_DISABLE                     = 0x8
+	EV_DISPATCH                    = 0x80
+	EV_DROP                        = 0x1000
+	EV_ENABLE                      = 0x4
+	EV_EOF                         = 0x8000
+	EV_ERROR                       = 0x4000
+	EV_FLAG1                       = 0x2000
+	EV_FLAG2                       = 0x4000
+	EV_FORCEONESHOT                = 0x100
+	EV_ONESHOT                     = 0x10
+	EV_RECEIPT                     = 0x40
+	EV_SYSFLAGS                    = 0xf000
+	EXTA                           = 0x4b00
+	EXTATTR_NAMESPACE_EMPTY        = 0x0
+	EXTATTR_NAMESPACE_SYSTEM       = 0x2
+	EXTATTR_NAMESPACE_USER         = 0x1
+	EXTB                           = 0x9600
+	EXTPROC                        = 0x800
+	FD_CLOEXEC                     = 0x1
+	FD_SETSIZE                     = 0x400
+	FLUSHO                         = 0x800000
+	F_CANCEL                       = 0x5
+	F_DUP2FD                       = 0xa
+	F_DUP2FD_CLOEXEC               = 0x12
+	F_DUPFD                        = 0x0
+	F_DUPFD_CLOEXEC                = 0x11
+	F_GETFD                        = 0x1
+	F_GETFL                        = 0x3
+	F_GETLK                        = 0xb
+	F_GETOWN                       = 0x5
+	F_OGETLK                       = 0x7
+	F_OK                           = 0x0
+	F_OSETLK                       = 0x8
+	F_OSETLKW                      = 0x9
+	F_RDAHEAD                      = 0x10
+	F_RDLCK                        = 0x1
+	F_READAHEAD                    = 0xf
+	F_SETFD                        = 0x2
+	F_SETFL                        = 0x4
+	F_SETLK                        = 0xc
+	F_SETLKW                       = 0xd
+	F_SETLK_REMOTE                 = 0xe
+	F_SETOWN                       = 0x6
+	F_UNLCK                        = 0x2
+	F_UNLCKSYS                     = 0x4
+	F_WRLCK                        = 0x3
+	HUPCL                          = 0x4000
+	ICANON                         = 0x100
+	ICMP6_FILTER                   = 0x12
+	ICRNL                          = 0x100
+	IEXTEN                         = 0x400
+	IFAN_ARRIVAL                   = 0x0
+	IFAN_DEPARTURE                 = 0x1
+	IFF_ALLMULTI                   = 0x200
+	IFF_ALTPHYS                    = 0x4000
+	IFF_BROADCAST                  = 0x2
+	IFF_CANTCHANGE                 = 0x218f52
+	IFF_CANTCONFIG                 = 0x10000
+	IFF_DEBUG                      = 0x4
+	IFF_DRV_OACTIVE                = 0x400
+	IFF_DRV_RUNNING                = 0x40
+	IFF_DYING                      = 0x200000
+	IFF_LINK0                      = 0x1000
+	IFF_LINK1                      = 0x2000
+	IFF_LINK2                      = 0x4000
+	IFF_LOOPBACK                   = 0x8
+	IFF_MONITOR                    = 0x40000
+	IFF_MULTICAST                  = 0x8000
+	IFF_NOARP                      = 0x80
+	IFF_OACTIVE                    = 0x400
+	IFF_POINTOPOINT                = 0x10
+	IFF_PPROMISC                   = 0x20000
+	IFF_PROMISC                    = 0x100
+	IFF_RENAMING                   = 0x400000
+	IFF_RUNNING                    = 0x40
+	IFF_SIMPLEX                    = 0x800
+	IFF_STATICARP                  = 0x80000
+	IFF_UP                         = 0x1
+	IFNAMSIZ                       = 0x10
+	IFT_BRIDGE                     = 0xd1
+	IFT_CARP                       = 0xf8
+	IFT_IEEE1394                   = 0x90
+	IFT_INFINIBAND                 = 0xc7
+	IFT_L2VLAN                     = 0x87
+	IFT_L3IPVLAN                   = 0x88
+	IFT_PPP                        = 0x17
+	IFT_PROPVIRTUAL                = 0x35
+	IGNBRK                         = 0x1
+	IGNCR                          = 0x80
+	IGNPAR                         = 0x4
+	IMAXBEL                        = 0x2000
+	INLCR                          = 0x40
+	INPCK                          = 0x10
+	IN_CLASSA_HOST                 = 0xffffff
+	IN_CLASSA_MAX                  = 0x80
+	IN_CLASSA_NET                  = 0xff000000
+	IN_CLASSA_NSHIFT               = 0x18
+	IN_CLASSB_HOST                 = 0xffff
+	IN_CLASSB_MAX                  = 0x10000
+	IN_CLASSB_NET                  = 0xffff0000
+	IN_CLASSB_NSHIFT               = 0x10
+	IN_CLASSC_HOST                 = 0xff
+	IN_CLASSC_NET                  = 0xffffff00
+	IN_CLASSC_NSHIFT               = 0x8
+	IN_CLASSD_HOST                 = 0xfffffff
+	IN_CLASSD_NET                  = 0xf0000000
+	IN_CLASSD_NSHIFT               = 0x1c
+	IN_LOOPBACKNET                 = 0x7f
+	IN_RFC3021_MASK                = 0xfffffffe
+	IPPROTO_3PC                    = 0x22
+	IPPROTO_ADFS                   = 0x44
+	IPPROTO_AH                     = 0x33
+	IPPROTO_AHIP                   = 0x3d
+	IPPROTO_APES                   = 0x63
+	IPPROTO_ARGUS                  = 0xd
+	IPPROTO_AX25                   = 0x5d
+	IPPROTO_BHA                    = 0x31
+	IPPROTO_BLT                    = 0x1e
+	IPPROTO_BRSATMON               = 0x4c
+	IPPROTO_CARP                   = 0x70
+	IPPROTO_CFTP                   = 0x3e
+	IPPROTO_CHAOS                  = 0x10
+	IPPROTO_CMTP                   = 0x26
+	IPPROTO_CPHB                   = 0x49
+	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DDP                    = 0x25
+	IPPROTO_DGP                    = 0x56
+	IPPROTO_DIVERT                 = 0x102
+	IPPROTO_DONE                   = 0x101
+	IPPROTO_DSTOPTS                = 0x3c
+	IPPROTO_EGP                    = 0x8
+	IPPROTO_EMCON                  = 0xe
+	IPPROTO_ENCAP                  = 0x62
+	IPPROTO_EON                    = 0x50
+	IPPROTO_ESP                    = 0x32
+	IPPROTO_ETHERIP                = 0x61
+	IPPROTO_FRAGMENT               = 0x2c
+	IPPROTO_GGP                    = 0x3
+	IPPROTO_GMTP                   = 0x64
+	IPPROTO_GRE                    = 0x2f
+	IPPROTO_HELLO                  = 0x3f
+	IPPROTO_HIP                    = 0x8b
+	IPPROTO_HMP                    = 0x14
+	IPPROTO_HOPOPTS                = 0x0
+	IPPROTO_ICMP                   = 0x1
+	IPPROTO_ICMPV6                 = 0x3a
+	IPPROTO_IDP                    = 0x16
+	IPPROTO_IDPR                   = 0x23
+	IPPROTO_IDRP                   = 0x2d
+	IPPROTO_IGMP                   = 0x2
+	IPPROTO_IGP                    = 0x55
+	IPPROTO_IGRP                   = 0x58
+	IPPROTO_IL                     = 0x28
+	IPPROTO_INLSP                  = 0x34
+	IPPROTO_INP                    = 0x20
+	IPPROTO_IP                     = 0x0
+	IPPROTO_IPCOMP                 = 0x6c
+	IPPROTO_IPCV                   = 0x47
+	IPPROTO_IPEIP                  = 0x5e
+	IPPROTO_IPIP                   = 0x4
+	IPPROTO_IPPC                   = 0x43
+	IPPROTO_IPV4                   = 0x4
+	IPPROTO_IPV6                   = 0x29
+	IPPROTO_IRTP                   = 0x1c
+	IPPROTO_KRYPTOLAN              = 0x41
+	IPPROTO_LARP                   = 0x5b
+	IPPROTO_LEAF1                  = 0x19
+	IPPROTO_LEAF2                  = 0x1a
+	IPPROTO_MAX                    = 0x100
+	IPPROTO_MEAS                   = 0x13
+	IPPROTO_MH                     = 0x87
+	IPPROTO_MHRP                   = 0x30
+	IPPROTO_MICP                   = 0x5f
+	IPPROTO_MOBILE                 = 0x37
+	IPPROTO_MPLS                   = 0x89
+	IPPROTO_MTP                    = 0x5c
+	IPPROTO_MUX                    = 0x12
+	IPPROTO_ND                     = 0x4d
+	IPPROTO_NHRP                   = 0x36
+	IPPROTO_NONE                   = 0x3b
+	IPPROTO_NSP                    = 0x1f
+	IPPROTO_NVPII                  = 0xb
+	IPPROTO_OLD_DIVERT             = 0xfe
+	IPPROTO_OSPFIGP                = 0x59
+	IPPROTO_PFSYNC                 = 0xf0
+	IPPROTO_PGM                    = 0x71
+	IPPROTO_PIGP                   = 0x9
+	IPPROTO_PIM                    = 0x67
+	IPPROTO_PRM                    = 0x15
+	IPPROTO_PUP                    = 0xc
+	IPPROTO_PVP                    = 0x4b
+	IPPROTO_RAW                    = 0xff
+	IPPROTO_RCCMON                 = 0xa
+	IPPROTO_RDP                    = 0x1b
+	IPPROTO_RESERVED_253           = 0xfd
+	IPPROTO_RESERVED_254           = 0xfe
+	IPPROTO_ROUTING                = 0x2b
+	IPPROTO_RSVP                   = 0x2e
+	IPPROTO_RVD                    = 0x42
+	IPPROTO_SATEXPAK               = 0x40
+	IPPROTO_SATMON                 = 0x45
+	IPPROTO_SCCSP                  = 0x60
+	IPPROTO_SCTP                   = 0x84
+	IPPROTO_SDRP                   = 0x2a
+	IPPROTO_SEND                   = 0x103
+	IPPROTO_SEP                    = 0x21
+	IPPROTO_SHIM6                  = 0x8c
+	IPPROTO_SKIP                   = 0x39
+	IPPROTO_SPACER                 = 0x7fff
+	IPPROTO_SRPC                   = 0x5a
+	IPPROTO_ST                     = 0x7
+	IPPROTO_SVMTP                  = 0x52
+	IPPROTO_SWIPE                  = 0x35
+	IPPROTO_TCF                    = 0x57
+	IPPROTO_TCP                    = 0x6
+	IPPROTO_TLSP                   = 0x38
+	IPPROTO_TP                     = 0x1d
+	IPPROTO_TPXX                   = 0x27
+	IPPROTO_TRUNK1                 = 0x17
+	IPPROTO_TRUNK2                 = 0x18
+	IPPROTO_TTP                    = 0x54
+	IPPROTO_UDP                    = 0x11
+	IPPROTO_UDPLITE                = 0x88
+	IPPROTO_VINES                  = 0x53
+	IPPROTO_VISA                   = 0x46
+	IPPROTO_VMTP                   = 0x51
+	IPPROTO_WBEXPAK                = 0x4f
+	IPPROTO_WBMON                  = 0x4e
+	IPPROTO_WSN                    = 0x4a
+	IPPROTO_XNET                   = 0xf
+	IPPROTO_XTP                    = 0x24
+	IPV6_AUTOFLOWLABEL             = 0x3b
+	IPV6_BINDANY                   = 0x40
+	IPV6_BINDMULTI                 = 0x41
+	IPV6_BINDV6ONLY                = 0x1b
+	IPV6_CHECKSUM                  = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS    = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP    = 0x1
+	IPV6_DEFHLIM                   = 0x40
+	IPV6_DONTFRAG                  = 0x3e
+	IPV6_DSTOPTS                   = 0x32
+	IPV6_FLOWID                    = 0x43
+	IPV6_FLOWINFO_MASK             = 0xffffff0f
+	IPV6_FLOWLABEL_MASK            = 0xffff0f00
+	IPV6_FLOWTYPE                  = 0x44
+	IPV6_FRAGTTL                   = 0x78
+	IPV6_FW_ADD                    = 0x1e
+	IPV6_FW_DEL                    = 0x1f
+	IPV6_FW_FLUSH                  = 0x20
+	IPV6_FW_GET                    = 0x22
+	IPV6_FW_ZERO                   = 0x21
+	IPV6_HLIMDEC                   = 0x1
+	IPV6_HOPLIMIT                  = 0x2f
+	IPV6_HOPOPTS                   = 0x31
+	IPV6_IPSEC_POLICY              = 0x1c
+	IPV6_JOIN_GROUP                = 0xc
+	IPV6_LEAVE_GROUP               = 0xd
+	IPV6_MAXHLIM                   = 0xff
+	IPV6_MAXOPTHDR                 = 0x800
+	IPV6_MAXPACKET                 = 0xffff
+	IPV6_MAX_GROUP_SRC_FILTER      = 0x200
+	IPV6_MAX_MEMBERSHIPS           = 0xfff
+	IPV6_MAX_SOCK_SRC_FILTER       = 0x80
+	IPV6_MIN_MEMBERSHIPS           = 0x1f
+	IPV6_MMTU                      = 0x500
+	IPV6_MSFILTER                  = 0x4a
+	IPV6_MULTICAST_HOPS            = 0xa
+	IPV6_MULTICAST_IF              = 0x9
+	IPV6_MULTICAST_LOOP            = 0xb
+	IPV6_NEXTHOP                   = 0x30
+	IPV6_PATHMTU                   = 0x2c
+	IPV6_PKTINFO                   = 0x2e
+	IPV6_PORTRANGE                 = 0xe
+	IPV6_PORTRANGE_DEFAULT         = 0x0
+	IPV6_PORTRANGE_HIGH            = 0x1
+	IPV6_PORTRANGE_LOW             = 0x2
+	IPV6_PREFER_TEMPADDR           = 0x3f
+	IPV6_RECVDSTOPTS               = 0x28
+	IPV6_RECVFLOWID                = 0x46
+	IPV6_RECVHOPLIMIT              = 0x25
+	IPV6_RECVHOPOPTS               = 0x27
+	IPV6_RECVPATHMTU               = 0x2b
+	IPV6_RECVPKTINFO               = 0x24
+	IPV6_RECVRSSBUCKETID           = 0x47
+	IPV6_RECVRTHDR                 = 0x26
+	IPV6_RECVTCLASS                = 0x39
+	IPV6_RSSBUCKETID               = 0x45
+	IPV6_RSS_LISTEN_BUCKET         = 0x42
+	IPV6_RTHDR                     = 0x33
+	IPV6_RTHDRDSTOPTS              = 0x23
+	IPV6_RTHDR_LOOSE               = 0x0
+	IPV6_RTHDR_STRICT              = 0x1
+	IPV6_RTHDR_TYPE_0              = 0x0
+	IPV6_SOCKOPT_RESERVED1         = 0x3
+	IPV6_TCLASS                    = 0x3d
+	IPV6_UNICAST_HOPS              = 0x4
+	IPV6_USE_MIN_MTU               = 0x2a
+	IPV6_V6ONLY                    = 0x1b
+	IPV6_VERSION                   = 0x60
+	IPV6_VERSION_MASK              = 0xf0
+	IP_ADD_MEMBERSHIP              = 0xc
+	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
+	IP_BINDANY                     = 0x18
+	IP_BINDMULTI                   = 0x19
+	IP_BLOCK_SOURCE                = 0x48
+	IP_DEFAULT_MULTICAST_LOOP      = 0x1
+	IP_DEFAULT_MULTICAST_TTL       = 0x1
+	IP_DF                          = 0x4000
+	IP_DONTFRAG                    = 0x43
+	IP_DROP_MEMBERSHIP             = 0xd
+	IP_DROP_SOURCE_MEMBERSHIP      = 0x47
+	IP_DUMMYNET3                   = 0x31
+	IP_DUMMYNET_CONFIGURE          = 0x3c
+	IP_DUMMYNET_DEL                = 0x3d
+	IP_DUMMYNET_FLUSH              = 0x3e
+	IP_DUMMYNET_GET                = 0x40
+	IP_FLOWID                      = 0x5a
+	IP_FLOWTYPE                    = 0x5b
+	IP_FW3                         = 0x30
+	IP_FW_ADD                      = 0x32
+	IP_FW_DEL                      = 0x33
+	IP_FW_FLUSH                    = 0x34
+	IP_FW_GET                      = 0x36
+	IP_FW_NAT_CFG                  = 0x38
+	IP_FW_NAT_DEL                  = 0x39
+	IP_FW_NAT_GET_CONFIG           = 0x3a
+	IP_FW_NAT_GET_LOG              = 0x3b
+	IP_FW_RESETLOG                 = 0x37
+	IP_FW_TABLE_ADD                = 0x28
+	IP_FW_TABLE_DEL                = 0x29
+	IP_FW_TABLE_FLUSH              = 0x2a
+	IP_FW_TABLE_GETSIZE            = 0x2b
+	IP_FW_TABLE_LIST               = 0x2c
+	IP_FW_ZERO                     = 0x35
+	IP_HDRINCL                     = 0x2
+	IP_IPSEC_POLICY                = 0x15
+	IP_MAXPACKET                   = 0xffff
+	IP_MAX_GROUP_SRC_FILTER        = 0x200
+	IP_MAX_MEMBERSHIPS             = 0xfff
+	IP_MAX_SOCK_MUTE_FILTER        = 0x80
+	IP_MAX_SOCK_SRC_FILTER         = 0x80
+	IP_MAX_SOURCE_FILTER           = 0x400
+	IP_MF                          = 0x2000
+	IP_MINTTL                      = 0x42
+	IP_MIN_MEMBERSHIPS             = 0x1f
+	IP_MSFILTER                    = 0x4a
+	IP_MSS                         = 0x240
+	IP_MULTICAST_IF                = 0x9
+	IP_MULTICAST_LOOP              = 0xb
+	IP_MULTICAST_TTL               = 0xa
+	IP_MULTICAST_VIF               = 0xe
+	IP_OFFMASK                     = 0x1fff
+	IP_ONESBCAST                   = 0x17
+	IP_OPTIONS                     = 0x1
+	IP_PORTRANGE                   = 0x13
+	IP_PORTRANGE_DEFAULT           = 0x0
+	IP_PORTRANGE_HIGH              = 0x1
+	IP_PORTRANGE_LOW               = 0x2
+	IP_RECVDSTADDR                 = 0x7
+	IP_RECVFLOWID                  = 0x5d
+	IP_RECVIF                      = 0x14
+	IP_RECVOPTS                    = 0x5
+	IP_RECVRETOPTS                 = 0x6
+	IP_RECVRSSBUCKETID             = 0x5e
+	IP_RECVTOS                     = 0x44
+	IP_RECVTTL                     = 0x41
+	IP_RETOPTS                     = 0x8
+	IP_RF                          = 0x8000
+	IP_RSSBUCKETID                 = 0x5c
+	IP_RSS_LISTEN_BUCKET           = 0x1a
+	IP_RSVP_OFF                    = 0x10
+	IP_RSVP_ON                     = 0xf
+	IP_RSVP_VIF_OFF                = 0x12
+	IP_RSVP_VIF_ON                 = 0x11
+	IP_SENDSRCADDR                 = 0x7
+	IP_TOS                         = 0x3
+	IP_TTL                         = 0x4
+	IP_UNBLOCK_SOURCE              = 0x49
+	ISIG                           = 0x80
+	ISTRIP                         = 0x20
+	IXANY                          = 0x800
+	IXOFF                          = 0x400
+	IXON                           = 0x200
+	LOCK_EX                        = 0x2
+	LOCK_NB                        = 0x4
+	LOCK_SH                        = 0x1
+	LOCK_UN                        = 0x8
+	MADV_AUTOSYNC                  = 0x7
+	MADV_CORE                      = 0x9
+	MADV_DONTNEED                  = 0x4
+	MADV_FREE                      = 0x5
+	MADV_NOCORE                    = 0x8
+	MADV_NORMAL                    = 0x0
+	MADV_NOSYNC                    = 0x6
+	MADV_PROTECT                   = 0xa
+	MADV_RANDOM                    = 0x1
+	MADV_SEQUENTIAL                = 0x2
+	MADV_WILLNEED                  = 0x3
+	MAP_ALIGNED_SUPER              = 0x1000000
+	MAP_ALIGNMENT_MASK             = -0x1000000
+	MAP_ALIGNMENT_SHIFT            = 0x18
+	MAP_ANON                       = 0x1000
+	MAP_ANONYMOUS                  = 0x1000
+	MAP_COPY                       = 0x2
+	MAP_EXCL                       = 0x4000
+	MAP_FILE                       = 0x0
+	MAP_FIXED                      = 0x10
+	MAP_GUARD                      = 0x2000
+	MAP_HASSEMAPHORE               = 0x200
+	MAP_NOCORE                     = 0x20000
+	MAP_NOSYNC                     = 0x800
+	MAP_PREFAULT_READ              = 0x40000
+	MAP_PRIVATE                    = 0x2
+	MAP_RESERVED0020               = 0x20
+	MAP_RESERVED0040               = 0x40
+	MAP_RESERVED0080               = 0x80
+	MAP_RESERVED0100               = 0x100
+	MAP_SHARED                     = 0x1
+	MAP_STACK                      = 0x400
+	MCL_CURRENT                    = 0x1
+	MCL_FUTURE                     = 0x2
+	MSG_CMSG_CLOEXEC               = 0x40000
+	MSG_COMPAT                     = 0x8000
+	MSG_CTRUNC                     = 0x20
+	MSG_DONTROUTE                  = 0x4
+	MSG_DONTWAIT                   = 0x80
+	MSG_EOF                        = 0x100
+	MSG_EOR                        = 0x8
+	MSG_NBIO                       = 0x4000
+	MSG_NOSIGNAL                   = 0x20000
+	MSG_NOTIFICATION               = 0x2000
+	MSG_OOB                        = 0x1
+	MSG_PEEK                       = 0x2
+	MSG_TRUNC                      = 0x10
+	MSG_WAITALL                    = 0x40
+	MSG_WAITFORONE                 = 0x80000
+	MS_ASYNC                       = 0x1
+	MS_INVALIDATE                  = 0x2
+	MS_SYNC                        = 0x0
+	NAME_MAX                       = 0xff
+	NET_RT_DUMP                    = 0x1
+	NET_RT_FLAGS                   = 0x2
+	NET_RT_IFLIST                  = 0x3
+	NET_RT_IFLISTL                 = 0x5
+	NET_RT_IFMALIST                = 0x4
+	NOFLSH                         = 0x80000000
+	NOKERNINFO                     = 0x2000000
+	NOTE_ATTRIB                    = 0x8
+	NOTE_CHILD                     = 0x4
+	NOTE_CLOSE                     = 0x100
+	NOTE_CLOSE_WRITE               = 0x200
+	NOTE_DELETE                    = 0x1
+	NOTE_EXEC                      = 0x20000000
+	NOTE_EXIT                      = 0x80000000
+	NOTE_EXTEND                    = 0x4
+	NOTE_FFAND                     = 0x40000000
+	NOTE_FFCOPY                    = 0xc0000000
+	NOTE_FFCTRLMASK                = 0xc0000000
+	NOTE_FFLAGSMASK                = 0xffffff
+	NOTE_FFNOP                     = 0x0
+	NOTE_FFOR                      = 0x80000000
+	NOTE_FILE_POLL                 = 0x2
+	NOTE_FORK                      = 0x40000000
+	NOTE_LINK                      = 0x10
+	NOTE_LOWAT                     = 0x1
+	NOTE_MSECONDS                  = 0x2
+	NOTE_NSECONDS                  = 0x8
+	NOTE_OPEN                      = 0x80
+	NOTE_PCTRLMASK                 = 0xf0000000
+	NOTE_PDATAMASK                 = 0xfffff
+	NOTE_READ                      = 0x400
+	NOTE_RENAME                    = 0x20
+	NOTE_REVOKE                    = 0x40
+	NOTE_SECONDS                   = 0x1
+	NOTE_TRACK                     = 0x1
+	NOTE_TRACKERR                  = 0x2
+	NOTE_TRIGGER                   = 0x1000000
+	NOTE_USECONDS                  = 0x4
+	NOTE_WRITE                     = 0x2
+	OCRNL                          = 0x10
+	ONLCR                          = 0x2
+	ONLRET                         = 0x40
+	ONOCR                          = 0x20
+	ONOEOT                         = 0x8
+	OPOST                          = 0x1
+	OXTABS                         = 0x4
+	O_ACCMODE                      = 0x3
+	O_APPEND                       = 0x8
+	O_ASYNC                        = 0x40
+	O_CLOEXEC                      = 0x100000
+	O_CREAT                        = 0x200
+	O_DIRECT                       = 0x10000
+	O_DIRECTORY                    = 0x20000
+	O_EXCL                         = 0x800
+	O_EXEC                         = 0x40000
+	O_EXLOCK                       = 0x20
+	O_FSYNC                        = 0x80
+	O_NDELAY                       = 0x4
+	O_NOCTTY                       = 0x8000
+	O_NOFOLLOW                     = 0x100
+	O_NONBLOCK                     = 0x4
+	O_RDONLY                       = 0x0
+	O_RDWR                         = 0x2
+	O_SHLOCK                       = 0x10
+	O_SYNC                         = 0x80
+	O_TRUNC                        = 0x400
+	O_TTY_INIT                     = 0x80000
+	O_VERIFY                       = 0x200000
+	O_WRONLY                       = 0x1
+	PARENB                         = 0x1000
+	PARMRK                         = 0x8
+	PARODD                         = 0x2000
+	PENDIN                         = 0x20000000
+	PRIO_PGRP                      = 0x1
+	PRIO_PROCESS                   = 0x0
+	PRIO_USER                      = 0x2
+	PROT_EXEC                      = 0x4
+	PROT_NONE                      = 0x0
+	PROT_READ                      = 0x1
+	PROT_WRITE                     = 0x2
+	RLIMIT_AS                      = 0xa
+	RLIMIT_CORE                    = 0x4
+	RLIMIT_CPU                     = 0x0
+	RLIMIT_DATA                    = 0x2
+	RLIMIT_FSIZE                   = 0x1
+	RLIMIT_MEMLOCK                 = 0x6
+	RLIMIT_NOFILE                  = 0x8
+	RLIMIT_NPROC                   = 0x7
+	RLIMIT_RSS                     = 0x5
+	RLIMIT_STACK                   = 0x3
+	RLIM_INFINITY                  = 0x7fffffffffffffff
+	RTAX_AUTHOR                    = 0x6
+	RTAX_BRD                       = 0x7
+	RTAX_DST                       = 0x0
+	RTAX_GATEWAY                   = 0x1
+	RTAX_GENMASK                   = 0x3
+	RTAX_IFA                       = 0x5
+	RTAX_IFP                       = 0x4
+	RTAX_MAX                       = 0x8
+	RTAX_NETMASK                   = 0x2
+	RTA_AUTHOR                     = 0x40
+	RTA_BRD                        = 0x80
+	RTA_DST                        = 0x1
+	RTA_GATEWAY                    = 0x2
+	RTA_GENMASK                    = 0x8
+	RTA_IFA                        = 0x20
+	RTA_IFP                        = 0x10
+	RTA_NETMASK                    = 0x4
+	RTF_BLACKHOLE                  = 0x1000
+	RTF_BROADCAST                  = 0x400000
+	RTF_DONE                       = 0x40
+	RTF_DYNAMIC                    = 0x10
+	RTF_FIXEDMTU                   = 0x80000
+	RTF_FMASK                      = 0x1004d808
+	RTF_GATEWAY                    = 0x2
+	RTF_GWFLAG_COMPAT              = 0x80000000
+	RTF_HOST                       = 0x4
+	RTF_LLDATA                     = 0x400
+	RTF_LLINFO                     = 0x400
+	RTF_LOCAL                      = 0x200000
+	RTF_MODIFIED                   = 0x20
+	RTF_MULTICAST                  = 0x800000
+	RTF_PINNED                     = 0x100000
+	RTF_PROTO1                     = 0x8000
+	RTF_PROTO2                     = 0x4000
+	RTF_PROTO3                     = 0x40000
+	RTF_REJECT                     = 0x8
+	RTF_RNH_LOCKED                 = 0x40000000
+	RTF_STATIC                     = 0x800
+	RTF_STICKY                     = 0x10000000
+	RTF_UP                         = 0x1
+	RTF_XRESOLVE                   = 0x200
+	RTM_ADD                        = 0x1
+	RTM_CHANGE                     = 0x3
+	RTM_DELADDR                    = 0xd
+	RTM_DELETE                     = 0x2
+	RTM_DELMADDR                   = 0x10
+	RTM_GET                        = 0x4
+	RTM_IEEE80211                  = 0x12
+	RTM_IFANNOUNCE                 = 0x11
+	RTM_IFINFO                     = 0xe
+	RTM_LOCK                       = 0x8
+	RTM_LOSING                     = 0x5
+	RTM_MISS                       = 0x7
+	RTM_NEWADDR                    = 0xc
+	RTM_NEWMADDR                   = 0xf
+	RTM_REDIRECT                   = 0x6
+	RTM_RESOLVE                    = 0xb
+	RTM_RTTUNIT                    = 0xf4240
+	RTM_VERSION                    = 0x5
+	RTV_EXPIRE                     = 0x4
+	RTV_HOPCOUNT                   = 0x2
+	RTV_MTU                        = 0x1
+	RTV_RPIPE                      = 0x8
+	RTV_RTT                        = 0x40
+	RTV_RTTVAR                     = 0x80
+	RTV_SPIPE                      = 0x10
+	RTV_SSTHRESH                   = 0x20
+	RTV_WEIGHT                     = 0x100
+	RT_ALL_FIBS                    = -0x1
+	RT_BLACKHOLE                   = 0x40
+	RT_CACHING_CONTEXT             = 0x1
+	RT_DEFAULT_FIB                 = 0x0
+	RT_HAS_GW                      = 0x80
+	RT_HAS_HEADER                  = 0x10
+	RT_HAS_HEADER_BIT              = 0x4
+	RT_L2_ME                       = 0x4
+	RT_L2_ME_BIT                   = 0x2
+	RT_LLE_CACHE                   = 0x100
+	RT_MAY_LOOP                    = 0x8
+	RT_MAY_LOOP_BIT                = 0x3
+	RT_NORTREF                     = 0x2
+	RT_REJECT                      = 0x20
+	RUSAGE_CHILDREN                = -0x1
+	RUSAGE_SELF                    = 0x0
+	RUSAGE_THREAD                  = 0x1
+	SCM_BINTIME                    = 0x4
+	SCM_CREDS                      = 0x3
+	SCM_RIGHTS                     = 0x1
+	SCM_TIMESTAMP                  = 0x2
+	SHUT_RD                        = 0x0
+	SHUT_RDWR                      = 0x2
+	SHUT_WR                        = 0x1
+	SIOCADDMULTI                   = 0x80206931
+	SIOCAIFADDR                    = 0x8040691a
+	SIOCAIFGROUP                   = 0x80246987
+	SIOCATMARK                     = 0x40047307
+	SIOCDELMULTI                   = 0x80206932
+	SIOCDIFADDR                    = 0x80206919
+	SIOCDIFGROUP                   = 0x80246989
+	SIOCDIFPHYADDR                 = 0x80206949
+	SIOCGDRVSPEC                   = 0xc01c697b
+	SIOCGETSGCNT                   = 0xc0147210
+	SIOCGETVIFCNT                  = 0xc014720f
+	SIOCGHIWAT                     = 0x40047301
+	SIOCGHWADDR                    = 0xc020693e
+	SIOCGI2C                       = 0xc020693d
+	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFBRDADDR                 = 0xc0206923
+	SIOCGIFCAP                     = 0xc020691f
+	SIOCGIFCONF                    = 0xc0086924
+	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDSTADDR                 = 0xc0206922
+	SIOCGIFFIB                     = 0xc020695c
+	SIOCGIFFLAGS                   = 0xc0206911
+	SIOCGIFGENERIC                 = 0xc020693a
+	SIOCGIFGMEMB                   = 0xc024698a
+	SIOCGIFGROUP                   = 0xc0246988
+	SIOCGIFINDEX                   = 0xc0206920
+	SIOCGIFMAC                     = 0xc0206926
+	SIOCGIFMEDIA                   = 0xc0286938
+	SIOCGIFMETRIC                  = 0xc0206917
+	SIOCGIFMTU                     = 0xc0206933
+	SIOCGIFNETMASK                 = 0xc0206925
+	SIOCGIFPDSTADDR                = 0xc0206948
+	SIOCGIFPHYS                    = 0xc0206935
+	SIOCGIFPSRCADDR                = 0xc0206947
+	SIOCGIFSTATUS                  = 0xc331693b
+	SIOCGIFXMEDIA                  = 0xc028698b
+	SIOCGLOWAT                     = 0x40047303
+	SIOCGPGRP                      = 0x40047309
+	SIOCGPRIVATE_0                 = 0xc0206950
+	SIOCGPRIVATE_1                 = 0xc0206951
+	SIOCGTUNFIB                    = 0xc020695e
+	SIOCIFCREATE                   = 0xc020697a
+	SIOCIFCREATE2                  = 0xc020697c
+	SIOCIFDESTROY                  = 0x80206979
+	SIOCIFGCLONERS                 = 0xc00c6978
+	SIOCSDRVSPEC                   = 0x801c697b
+	SIOCSHIWAT                     = 0x80047300
+	SIOCSIFADDR                    = 0x8020690c
+	SIOCSIFBRDADDR                 = 0x80206913
+	SIOCSIFCAP                     = 0x8020691e
+	SIOCSIFDESCR                   = 0x80206929
+	SIOCSIFDSTADDR                 = 0x8020690e
+	SIOCSIFFIB                     = 0x8020695d
+	SIOCSIFFLAGS                   = 0x80206910
+	SIOCSIFGENERIC                 = 0x80206939
+	SIOCSIFLLADDR                  = 0x8020693c
+	SIOCSIFMAC                     = 0x80206927
+	SIOCSIFMEDIA                   = 0xc0206937
+	SIOCSIFMETRIC                  = 0x80206918
+	SIOCSIFMTU                     = 0x80206934
+	SIOCSIFNAME                    = 0x80206928
+	SIOCSIFNETMASK                 = 0x80206916
+	SIOCSIFPHYADDR                 = 0x80406946
+	SIOCSIFPHYS                    = 0x80206936
+	SIOCSIFRVNET                   = 0xc020695b
+	SIOCSIFVNET                    = 0xc020695a
+	SIOCSLOWAT                     = 0x80047302
+	SIOCSPGRP                      = 0x80047308
+	SIOCSTUNFIB                    = 0x8020695f
+	SOCK_CLOEXEC                   = 0x10000000
+	SOCK_DGRAM                     = 0x2
+	SOCK_MAXADDRLEN                = 0xff
+	SOCK_NONBLOCK                  = 0x20000000
+	SOCK_RAW                       = 0x3
+	SOCK_RDM                       = 0x4
+	SOCK_SEQPACKET                 = 0x5
+	SOCK_STREAM                    = 0x1
+	SOL_SOCKET                     = 0xffff
+	SOMAXCONN                      = 0x80
+	SO_ACCEPTCONN                  = 0x2
+	SO_ACCEPTFILTER                = 0x1000
+	SO_BINTIME                     = 0x2000
+	SO_BROADCAST                   = 0x20
+	SO_DEBUG                       = 0x1
+	SO_DONTROUTE                   = 0x10
+	SO_ERROR                       = 0x1007
+	SO_KEEPALIVE                   = 0x8
+	SO_LABEL                       = 0x1009
+	SO_LINGER                      = 0x80
+	SO_LISTENINCQLEN               = 0x1013
+	SO_LISTENQLEN                  = 0x1012
+	SO_LISTENQLIMIT                = 0x1011
+	SO_NOSIGPIPE                   = 0x800
+	SO_NO_DDP                      = 0x8000
+	SO_NO_OFFLOAD                  = 0x4000
+	SO_OOBINLINE                   = 0x100
+	SO_PEERLABEL                   = 0x1010
+	SO_PROTOCOL                    = 0x1016
+	SO_PROTOTYPE                   = 0x1016
+	SO_RCVBUF                      = 0x1002
+	SO_RCVLOWAT                    = 0x1004
+	SO_RCVTIMEO                    = 0x1006
+	SO_REUSEADDR                   = 0x4
+	SO_REUSEPORT                   = 0x200
+	SO_SETFIB                      = 0x1014
+	SO_SNDBUF                      = 0x1001
+	SO_SNDLOWAT                    = 0x1003
+	SO_SNDTIMEO                    = 0x1005
+	SO_TIMESTAMP                   = 0x400
+	SO_TYPE                        = 0x1008
+	SO_USELOOPBACK                 = 0x40
+	SO_USER_COOKIE                 = 0x1015
+	SO_VENDOR                      = 0x80000000
+	TAB0                           = 0x0
+	TAB3                           = 0x4
+	TABDLY                         = 0x4
+	TCIFLUSH                       = 0x1
+	TCIOFF                         = 0x3
+	TCIOFLUSH                      = 0x3
+	TCION                          = 0x4
+	TCOFLUSH                       = 0x2
+	TCOOFF                         = 0x1
+	TCOON                          = 0x2
+	TCP_CA_NAME_MAX                = 0x10
+	TCP_CCALGOOPT                  = 0x41
+	TCP_CONGESTION                 = 0x40
+	TCP_FASTOPEN                   = 0x401
+	TCP_FUNCTION_BLK               = 0x2000
+	TCP_FUNCTION_NAME_LEN_MAX      = 0x20
+	TCP_INFO                       = 0x20
+	TCP_KEEPCNT                    = 0x400
+	TCP_KEEPIDLE                   = 0x100
+	TCP_KEEPINIT                   = 0x80
+	TCP_KEEPINTVL                  = 0x200
+	TCP_MAXBURST                   = 0x4
+	TCP_MAXHLEN                    = 0x3c
+	TCP_MAXOLEN                    = 0x28
+	TCP_MAXSEG                     = 0x2
+	TCP_MAXWIN                     = 0xffff
+	TCP_MAX_SACK                   = 0x4
+	TCP_MAX_WINSHIFT               = 0xe
+	TCP_MD5SIG                     = 0x10
+	TCP_MINMSS                     = 0xd8
+	TCP_MSS                        = 0x218
+	TCP_NODELAY                    = 0x1
+	TCP_NOOPT                      = 0x8
+	TCP_NOPUSH                     = 0x4
+	TCP_PCAP_IN                    = 0x1000
+	TCP_PCAP_OUT                   = 0x800
+	TCP_VENDOR                     = 0x80000000
+	TCSAFLUSH                      = 0x2
+	TIOCCBRK                       = 0x2000747a
+	TIOCCDTR                       = 0x20007478
+	TIOCCONS                       = 0x80047462
+	TIOCDRAIN                      = 0x2000745e
+	TIOCEXCL                       = 0x2000740d
+	TIOCEXT                        = 0x80047460
+	TIOCFLUSH                      = 0x80047410
+	TIOCGDRAINWAIT                 = 0x40047456
+	TIOCGETA                       = 0x402c7413
+	TIOCGETD                       = 0x4004741a
+	TIOCGPGRP                      = 0x40047477
+	TIOCGPTN                       = 0x4004740f
+	TIOCGSID                       = 0x40047463
+	TIOCGWINSZ                     = 0x40087468
+	TIOCMBIC                       = 0x8004746b
+	TIOCMBIS                       = 0x8004746c
+	TIOCMGDTRWAIT                  = 0x4004745a
+	TIOCMGET                       = 0x4004746a
+	TIOCMSDTRWAIT                  = 0x8004745b
+	TIOCMSET                       = 0x8004746d
+	TIOCM_CAR                      = 0x40
+	TIOCM_CD                       = 0x40
+	TIOCM_CTS                      = 0x20
+	TIOCM_DCD                      = 0x40
+	TIOCM_DSR                      = 0x100
+	TIOCM_DTR                      = 0x2
+	TIOCM_LE                       = 0x1
+	TIOCM_RI                       = 0x80
+	TIOCM_RNG                      = 0x80
+	TIOCM_RTS                      = 0x4
+	TIOCM_SR                       = 0x10
+	TIOCM_ST                       = 0x8
+	TIOCNOTTY                      = 0x20007471
+	TIOCNXCL                       = 0x2000740e
+	TIOCOUTQ                       = 0x40047473
+	TIOCPKT                        = 0x80047470
+	TIOCPKT_DATA                   = 0x0
+	TIOCPKT_DOSTOP                 = 0x20
+	TIOCPKT_FLUSHREAD              = 0x1
+	TIOCPKT_FLUSHWRITE             = 0x2
+	TIOCPKT_IOCTL                  = 0x40
+	TIOCPKT_NOSTOP                 = 0x10
+	TIOCPKT_START                  = 0x8
+	TIOCPKT_STOP                   = 0x4
+	TIOCPTMASTER                   = 0x2000741c
+	TIOCSBRK                       = 0x2000747b
+	TIOCSCTTY                      = 0x20007461
+	TIOCSDRAINWAIT                 = 0x80047457
+	TIOCSDTR                       = 0x20007479
+	TIOCSETA                       = 0x802c7414
+	TIOCSETAF                      = 0x802c7416
+	TIOCSETAW                      = 0x802c7415
+	TIOCSETD                       = 0x8004741b
+	TIOCSIG                        = 0x2004745f
+	TIOCSPGRP                      = 0x80047476
+	TIOCSTART                      = 0x2000746e
+	TIOCSTAT                       = 0x20007465
+	TIOCSTI                        = 0x80017472
+	TIOCSTOP                       = 0x2000746f
+	TIOCSWINSZ                     = 0x80087467
+	TIOCTIMESTAMP                  = 0x40107459
+	TIOCUCNTL                      = 0x80047466
+	TOSTOP                         = 0x400000
+	VDISCARD                       = 0xf
+	VDSUSP                         = 0xb
+	VEOF                           = 0x0
+	VEOL                           = 0x1
+	VEOL2                          = 0x2
+	VERASE                         = 0x3
+	VERASE2                        = 0x7
+	VINTR                          = 0x8
+	VKILL                          = 0x5
+	VLNEXT                         = 0xe
+	VMIN                           = 0x10
+	VQUIT                          = 0x9
+	VREPRINT                       = 0x6
+	VSTART                         = 0xc
+	VSTATUS                        = 0x12
+	VSTOP                          = 0xd
+	VSUSP                          = 0xa
+	VTIME                          = 0x11
+	VWERASE                        = 0x4
+	WCONTINUED                     = 0x4
+	WCOREFLAG                      = 0x80
+	WEXITED                        = 0x10
+	WLINUXCLONE                    = 0x80000000
+	WNOHANG                        = 0x1
+	WNOWAIT                        = 0x8
+	WSTOPPED                       = 0x2
+	WTRAPPED                       = 0x20
+	WUNTRACED                      = 0x2
 )
 
 // Errors
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index 4723162..a6b3b5f 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -1413,6 +1413,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x8905
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1420,7 +1430,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1440,13 +1452,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x541b
+	SIOCOUTQ                             = 0x5411
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1465,11 +1485,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x8902
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x2
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x800
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index b5c978e..4ffc8d2 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -1414,6 +1414,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x8905
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1421,7 +1431,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1441,13 +1453,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x541b
+	SIOCOUTQ                             = 0x5411
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1466,11 +1486,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x8902
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x2
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x800
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
index 0ae0e8c..f4b178e 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
@@ -1418,6 +1418,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x8905
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1425,7 +1435,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1445,13 +1457,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x541b
+	SIOCOUTQ                             = 0x5411
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1470,11 +1490,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x8902
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x2
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x800
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index 3c53a84..495f13b 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -1403,6 +1403,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x8905
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1410,7 +1420,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1430,13 +1442,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x541b
+	SIOCOUTQ                             = 0x5411
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1455,11 +1475,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x8902
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x2
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x800
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
index 23e845e..59651e4 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
@@ -1415,6 +1415,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x40047307
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1422,7 +1432,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1442,13 +1454,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x467f
+	SIOCOUTQ                             = 0x7472
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1467,11 +1487,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x80047308
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x1
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x80
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
index d27b373..a09bf9b 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
@@ -1415,6 +1415,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x40047307
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1422,7 +1432,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1442,13 +1454,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x467f
+	SIOCOUTQ                             = 0x7472
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1467,11 +1487,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x80047308
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x1
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x80
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
index b314601..72a0083 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
@@ -1415,6 +1415,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x40047307
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1422,7 +1432,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1442,13 +1454,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x467f
+	SIOCOUTQ                             = 0x7472
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1467,11 +1487,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x80047308
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x1
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x80
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
index aa69fe6..84c0e3c 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
@@ -1415,6 +1415,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x40047307
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1422,7 +1432,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1442,13 +1454,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x40047309
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x467f
+	SIOCOUTQ                             = 0x7472
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1467,11 +1487,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x80047308
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x1
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x80
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
index 6438fc8..8e4606e 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
@@ -1471,6 +1471,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x8905
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1478,7 +1488,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1498,13 +1510,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x4004667f
+	SIOCOUTQ                             = 0x40047473
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1523,11 +1543,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x8902
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x2
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x800
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
index 00c9942..16ed193 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
@@ -1471,6 +1471,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x8905
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1478,7 +1488,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1498,13 +1510,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x4004667f
+	SIOCOUTQ                             = 0x40047473
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1523,11 +1543,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x8902
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x2
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x800
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
index 89674f3..bd385f8 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
@@ -1475,6 +1475,16 @@
 	SIOCADDMULTI                         = 0x8931
 	SIOCADDRT                            = 0x890b
 	SIOCATMARK                           = 0x8905
+	SIOCBONDCHANGEACTIVE                 = 0x8995
+	SIOCBONDENSLAVE                      = 0x8990
+	SIOCBONDINFOQUERY                    = 0x8994
+	SIOCBONDRELEASE                      = 0x8991
+	SIOCBONDSETHWADDR                    = 0x8992
+	SIOCBONDSLAVEINFOQUERY               = 0x8993
+	SIOCBRADDBR                          = 0x89a0
+	SIOCBRADDIF                          = 0x89a2
+	SIOCBRDELBR                          = 0x89a1
+	SIOCBRDELIF                          = 0x89a3
 	SIOCDARP                             = 0x8953
 	SIOCDELDLCI                          = 0x8981
 	SIOCDELMULTI                         = 0x8932
@@ -1482,7 +1492,9 @@
 	SIOCDEVPRIVATE                       = 0x89f0
 	SIOCDIFADDR                          = 0x8936
 	SIOCDRARP                            = 0x8960
+	SIOCETHTOOL                          = 0x8946
 	SIOCGARP                             = 0x8954
+	SIOCGHWTSTAMP                        = 0x89b1
 	SIOCGIFADDR                          = 0x8915
 	SIOCGIFBR                            = 0x8940
 	SIOCGIFBRDADDR                       = 0x8919
@@ -1502,13 +1514,21 @@
 	SIOCGIFPFLAGS                        = 0x8935
 	SIOCGIFSLAVE                         = 0x8929
 	SIOCGIFTXQLEN                        = 0x8942
+	SIOCGIFVLAN                          = 0x8982
+	SIOCGMIIPHY                          = 0x8947
+	SIOCGMIIREG                          = 0x8948
 	SIOCGPGRP                            = 0x8904
 	SIOCGRARP                            = 0x8961
+	SIOCGSKNS                            = 0x894c
 	SIOCGSTAMP                           = 0x8906
 	SIOCGSTAMPNS                         = 0x8907
+	SIOCINQ                              = 0x541b
+	SIOCOUTQ                             = 0x5411
+	SIOCOUTQNSD                          = 0x894b
 	SIOCPROTOPRIVATE                     = 0x89e0
 	SIOCRTMSG                            = 0x890d
 	SIOCSARP                             = 0x8955
+	SIOCSHWTSTAMP                        = 0x89b0
 	SIOCSIFADDR                          = 0x8916
 	SIOCSIFBR                            = 0x8941
 	SIOCSIFBRDADDR                       = 0x891a
@@ -1527,11 +1547,15 @@
 	SIOCSIFPFLAGS                        = 0x8934
 	SIOCSIFSLAVE                         = 0x8930
 	SIOCSIFTXQLEN                        = 0x8943
+	SIOCSIFVLAN                          = 0x8983
+	SIOCSMIIREG                          = 0x8949
 	SIOCSPGRP                            = 0x8902
 	SIOCSRARP                            = 0x8962
+	SIOCWANDEV                           = 0x894a
 	SOCK_CLOEXEC                         = 0x80000
 	SOCK_DCCP                            = 0x6
 	SOCK_DGRAM                           = 0x2
+	SOCK_IOC_TYPE                        = 0x89
 	SOCK_NONBLOCK                        = 0x800
 	SOCK_PACKET                          = 0xa
 	SOCK_RAW                             = 0x3
diff --git a/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go
index ac85ca6..206c75f 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_netbsd_arm.go
@@ -1006,6 +1006,9 @@
 	MSG_TRUNC                         = 0x10
 	MSG_USERFLAGS                     = 0xffffff
 	MSG_WAITALL                       = 0x40
+	MS_ASYNC                          = 0x1
+	MS_INVALIDATE                     = 0x2
+	MS_SYNC                           = 0x4
 	NAME_MAX                          = 0x1ff
 	NET_RT_DUMP                       = 0x1
 	NET_RT_FLAGS                      = 0x2
diff --git a/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go
new file mode 100644
index 0000000..3ed0b26
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/zerrors_openbsd_arm.go
@@ -0,0 +1,1586 @@
+// mkerrors.sh
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs -- _const.go
+
+// +build arm,openbsd
+
+package unix
+
+import "syscall"
+
+const (
+	AF_APPLETALK                      = 0x10
+	AF_BLUETOOTH                      = 0x20
+	AF_CCITT                          = 0xa
+	AF_CHAOS                          = 0x5
+	AF_CNT                            = 0x15
+	AF_COIP                           = 0x14
+	AF_DATAKIT                        = 0x9
+	AF_DECnet                         = 0xc
+	AF_DLI                            = 0xd
+	AF_E164                           = 0x1a
+	AF_ECMA                           = 0x8
+	AF_ENCAP                          = 0x1c
+	AF_HYLINK                         = 0xf
+	AF_IMPLINK                        = 0x3
+	AF_INET                           = 0x2
+	AF_INET6                          = 0x18
+	AF_IPX                            = 0x17
+	AF_ISDN                           = 0x1a
+	AF_ISO                            = 0x7
+	AF_KEY                            = 0x1e
+	AF_LAT                            = 0xe
+	AF_LINK                           = 0x12
+	AF_LOCAL                          = 0x1
+	AF_MAX                            = 0x24
+	AF_MPLS                           = 0x21
+	AF_NATM                           = 0x1b
+	AF_NS                             = 0x6
+	AF_OSI                            = 0x7
+	AF_PUP                            = 0x4
+	AF_ROUTE                          = 0x11
+	AF_SIP                            = 0x1d
+	AF_SNA                            = 0xb
+	AF_UNIX                           = 0x1
+	AF_UNSPEC                         = 0x0
+	ARPHRD_ETHER                      = 0x1
+	ARPHRD_FRELAY                     = 0xf
+	ARPHRD_IEEE1394                   = 0x18
+	ARPHRD_IEEE802                    = 0x6
+	B0                                = 0x0
+	B110                              = 0x6e
+	B115200                           = 0x1c200
+	B1200                             = 0x4b0
+	B134                              = 0x86
+	B14400                            = 0x3840
+	B150                              = 0x96
+	B1800                             = 0x708
+	B19200                            = 0x4b00
+	B200                              = 0xc8
+	B230400                           = 0x38400
+	B2400                             = 0x960
+	B28800                            = 0x7080
+	B300                              = 0x12c
+	B38400                            = 0x9600
+	B4800                             = 0x12c0
+	B50                               = 0x32
+	B57600                            = 0xe100
+	B600                              = 0x258
+	B7200                             = 0x1c20
+	B75                               = 0x4b
+	B76800                            = 0x12c00
+	B9600                             = 0x2580
+	BIOCFLUSH                         = 0x20004268
+	BIOCGBLEN                         = 0x40044266
+	BIOCGDIRFILT                      = 0x4004427c
+	BIOCGDLT                          = 0x4004426a
+	BIOCGDLTLIST                      = 0xc008427b
+	BIOCGETIF                         = 0x4020426b
+	BIOCGFILDROP                      = 0x40044278
+	BIOCGHDRCMPLT                     = 0x40044274
+	BIOCGRSIG                         = 0x40044273
+	BIOCGRTIMEOUT                     = 0x400c426e
+	BIOCGSTATS                        = 0x4008426f
+	BIOCIMMEDIATE                     = 0x80044270
+	BIOCLOCK                          = 0x20004276
+	BIOCPROMISC                       = 0x20004269
+	BIOCSBLEN                         = 0xc0044266
+	BIOCSDIRFILT                      = 0x8004427d
+	BIOCSDLT                          = 0x8004427a
+	BIOCSETF                          = 0x80084267
+	BIOCSETIF                         = 0x8020426c
+	BIOCSETWF                         = 0x80084277
+	BIOCSFILDROP                      = 0x80044279
+	BIOCSHDRCMPLT                     = 0x80044275
+	BIOCSRSIG                         = 0x80044272
+	BIOCSRTIMEOUT                     = 0x800c426d
+	BIOCVERSION                       = 0x40044271
+	BPF_A                             = 0x10
+	BPF_ABS                           = 0x20
+	BPF_ADD                           = 0x0
+	BPF_ALIGNMENT                     = 0x4
+	BPF_ALU                           = 0x4
+	BPF_AND                           = 0x50
+	BPF_B                             = 0x10
+	BPF_DIRECTION_IN                  = 0x1
+	BPF_DIRECTION_OUT                 = 0x2
+	BPF_DIV                           = 0x30
+	BPF_H                             = 0x8
+	BPF_IMM                           = 0x0
+	BPF_IND                           = 0x40
+	BPF_JA                            = 0x0
+	BPF_JEQ                           = 0x10
+	BPF_JGE                           = 0x30
+	BPF_JGT                           = 0x20
+	BPF_JMP                           = 0x5
+	BPF_JSET                          = 0x40
+	BPF_K                             = 0x0
+	BPF_LD                            = 0x0
+	BPF_LDX                           = 0x1
+	BPF_LEN                           = 0x80
+	BPF_LSH                           = 0x60
+	BPF_MAJOR_VERSION                 = 0x1
+	BPF_MAXBUFSIZE                    = 0x200000
+	BPF_MAXINSNS                      = 0x200
+	BPF_MEM                           = 0x60
+	BPF_MEMWORDS                      = 0x10
+	BPF_MINBUFSIZE                    = 0x20
+	BPF_MINOR_VERSION                 = 0x1
+	BPF_MISC                          = 0x7
+	BPF_MSH                           = 0xa0
+	BPF_MUL                           = 0x20
+	BPF_NEG                           = 0x80
+	BPF_OR                            = 0x40
+	BPF_RELEASE                       = 0x30bb6
+	BPF_RET                           = 0x6
+	BPF_RSH                           = 0x70
+	BPF_ST                            = 0x2
+	BPF_STX                           = 0x3
+	BPF_SUB                           = 0x10
+	BPF_TAX                           = 0x0
+	BPF_TXA                           = 0x80
+	BPF_W                             = 0x0
+	BPF_X                             = 0x8
+	BRKINT                            = 0x2
+	CFLUSH                            = 0xf
+	CLOCAL                            = 0x8000
+	CREAD                             = 0x800
+	CS5                               = 0x0
+	CS6                               = 0x100
+	CS7                               = 0x200
+	CS8                               = 0x300
+	CSIZE                             = 0x300
+	CSTART                            = 0x11
+	CSTATUS                           = 0xff
+	CSTOP                             = 0x13
+	CSTOPB                            = 0x400
+	CSUSP                             = 0x1a
+	CTL_MAXNAME                       = 0xc
+	CTL_NET                           = 0x4
+	DIOCOSFPFLUSH                     = 0x2000444e
+	DLT_ARCNET                        = 0x7
+	DLT_ATM_RFC1483                   = 0xb
+	DLT_AX25                          = 0x3
+	DLT_CHAOS                         = 0x5
+	DLT_C_HDLC                        = 0x68
+	DLT_EN10MB                        = 0x1
+	DLT_EN3MB                         = 0x2
+	DLT_ENC                           = 0xd
+	DLT_FDDI                          = 0xa
+	DLT_IEEE802                       = 0x6
+	DLT_IEEE802_11                    = 0x69
+	DLT_IEEE802_11_RADIO              = 0x7f
+	DLT_LOOP                          = 0xc
+	DLT_MPLS                          = 0xdb
+	DLT_NULL                          = 0x0
+	DLT_PFLOG                         = 0x75
+	DLT_PFSYNC                        = 0x12
+	DLT_PPP                           = 0x9
+	DLT_PPP_BSDOS                     = 0x10
+	DLT_PPP_ETHER                     = 0x33
+	DLT_PPP_SERIAL                    = 0x32
+	DLT_PRONET                        = 0x4
+	DLT_RAW                           = 0xe
+	DLT_SLIP                          = 0x8
+	DLT_SLIP_BSDOS                    = 0xf
+	DT_BLK                            = 0x6
+	DT_CHR                            = 0x2
+	DT_DIR                            = 0x4
+	DT_FIFO                           = 0x1
+	DT_LNK                            = 0xa
+	DT_REG                            = 0x8
+	DT_SOCK                           = 0xc
+	DT_UNKNOWN                        = 0x0
+	ECHO                              = 0x8
+	ECHOCTL                           = 0x40
+	ECHOE                             = 0x2
+	ECHOK                             = 0x4
+	ECHOKE                            = 0x1
+	ECHONL                            = 0x10
+	ECHOPRT                           = 0x20
+	EMT_TAGOVF                        = 0x1
+	EMUL_ENABLED                      = 0x1
+	EMUL_NATIVE                       = 0x2
+	ENDRUNDISC                        = 0x9
+	ETHERMIN                          = 0x2e
+	ETHERMTU                          = 0x5dc
+	ETHERTYPE_8023                    = 0x4
+	ETHERTYPE_AARP                    = 0x80f3
+	ETHERTYPE_ACCTON                  = 0x8390
+	ETHERTYPE_AEONIC                  = 0x8036
+	ETHERTYPE_ALPHA                   = 0x814a
+	ETHERTYPE_AMBER                   = 0x6008
+	ETHERTYPE_AMOEBA                  = 0x8145
+	ETHERTYPE_AOE                     = 0x88a2
+	ETHERTYPE_APOLLO                  = 0x80f7
+	ETHERTYPE_APOLLODOMAIN            = 0x8019
+	ETHERTYPE_APPLETALK               = 0x809b
+	ETHERTYPE_APPLITEK                = 0x80c7
+	ETHERTYPE_ARGONAUT                = 0x803a
+	ETHERTYPE_ARP                     = 0x806
+	ETHERTYPE_AT                      = 0x809b
+	ETHERTYPE_ATALK                   = 0x809b
+	ETHERTYPE_ATOMIC                  = 0x86df
+	ETHERTYPE_ATT                     = 0x8069
+	ETHERTYPE_ATTSTANFORD             = 0x8008
+	ETHERTYPE_AUTOPHON                = 0x806a
+	ETHERTYPE_AXIS                    = 0x8856
+	ETHERTYPE_BCLOOP                  = 0x9003
+	ETHERTYPE_BOFL                    = 0x8102
+	ETHERTYPE_CABLETRON               = 0x7034
+	ETHERTYPE_CHAOS                   = 0x804
+	ETHERTYPE_COMDESIGN               = 0x806c
+	ETHERTYPE_COMPUGRAPHIC            = 0x806d
+	ETHERTYPE_COUNTERPOINT            = 0x8062
+	ETHERTYPE_CRONUS                  = 0x8004
+	ETHERTYPE_CRONUSVLN               = 0x8003
+	ETHERTYPE_DCA                     = 0x1234
+	ETHERTYPE_DDE                     = 0x807b
+	ETHERTYPE_DEBNI                   = 0xaaaa
+	ETHERTYPE_DECAM                   = 0x8048
+	ETHERTYPE_DECCUST                 = 0x6006
+	ETHERTYPE_DECDIAG                 = 0x6005
+	ETHERTYPE_DECDNS                  = 0x803c
+	ETHERTYPE_DECDTS                  = 0x803e
+	ETHERTYPE_DECEXPER                = 0x6000
+	ETHERTYPE_DECLAST                 = 0x8041
+	ETHERTYPE_DECLTM                  = 0x803f
+	ETHERTYPE_DECMUMPS                = 0x6009
+	ETHERTYPE_DECNETBIOS              = 0x8040
+	ETHERTYPE_DELTACON                = 0x86de
+	ETHERTYPE_DIDDLE                  = 0x4321
+	ETHERTYPE_DLOG1                   = 0x660
+	ETHERTYPE_DLOG2                   = 0x661
+	ETHERTYPE_DN                      = 0x6003
+	ETHERTYPE_DOGFIGHT                = 0x1989
+	ETHERTYPE_DSMD                    = 0x8039
+	ETHERTYPE_ECMA                    = 0x803
+	ETHERTYPE_ENCRYPT                 = 0x803d
+	ETHERTYPE_ES                      = 0x805d
+	ETHERTYPE_EXCELAN                 = 0x8010
+	ETHERTYPE_EXPERDATA               = 0x8049
+	ETHERTYPE_FLIP                    = 0x8146
+	ETHERTYPE_FLOWCONTROL             = 0x8808
+	ETHERTYPE_FRARP                   = 0x808
+	ETHERTYPE_GENDYN                  = 0x8068
+	ETHERTYPE_HAYES                   = 0x8130
+	ETHERTYPE_HIPPI_FP                = 0x8180
+	ETHERTYPE_HITACHI                 = 0x8820
+	ETHERTYPE_HP                      = 0x8005
+	ETHERTYPE_IEEEPUP                 = 0xa00
+	ETHERTYPE_IEEEPUPAT               = 0xa01
+	ETHERTYPE_IMLBL                   = 0x4c42
+	ETHERTYPE_IMLBLDIAG               = 0x424c
+	ETHERTYPE_IP                      = 0x800
+	ETHERTYPE_IPAS                    = 0x876c
+	ETHERTYPE_IPV6                    = 0x86dd
+	ETHERTYPE_IPX                     = 0x8137
+	ETHERTYPE_IPXNEW                  = 0x8037
+	ETHERTYPE_KALPANA                 = 0x8582
+	ETHERTYPE_LANBRIDGE               = 0x8038
+	ETHERTYPE_LANPROBE                = 0x8888
+	ETHERTYPE_LAT                     = 0x6004
+	ETHERTYPE_LBACK                   = 0x9000
+	ETHERTYPE_LITTLE                  = 0x8060
+	ETHERTYPE_LLDP                    = 0x88cc
+	ETHERTYPE_LOGICRAFT               = 0x8148
+	ETHERTYPE_LOOPBACK                = 0x9000
+	ETHERTYPE_MATRA                   = 0x807a
+	ETHERTYPE_MAX                     = 0xffff
+	ETHERTYPE_MERIT                   = 0x807c
+	ETHERTYPE_MICP                    = 0x873a
+	ETHERTYPE_MOPDL                   = 0x6001
+	ETHERTYPE_MOPRC                   = 0x6002
+	ETHERTYPE_MOTOROLA                = 0x818d
+	ETHERTYPE_MPLS                    = 0x8847
+	ETHERTYPE_MPLS_MCAST              = 0x8848
+	ETHERTYPE_MUMPS                   = 0x813f
+	ETHERTYPE_NBPCC                   = 0x3c04
+	ETHERTYPE_NBPCLAIM                = 0x3c09
+	ETHERTYPE_NBPCLREQ                = 0x3c05
+	ETHERTYPE_NBPCLRSP                = 0x3c06
+	ETHERTYPE_NBPCREQ                 = 0x3c02
+	ETHERTYPE_NBPCRSP                 = 0x3c03
+	ETHERTYPE_NBPDG                   = 0x3c07
+	ETHERTYPE_NBPDGB                  = 0x3c08
+	ETHERTYPE_NBPDLTE                 = 0x3c0a
+	ETHERTYPE_NBPRAR                  = 0x3c0c
+	ETHERTYPE_NBPRAS                  = 0x3c0b
+	ETHERTYPE_NBPRST                  = 0x3c0d
+	ETHERTYPE_NBPSCD                  = 0x3c01
+	ETHERTYPE_NBPVCD                  = 0x3c00
+	ETHERTYPE_NBS                     = 0x802
+	ETHERTYPE_NCD                     = 0x8149
+	ETHERTYPE_NESTAR                  = 0x8006
+	ETHERTYPE_NETBEUI                 = 0x8191
+	ETHERTYPE_NOVELL                  = 0x8138
+	ETHERTYPE_NS                      = 0x600
+	ETHERTYPE_NSAT                    = 0x601
+	ETHERTYPE_NSCOMPAT                = 0x807
+	ETHERTYPE_NTRAILER                = 0x10
+	ETHERTYPE_OS9                     = 0x7007
+	ETHERTYPE_OS9NET                  = 0x7009
+	ETHERTYPE_PACER                   = 0x80c6
+	ETHERTYPE_PAE                     = 0x888e
+	ETHERTYPE_PCS                     = 0x4242
+	ETHERTYPE_PLANNING                = 0x8044
+	ETHERTYPE_PPP                     = 0x880b
+	ETHERTYPE_PPPOE                   = 0x8864
+	ETHERTYPE_PPPOEDISC               = 0x8863
+	ETHERTYPE_PRIMENTS                = 0x7031
+	ETHERTYPE_PUP                     = 0x200
+	ETHERTYPE_PUPAT                   = 0x200
+	ETHERTYPE_QINQ                    = 0x88a8
+	ETHERTYPE_RACAL                   = 0x7030
+	ETHERTYPE_RATIONAL                = 0x8150
+	ETHERTYPE_RAWFR                   = 0x6559
+	ETHERTYPE_RCL                     = 0x1995
+	ETHERTYPE_RDP                     = 0x8739
+	ETHERTYPE_RETIX                   = 0x80f2
+	ETHERTYPE_REVARP                  = 0x8035
+	ETHERTYPE_SCA                     = 0x6007
+	ETHERTYPE_SECTRA                  = 0x86db
+	ETHERTYPE_SECUREDATA              = 0x876d
+	ETHERTYPE_SGITW                   = 0x817e
+	ETHERTYPE_SG_BOUNCE               = 0x8016
+	ETHERTYPE_SG_DIAG                 = 0x8013
+	ETHERTYPE_SG_NETGAMES             = 0x8014
+	ETHERTYPE_SG_RESV                 = 0x8015
+	ETHERTYPE_SIMNET                  = 0x5208
+	ETHERTYPE_SLOW                    = 0x8809
+	ETHERTYPE_SNA                     = 0x80d5
+	ETHERTYPE_SNMP                    = 0x814c
+	ETHERTYPE_SONIX                   = 0xfaf5
+	ETHERTYPE_SPIDER                  = 0x809f
+	ETHERTYPE_SPRITE                  = 0x500
+	ETHERTYPE_STP                     = 0x8181
+	ETHERTYPE_TALARIS                 = 0x812b
+	ETHERTYPE_TALARISMC               = 0x852b
+	ETHERTYPE_TCPCOMP                 = 0x876b
+	ETHERTYPE_TCPSM                   = 0x9002
+	ETHERTYPE_TEC                     = 0x814f
+	ETHERTYPE_TIGAN                   = 0x802f
+	ETHERTYPE_TRAIL                   = 0x1000
+	ETHERTYPE_TRANSETHER              = 0x6558
+	ETHERTYPE_TYMSHARE                = 0x802e
+	ETHERTYPE_UBBST                   = 0x7005
+	ETHERTYPE_UBDEBUG                 = 0x900
+	ETHERTYPE_UBDIAGLOOP              = 0x7002
+	ETHERTYPE_UBDL                    = 0x7000
+	ETHERTYPE_UBNIU                   = 0x7001
+	ETHERTYPE_UBNMC                   = 0x7003
+	ETHERTYPE_VALID                   = 0x1600
+	ETHERTYPE_VARIAN                  = 0x80dd
+	ETHERTYPE_VAXELN                  = 0x803b
+	ETHERTYPE_VEECO                   = 0x8067
+	ETHERTYPE_VEXP                    = 0x805b
+	ETHERTYPE_VGLAB                   = 0x8131
+	ETHERTYPE_VINES                   = 0xbad
+	ETHERTYPE_VINESECHO               = 0xbaf
+	ETHERTYPE_VINESLOOP               = 0xbae
+	ETHERTYPE_VITAL                   = 0xff00
+	ETHERTYPE_VLAN                    = 0x8100
+	ETHERTYPE_VLTLMAN                 = 0x8080
+	ETHERTYPE_VPROD                   = 0x805c
+	ETHERTYPE_VURESERVED              = 0x8147
+	ETHERTYPE_WATERLOO                = 0x8130
+	ETHERTYPE_WELLFLEET               = 0x8103
+	ETHERTYPE_X25                     = 0x805
+	ETHERTYPE_X75                     = 0x801
+	ETHERTYPE_XNSSM                   = 0x9001
+	ETHERTYPE_XTP                     = 0x817d
+	ETHER_ADDR_LEN                    = 0x6
+	ETHER_ALIGN                       = 0x2
+	ETHER_CRC_LEN                     = 0x4
+	ETHER_CRC_POLY_BE                 = 0x4c11db6
+	ETHER_CRC_POLY_LE                 = 0xedb88320
+	ETHER_HDR_LEN                     = 0xe
+	ETHER_MAX_DIX_LEN                 = 0x600
+	ETHER_MAX_LEN                     = 0x5ee
+	ETHER_MIN_LEN                     = 0x40
+	ETHER_TYPE_LEN                    = 0x2
+	ETHER_VLAN_ENCAP_LEN              = 0x4
+	EVFILT_AIO                        = -0x3
+	EVFILT_PROC                       = -0x5
+	EVFILT_READ                       = -0x1
+	EVFILT_SIGNAL                     = -0x6
+	EVFILT_SYSCOUNT                   = 0x7
+	EVFILT_TIMER                      = -0x7
+	EVFILT_VNODE                      = -0x4
+	EVFILT_WRITE                      = -0x2
+	EV_ADD                            = 0x1
+	EV_CLEAR                          = 0x20
+	EV_DELETE                         = 0x2
+	EV_DISABLE                        = 0x8
+	EV_ENABLE                         = 0x4
+	EV_EOF                            = 0x8000
+	EV_ERROR                          = 0x4000
+	EV_FLAG1                          = 0x2000
+	EV_ONESHOT                        = 0x10
+	EV_SYSFLAGS                       = 0xf000
+	EXTA                              = 0x4b00
+	EXTB                              = 0x9600
+	EXTPROC                           = 0x800
+	FD_CLOEXEC                        = 0x1
+	FD_SETSIZE                        = 0x400
+	FLUSHO                            = 0x800000
+	F_DUPFD                           = 0x0
+	F_DUPFD_CLOEXEC                   = 0xa
+	F_GETFD                           = 0x1
+	F_GETFL                           = 0x3
+	F_GETLK                           = 0x7
+	F_GETOWN                          = 0x5
+	F_RDLCK                           = 0x1
+	F_SETFD                           = 0x2
+	F_SETFL                           = 0x4
+	F_SETLK                           = 0x8
+	F_SETLKW                          = 0x9
+	F_SETOWN                          = 0x6
+	F_UNLCK                           = 0x2
+	F_WRLCK                           = 0x3
+	HUPCL                             = 0x4000
+	ICANON                            = 0x100
+	ICMP6_FILTER                      = 0x12
+	ICRNL                             = 0x100
+	IEXTEN                            = 0x400
+	IFAN_ARRIVAL                      = 0x0
+	IFAN_DEPARTURE                    = 0x1
+	IFA_ROUTE                         = 0x1
+	IFF_ALLMULTI                      = 0x200
+	IFF_BROADCAST                     = 0x2
+	IFF_CANTCHANGE                    = 0x8e52
+	IFF_DEBUG                         = 0x4
+	IFF_LINK0                         = 0x1000
+	IFF_LINK1                         = 0x2000
+	IFF_LINK2                         = 0x4000
+	IFF_LOOPBACK                      = 0x8
+	IFF_MULTICAST                     = 0x8000
+	IFF_NOARP                         = 0x80
+	IFF_NOTRAILERS                    = 0x20
+	IFF_OACTIVE                       = 0x400
+	IFF_POINTOPOINT                   = 0x10
+	IFF_PROMISC                       = 0x100
+	IFF_RUNNING                       = 0x40
+	IFF_SIMPLEX                       = 0x800
+	IFF_UP                            = 0x1
+	IFNAMSIZ                          = 0x10
+	IFT_1822                          = 0x2
+	IFT_A12MPPSWITCH                  = 0x82
+	IFT_AAL2                          = 0xbb
+	IFT_AAL5                          = 0x31
+	IFT_ADSL                          = 0x5e
+	IFT_AFLANE8023                    = 0x3b
+	IFT_AFLANE8025                    = 0x3c
+	IFT_ARAP                          = 0x58
+	IFT_ARCNET                        = 0x23
+	IFT_ARCNETPLUS                    = 0x24
+	IFT_ASYNC                         = 0x54
+	IFT_ATM                           = 0x25
+	IFT_ATMDXI                        = 0x69
+	IFT_ATMFUNI                       = 0x6a
+	IFT_ATMIMA                        = 0x6b
+	IFT_ATMLOGICAL                    = 0x50
+	IFT_ATMRADIO                      = 0xbd
+	IFT_ATMSUBINTERFACE               = 0x86
+	IFT_ATMVCIENDPT                   = 0xc2
+	IFT_ATMVIRTUAL                    = 0x95
+	IFT_BGPPOLICYACCOUNTING           = 0xa2
+	IFT_BLUETOOTH                     = 0xf8
+	IFT_BRIDGE                        = 0xd1
+	IFT_BSC                           = 0x53
+	IFT_CARP                          = 0xf7
+	IFT_CCTEMUL                       = 0x3d
+	IFT_CEPT                          = 0x13
+	IFT_CES                           = 0x85
+	IFT_CHANNEL                       = 0x46
+	IFT_CNR                           = 0x55
+	IFT_COFFEE                        = 0x84
+	IFT_COMPOSITELINK                 = 0x9b
+	IFT_DCN                           = 0x8d
+	IFT_DIGITALPOWERLINE              = 0x8a
+	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
+	IFT_DLSW                          = 0x4a
+	IFT_DOCSCABLEDOWNSTREAM           = 0x80
+	IFT_DOCSCABLEMACLAYER             = 0x7f
+	IFT_DOCSCABLEUPSTREAM             = 0x81
+	IFT_DOCSCABLEUPSTREAMCHANNEL      = 0xcd
+	IFT_DS0                           = 0x51
+	IFT_DS0BUNDLE                     = 0x52
+	IFT_DS1FDL                        = 0xaa
+	IFT_DS3                           = 0x1e
+	IFT_DTM                           = 0x8c
+	IFT_DUMMY                         = 0xf1
+	IFT_DVBASILN                      = 0xac
+	IFT_DVBASIOUT                     = 0xad
+	IFT_DVBRCCDOWNSTREAM              = 0x93
+	IFT_DVBRCCMACLAYER                = 0x92
+	IFT_DVBRCCUPSTREAM                = 0x94
+	IFT_ECONET                        = 0xce
+	IFT_ENC                           = 0xf4
+	IFT_EON                           = 0x19
+	IFT_EPLRS                         = 0x57
+	IFT_ESCON                         = 0x49
+	IFT_ETHER                         = 0x6
+	IFT_FAITH                         = 0xf3
+	IFT_FAST                          = 0x7d
+	IFT_FASTETHER                     = 0x3e
+	IFT_FASTETHERFX                   = 0x45
+	IFT_FDDI                          = 0xf
+	IFT_FIBRECHANNEL                  = 0x38
+	IFT_FRAMERELAYINTERCONNECT        = 0x3a
+	IFT_FRAMERELAYMPI                 = 0x5c
+	IFT_FRDLCIENDPT                   = 0xc1
+	IFT_FRELAY                        = 0x20
+	IFT_FRELAYDCE                     = 0x2c
+	IFT_FRF16MFRBUNDLE                = 0xa3
+	IFT_FRFORWARD                     = 0x9e
+	IFT_G703AT2MB                     = 0x43
+	IFT_G703AT64K                     = 0x42
+	IFT_GIF                           = 0xf0
+	IFT_GIGABITETHERNET               = 0x75
+	IFT_GR303IDT                      = 0xb2
+	IFT_GR303RDT                      = 0xb1
+	IFT_H323GATEKEEPER                = 0xa4
+	IFT_H323PROXY                     = 0xa5
+	IFT_HDH1822                       = 0x3
+	IFT_HDLC                          = 0x76
+	IFT_HDSL2                         = 0xa8
+	IFT_HIPERLAN2                     = 0xb7
+	IFT_HIPPI                         = 0x2f
+	IFT_HIPPIINTERFACE                = 0x39
+	IFT_HOSTPAD                       = 0x5a
+	IFT_HSSI                          = 0x2e
+	IFT_HY                            = 0xe
+	IFT_IBM370PARCHAN                 = 0x48
+	IFT_IDSL                          = 0x9a
+	IFT_IEEE1394                      = 0x90
+	IFT_IEEE80211                     = 0x47
+	IFT_IEEE80212                     = 0x37
+	IFT_IEEE8023ADLAG                 = 0xa1
+	IFT_IFGSN                         = 0x91
+	IFT_IMT                           = 0xbe
+	IFT_INFINIBAND                    = 0xc7
+	IFT_INTERLEAVE                    = 0x7c
+	IFT_IP                            = 0x7e
+	IFT_IPFORWARD                     = 0x8e
+	IFT_IPOVERATM                     = 0x72
+	IFT_IPOVERCDLC                    = 0x6d
+	IFT_IPOVERCLAW                    = 0x6e
+	IFT_IPSWITCH                      = 0x4e
+	IFT_ISDN                          = 0x3f
+	IFT_ISDNBASIC                     = 0x14
+	IFT_ISDNPRIMARY                   = 0x15
+	IFT_ISDNS                         = 0x4b
+	IFT_ISDNU                         = 0x4c
+	IFT_ISO88022LLC                   = 0x29
+	IFT_ISO88023                      = 0x7
+	IFT_ISO88024                      = 0x8
+	IFT_ISO88025                      = 0x9
+	IFT_ISO88025CRFPINT               = 0x62
+	IFT_ISO88025DTR                   = 0x56
+	IFT_ISO88025FIBER                 = 0x73
+	IFT_ISO88026                      = 0xa
+	IFT_ISUP                          = 0xb3
+	IFT_L2VLAN                        = 0x87
+	IFT_L3IPVLAN                      = 0x88
+	IFT_L3IPXVLAN                     = 0x89
+	IFT_LAPB                          = 0x10
+	IFT_LAPD                          = 0x4d
+	IFT_LAPF                          = 0x77
+	IFT_LINEGROUP                     = 0xd2
+	IFT_LOCALTALK                     = 0x2a
+	IFT_LOOP                          = 0x18
+	IFT_MEDIAMAILOVERIP               = 0x8b
+	IFT_MFSIGLINK                     = 0xa7
+	IFT_MIOX25                        = 0x26
+	IFT_MODEM                         = 0x30
+	IFT_MPC                           = 0x71
+	IFT_MPLS                          = 0xa6
+	IFT_MPLSTUNNEL                    = 0x96
+	IFT_MSDSL                         = 0x8f
+	IFT_MVL                           = 0xbf
+	IFT_MYRINET                       = 0x63
+	IFT_NFAS                          = 0xaf
+	IFT_NSIP                          = 0x1b
+	IFT_OPTICALCHANNEL                = 0xc3
+	IFT_OPTICALTRANSPORT              = 0xc4
+	IFT_OTHER                         = 0x1
+	IFT_P10                           = 0xc
+	IFT_P80                           = 0xd
+	IFT_PARA                          = 0x22
+	IFT_PFLOG                         = 0xf5
+	IFT_PFLOW                         = 0xf9
+	IFT_PFSYNC                        = 0xf6
+	IFT_PLC                           = 0xae
+	IFT_PON155                        = 0xcf
+	IFT_PON622                        = 0xd0
+	IFT_POS                           = 0xab
+	IFT_PPP                           = 0x17
+	IFT_PPPMULTILINKBUNDLE            = 0x6c
+	IFT_PROPATM                       = 0xc5
+	IFT_PROPBWAP2MP                   = 0xb8
+	IFT_PROPCNLS                      = 0x59
+	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
+	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
+	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
+	IFT_PROPMUX                       = 0x36
+	IFT_PROPVIRTUAL                   = 0x35
+	IFT_PROPWIRELESSP2P               = 0x9d
+	IFT_PTPSERIAL                     = 0x16
+	IFT_PVC                           = 0xf2
+	IFT_Q2931                         = 0xc9
+	IFT_QLLC                          = 0x44
+	IFT_RADIOMAC                      = 0xbc
+	IFT_RADSL                         = 0x5f
+	IFT_REACHDSL                      = 0xc0
+	IFT_RFC1483                       = 0x9f
+	IFT_RS232                         = 0x21
+	IFT_RSRB                          = 0x4f
+	IFT_SDLC                          = 0x11
+	IFT_SDSL                          = 0x60
+	IFT_SHDSL                         = 0xa9
+	IFT_SIP                           = 0x1f
+	IFT_SIPSIG                        = 0xcc
+	IFT_SIPTG                         = 0xcb
+	IFT_SLIP                          = 0x1c
+	IFT_SMDSDXI                       = 0x2b
+	IFT_SMDSICIP                      = 0x34
+	IFT_SONET                         = 0x27
+	IFT_SONETOVERHEADCHANNEL          = 0xb9
+	IFT_SONETPATH                     = 0x32
+	IFT_SONETVT                       = 0x33
+	IFT_SRP                           = 0x97
+	IFT_SS7SIGLINK                    = 0x9c
+	IFT_STACKTOSTACK                  = 0x6f
+	IFT_STARLAN                       = 0xb
+	IFT_T1                            = 0x12
+	IFT_TDLC                          = 0x74
+	IFT_TELINK                        = 0xc8
+	IFT_TERMPAD                       = 0x5b
+	IFT_TR008                         = 0xb0
+	IFT_TRANSPHDLC                    = 0x7b
+	IFT_TUNNEL                        = 0x83
+	IFT_ULTRA                         = 0x1d
+	IFT_USB                           = 0xa0
+	IFT_V11                           = 0x40
+	IFT_V35                           = 0x2d
+	IFT_V36                           = 0x41
+	IFT_V37                           = 0x78
+	IFT_VDSL                          = 0x61
+	IFT_VIRTUALIPADDRESS              = 0x70
+	IFT_VIRTUALTG                     = 0xca
+	IFT_VOICEDID                      = 0xd5
+	IFT_VOICEEM                       = 0x64
+	IFT_VOICEEMFGD                    = 0xd3
+	IFT_VOICEENCAP                    = 0x67
+	IFT_VOICEFGDEANA                  = 0xd4
+	IFT_VOICEFXO                      = 0x65
+	IFT_VOICEFXS                      = 0x66
+	IFT_VOICEOVERATM                  = 0x98
+	IFT_VOICEOVERCABLE                = 0xc6
+	IFT_VOICEOVERFRAMERELAY           = 0x99
+	IFT_VOICEOVERIP                   = 0x68
+	IFT_X213                          = 0x5d
+	IFT_X25                           = 0x5
+	IFT_X25DDN                        = 0x4
+	IFT_X25HUNTGROUP                  = 0x7a
+	IFT_X25MLP                        = 0x79
+	IFT_X25PLE                        = 0x28
+	IFT_XETHER                        = 0x1a
+	IGNBRK                            = 0x1
+	IGNCR                             = 0x80
+	IGNPAR                            = 0x4
+	IMAXBEL                           = 0x2000
+	INLCR                             = 0x40
+	INPCK                             = 0x10
+	IN_CLASSA_HOST                    = 0xffffff
+	IN_CLASSA_MAX                     = 0x80
+	IN_CLASSA_NET                     = 0xff000000
+	IN_CLASSA_NSHIFT                  = 0x18
+	IN_CLASSB_HOST                    = 0xffff
+	IN_CLASSB_MAX                     = 0x10000
+	IN_CLASSB_NET                     = 0xffff0000
+	IN_CLASSB_NSHIFT                  = 0x10
+	IN_CLASSC_HOST                    = 0xff
+	IN_CLASSC_NET                     = 0xffffff00
+	IN_CLASSC_NSHIFT                  = 0x8
+	IN_CLASSD_HOST                    = 0xfffffff
+	IN_CLASSD_NET                     = 0xf0000000
+	IN_CLASSD_NSHIFT                  = 0x1c
+	IN_LOOPBACKNET                    = 0x7f
+	IN_RFC3021_HOST                   = 0x1
+	IN_RFC3021_NET                    = 0xfffffffe
+	IN_RFC3021_NSHIFT                 = 0x1f
+	IPPROTO_AH                        = 0x33
+	IPPROTO_CARP                      = 0x70
+	IPPROTO_DIVERT                    = 0x102
+	IPPROTO_DIVERT_INIT               = 0x2
+	IPPROTO_DIVERT_RESP               = 0x1
+	IPPROTO_DONE                      = 0x101
+	IPPROTO_DSTOPTS                   = 0x3c
+	IPPROTO_EGP                       = 0x8
+	IPPROTO_ENCAP                     = 0x62
+	IPPROTO_EON                       = 0x50
+	IPPROTO_ESP                       = 0x32
+	IPPROTO_ETHERIP                   = 0x61
+	IPPROTO_FRAGMENT                  = 0x2c
+	IPPROTO_GGP                       = 0x3
+	IPPROTO_GRE                       = 0x2f
+	IPPROTO_HOPOPTS                   = 0x0
+	IPPROTO_ICMP                      = 0x1
+	IPPROTO_ICMPV6                    = 0x3a
+	IPPROTO_IDP                       = 0x16
+	IPPROTO_IGMP                      = 0x2
+	IPPROTO_IP                        = 0x0
+	IPPROTO_IPCOMP                    = 0x6c
+	IPPROTO_IPIP                      = 0x4
+	IPPROTO_IPV4                      = 0x4
+	IPPROTO_IPV6                      = 0x29
+	IPPROTO_MAX                       = 0x100
+	IPPROTO_MAXID                     = 0x103
+	IPPROTO_MOBILE                    = 0x37
+	IPPROTO_MPLS                      = 0x89
+	IPPROTO_NONE                      = 0x3b
+	IPPROTO_PFSYNC                    = 0xf0
+	IPPROTO_PIM                       = 0x67
+	IPPROTO_PUP                       = 0xc
+	IPPROTO_RAW                       = 0xff
+	IPPROTO_ROUTING                   = 0x2b
+	IPPROTO_RSVP                      = 0x2e
+	IPPROTO_TCP                       = 0x6
+	IPPROTO_TP                        = 0x1d
+	IPPROTO_UDP                       = 0x11
+	IPV6_AUTH_LEVEL                   = 0x35
+	IPV6_AUTOFLOWLABEL                = 0x3b
+	IPV6_CHECKSUM                     = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
+	IPV6_DEFHLIM                      = 0x40
+	IPV6_DONTFRAG                     = 0x3e
+	IPV6_DSTOPTS                      = 0x32
+	IPV6_ESP_NETWORK_LEVEL            = 0x37
+	IPV6_ESP_TRANS_LEVEL              = 0x36
+	IPV6_FAITH                        = 0x1d
+	IPV6_FLOWINFO_MASK                = 0xffffff0f
+	IPV6_FLOWLABEL_MASK               = 0xffff0f00
+	IPV6_FRAGTTL                      = 0x78
+	IPV6_HLIMDEC                      = 0x1
+	IPV6_HOPLIMIT                     = 0x2f
+	IPV6_HOPOPTS                      = 0x31
+	IPV6_IPCOMP_LEVEL                 = 0x3c
+	IPV6_JOIN_GROUP                   = 0xc
+	IPV6_LEAVE_GROUP                  = 0xd
+	IPV6_MAXHLIM                      = 0xff
+	IPV6_MAXPACKET                    = 0xffff
+	IPV6_MMTU                         = 0x500
+	IPV6_MULTICAST_HOPS               = 0xa
+	IPV6_MULTICAST_IF                 = 0x9
+	IPV6_MULTICAST_LOOP               = 0xb
+	IPV6_NEXTHOP                      = 0x30
+	IPV6_OPTIONS                      = 0x1
+	IPV6_PATHMTU                      = 0x2c
+	IPV6_PIPEX                        = 0x3f
+	IPV6_PKTINFO                      = 0x2e
+	IPV6_PORTRANGE                    = 0xe
+	IPV6_PORTRANGE_DEFAULT            = 0x0
+	IPV6_PORTRANGE_HIGH               = 0x1
+	IPV6_PORTRANGE_LOW                = 0x2
+	IPV6_RECVDSTOPTS                  = 0x28
+	IPV6_RECVDSTPORT                  = 0x40
+	IPV6_RECVHOPLIMIT                 = 0x25
+	IPV6_RECVHOPOPTS                  = 0x27
+	IPV6_RECVPATHMTU                  = 0x2b
+	IPV6_RECVPKTINFO                  = 0x24
+	IPV6_RECVRTHDR                    = 0x26
+	IPV6_RECVTCLASS                   = 0x39
+	IPV6_RTABLE                       = 0x1021
+	IPV6_RTHDR                        = 0x33
+	IPV6_RTHDRDSTOPTS                 = 0x23
+	IPV6_RTHDR_LOOSE                  = 0x0
+	IPV6_RTHDR_STRICT                 = 0x1
+	IPV6_RTHDR_TYPE_0                 = 0x0
+	IPV6_SOCKOPT_RESERVED1            = 0x3
+	IPV6_TCLASS                       = 0x3d
+	IPV6_UNICAST_HOPS                 = 0x4
+	IPV6_USE_MIN_MTU                  = 0x2a
+	IPV6_V6ONLY                       = 0x1b
+	IPV6_VERSION                      = 0x60
+	IPV6_VERSION_MASK                 = 0xf0
+	IP_ADD_MEMBERSHIP                 = 0xc
+	IP_AUTH_LEVEL                     = 0x14
+	IP_DEFAULT_MULTICAST_LOOP         = 0x1
+	IP_DEFAULT_MULTICAST_TTL          = 0x1
+	IP_DF                             = 0x4000
+	IP_DIVERTFL                       = 0x1022
+	IP_DROP_MEMBERSHIP                = 0xd
+	IP_ESP_NETWORK_LEVEL              = 0x16
+	IP_ESP_TRANS_LEVEL                = 0x15
+	IP_HDRINCL                        = 0x2
+	IP_IPCOMP_LEVEL                   = 0x1d
+	IP_IPSECFLOWINFO                  = 0x24
+	IP_IPSEC_LOCAL_AUTH               = 0x1b
+	IP_IPSEC_LOCAL_CRED               = 0x19
+	IP_IPSEC_LOCAL_ID                 = 0x17
+	IP_IPSEC_REMOTE_AUTH              = 0x1c
+	IP_IPSEC_REMOTE_CRED              = 0x1a
+	IP_IPSEC_REMOTE_ID                = 0x18
+	IP_MAXPACKET                      = 0xffff
+	IP_MAX_MEMBERSHIPS                = 0xfff
+	IP_MF                             = 0x2000
+	IP_MINTTL                         = 0x20
+	IP_MIN_MEMBERSHIPS                = 0xf
+	IP_MSS                            = 0x240
+	IP_MULTICAST_IF                   = 0x9
+	IP_MULTICAST_LOOP                 = 0xb
+	IP_MULTICAST_TTL                  = 0xa
+	IP_OFFMASK                        = 0x1fff
+	IP_OPTIONS                        = 0x1
+	IP_PIPEX                          = 0x22
+	IP_PORTRANGE                      = 0x13
+	IP_PORTRANGE_DEFAULT              = 0x0
+	IP_PORTRANGE_HIGH                 = 0x1
+	IP_PORTRANGE_LOW                  = 0x2
+	IP_RECVDSTADDR                    = 0x7
+	IP_RECVDSTPORT                    = 0x21
+	IP_RECVIF                         = 0x1e
+	IP_RECVOPTS                       = 0x5
+	IP_RECVRETOPTS                    = 0x6
+	IP_RECVRTABLE                     = 0x23
+	IP_RECVTTL                        = 0x1f
+	IP_RETOPTS                        = 0x8
+	IP_RF                             = 0x8000
+	IP_RTABLE                         = 0x1021
+	IP_TOS                            = 0x3
+	IP_TTL                            = 0x4
+	ISIG                              = 0x80
+	ISTRIP                            = 0x20
+	IXANY                             = 0x800
+	IXOFF                             = 0x400
+	IXON                              = 0x200
+	LCNT_OVERLOAD_FLUSH               = 0x6
+	LOCK_EX                           = 0x2
+	LOCK_NB                           = 0x4
+	LOCK_SH                           = 0x1
+	LOCK_UN                           = 0x8
+	MADV_DONTNEED                     = 0x4
+	MADV_FREE                         = 0x6
+	MADV_NORMAL                       = 0x0
+	MADV_RANDOM                       = 0x1
+	MADV_SEQUENTIAL                   = 0x2
+	MADV_SPACEAVAIL                   = 0x5
+	MADV_WILLNEED                     = 0x3
+	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
+	MAP_COPY                          = 0x2
+	MAP_FILE                          = 0x0
+	MAP_FIXED                         = 0x10
+	MAP_FLAGMASK                      = 0x3ff7
+	MAP_HASSEMAPHORE                  = 0x0
+	MAP_INHERIT                       = 0x0
+	MAP_INHERIT_COPY                  = 0x1
+	MAP_INHERIT_NONE                  = 0x2
+	MAP_INHERIT_SHARE                 = 0x0
+	MAP_INHERIT_ZERO                  = 0x3
+	MAP_NOEXTEND                      = 0x0
+	MAP_NORESERVE                     = 0x0
+	MAP_PRIVATE                       = 0x2
+	MAP_RENAME                        = 0x0
+	MAP_SHARED                        = 0x1
+	MAP_TRYFIXED                      = 0x0
+	MCL_CURRENT                       = 0x1
+	MCL_FUTURE                        = 0x2
+	MSG_BCAST                         = 0x100
+	MSG_CMSG_CLOEXEC                  = 0x800
+	MSG_CTRUNC                        = 0x20
+	MSG_DONTROUTE                     = 0x4
+	MSG_DONTWAIT                      = 0x80
+	MSG_EOR                           = 0x8
+	MSG_MCAST                         = 0x200
+	MSG_NOSIGNAL                      = 0x400
+	MSG_OOB                           = 0x1
+	MSG_PEEK                          = 0x2
+	MSG_TRUNC                         = 0x10
+	MSG_WAITALL                       = 0x40
+	MS_ASYNC                          = 0x1
+	MS_INVALIDATE                     = 0x4
+	MS_SYNC                           = 0x2
+	NAME_MAX                          = 0xff
+	NET_RT_DUMP                       = 0x1
+	NET_RT_FLAGS                      = 0x2
+	NET_RT_IFLIST                     = 0x3
+	NET_RT_MAXID                      = 0x6
+	NET_RT_STATS                      = 0x4
+	NET_RT_TABLE                      = 0x5
+	NOFLSH                            = 0x80000000
+	NOTE_ATTRIB                       = 0x8
+	NOTE_CHILD                        = 0x4
+	NOTE_DELETE                       = 0x1
+	NOTE_EOF                          = 0x2
+	NOTE_EXEC                         = 0x20000000
+	NOTE_EXIT                         = 0x80000000
+	NOTE_EXTEND                       = 0x4
+	NOTE_FORK                         = 0x40000000
+	NOTE_LINK                         = 0x10
+	NOTE_LOWAT                        = 0x1
+	NOTE_PCTRLMASK                    = 0xf0000000
+	NOTE_PDATAMASK                    = 0xfffff
+	NOTE_RENAME                       = 0x20
+	NOTE_REVOKE                       = 0x40
+	NOTE_TRACK                        = 0x1
+	NOTE_TRACKERR                     = 0x2
+	NOTE_TRUNCATE                     = 0x80
+	NOTE_WRITE                        = 0x2
+	OCRNL                             = 0x10
+	ONLCR                             = 0x2
+	ONLRET                            = 0x80
+	ONOCR                             = 0x40
+	ONOEOT                            = 0x8
+	OPOST                             = 0x1
+	O_ACCMODE                         = 0x3
+	O_APPEND                          = 0x8
+	O_ASYNC                           = 0x40
+	O_CLOEXEC                         = 0x10000
+	O_CREAT                           = 0x200
+	O_DIRECTORY                       = 0x20000
+	O_DSYNC                           = 0x80
+	O_EXCL                            = 0x800
+	O_EXLOCK                          = 0x20
+	O_FSYNC                           = 0x80
+	O_NDELAY                          = 0x4
+	O_NOCTTY                          = 0x8000
+	O_NOFOLLOW                        = 0x100
+	O_NONBLOCK                        = 0x4
+	O_RDONLY                          = 0x0
+	O_RDWR                            = 0x2
+	O_RSYNC                           = 0x80
+	O_SHLOCK                          = 0x10
+	O_SYNC                            = 0x80
+	O_TRUNC                           = 0x400
+	O_WRONLY                          = 0x1
+	PARENB                            = 0x1000
+	PARMRK                            = 0x8
+	PARODD                            = 0x2000
+	PENDIN                            = 0x20000000
+	PF_FLUSH                          = 0x1
+	PRIO_PGRP                         = 0x1
+	PRIO_PROCESS                      = 0x0
+	PRIO_USER                         = 0x2
+	PROT_EXEC                         = 0x4
+	PROT_NONE                         = 0x0
+	PROT_READ                         = 0x1
+	PROT_WRITE                        = 0x2
+	RLIMIT_CORE                       = 0x4
+	RLIMIT_CPU                        = 0x0
+	RLIMIT_DATA                       = 0x2
+	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_STACK                      = 0x3
+	RLIM_INFINITY                     = 0x7fffffffffffffff
+	RTAX_AUTHOR                       = 0x6
+	RTAX_BRD                          = 0x7
+	RTAX_DST                          = 0x0
+	RTAX_GATEWAY                      = 0x1
+	RTAX_GENMASK                      = 0x3
+	RTAX_IFA                          = 0x5
+	RTAX_IFP                          = 0x4
+	RTAX_LABEL                        = 0xa
+	RTAX_MAX                          = 0xb
+	RTAX_NETMASK                      = 0x2
+	RTAX_SRC                          = 0x8
+	RTAX_SRCMASK                      = 0x9
+	RTA_AUTHOR                        = 0x40
+	RTA_BRD                           = 0x80
+	RTA_DST                           = 0x1
+	RTA_GATEWAY                       = 0x2
+	RTA_GENMASK                       = 0x8
+	RTA_IFA                           = 0x20
+	RTA_IFP                           = 0x10
+	RTA_LABEL                         = 0x400
+	RTA_NETMASK                       = 0x4
+	RTA_SRC                           = 0x100
+	RTA_SRCMASK                       = 0x200
+	RTF_ANNOUNCE                      = 0x4000
+	RTF_BLACKHOLE                     = 0x1000
+	RTF_BROADCAST                     = 0x400000
+	RTF_CLONED                        = 0x10000
+	RTF_CLONING                       = 0x100
+	RTF_DONE                          = 0x40
+	RTF_DYNAMIC                       = 0x10
+	RTF_FMASK                         = 0x70f808
+	RTF_GATEWAY                       = 0x2
+	RTF_HOST                          = 0x4
+	RTF_LLINFO                        = 0x400
+	RTF_LOCAL                         = 0x200000
+	RTF_MASK                          = 0x80
+	RTF_MODIFIED                      = 0x20
+	RTF_MPATH                         = 0x40000
+	RTF_MPLS                          = 0x100000
+	RTF_PERMANENT_ARP                 = 0x2000
+	RTF_PROTO1                        = 0x8000
+	RTF_PROTO2                        = 0x4000
+	RTF_PROTO3                        = 0x2000
+	RTF_REJECT                        = 0x8
+	RTF_STATIC                        = 0x800
+	RTF_UP                            = 0x1
+	RTF_USETRAILERS                   = 0x8000
+	RTF_XRESOLVE                      = 0x200
+	RTM_ADD                           = 0x1
+	RTM_CHANGE                        = 0x3
+	RTM_DELADDR                       = 0xd
+	RTM_DELETE                        = 0x2
+	RTM_DESYNC                        = 0x10
+	RTM_GET                           = 0x4
+	RTM_IFANNOUNCE                    = 0xf
+	RTM_IFINFO                        = 0xe
+	RTM_LOCK                          = 0x8
+	RTM_LOSING                        = 0x5
+	RTM_MAXSIZE                       = 0x800
+	RTM_MISS                          = 0x7
+	RTM_NEWADDR                       = 0xc
+	RTM_REDIRECT                      = 0x6
+	RTM_RESOLVE                       = 0xb
+	RTM_RTTUNIT                       = 0xf4240
+	RTM_VERSION                       = 0x5
+	RTV_EXPIRE                        = 0x4
+	RTV_HOPCOUNT                      = 0x2
+	RTV_MTU                           = 0x1
+	RTV_RPIPE                         = 0x8
+	RTV_RTT                           = 0x40
+	RTV_RTTVAR                        = 0x80
+	RTV_SPIPE                         = 0x10
+	RTV_SSTHRESH                      = 0x20
+	RT_TABLEID_MAX                    = 0xff
+	RUSAGE_CHILDREN                   = -0x1
+	RUSAGE_SELF                       = 0x0
+	RUSAGE_THREAD                     = 0x1
+	SCM_RIGHTS                        = 0x1
+	SCM_TIMESTAMP                     = 0x4
+	SHUT_RD                           = 0x0
+	SHUT_RDWR                         = 0x2
+	SHUT_WR                           = 0x1
+	SIOCADDMULTI                      = 0x80206931
+	SIOCAIFADDR                       = 0x8040691a
+	SIOCAIFGROUP                      = 0x80246987
+	SIOCALIFADDR                      = 0x8218691c
+	SIOCATMARK                        = 0x40047307
+	SIOCBRDGADD                       = 0x8054693c
+	SIOCBRDGADDS                      = 0x80546941
+	SIOCBRDGARL                       = 0x806e694d
+	SIOCBRDGDADDR                     = 0x81286947
+	SIOCBRDGDEL                       = 0x8054693d
+	SIOCBRDGDELS                      = 0x80546942
+	SIOCBRDGFLUSH                     = 0x80546948
+	SIOCBRDGFRL                       = 0x806e694e
+	SIOCBRDGGCACHE                    = 0xc0146941
+	SIOCBRDGGFD                       = 0xc0146952
+	SIOCBRDGGHT                       = 0xc0146951
+	SIOCBRDGGIFFLGS                   = 0xc054693e
+	SIOCBRDGGMA                       = 0xc0146953
+	SIOCBRDGGPARAM                    = 0xc03c6958
+	SIOCBRDGGPRI                      = 0xc0146950
+	SIOCBRDGGRL                       = 0xc028694f
+	SIOCBRDGGSIFS                     = 0xc054693c
+	SIOCBRDGGTO                       = 0xc0146946
+	SIOCBRDGIFS                       = 0xc0546942
+	SIOCBRDGRTS                       = 0xc0186943
+	SIOCBRDGSADDR                     = 0xc1286944
+	SIOCBRDGSCACHE                    = 0x80146940
+	SIOCBRDGSFD                       = 0x80146952
+	SIOCBRDGSHT                       = 0x80146951
+	SIOCBRDGSIFCOST                   = 0x80546955
+	SIOCBRDGSIFFLGS                   = 0x8054693f
+	SIOCBRDGSIFPRIO                   = 0x80546954
+	SIOCBRDGSMA                       = 0x80146953
+	SIOCBRDGSPRI                      = 0x80146950
+	SIOCBRDGSPROTO                    = 0x8014695a
+	SIOCBRDGSTO                       = 0x80146945
+	SIOCBRDGSTXHC                     = 0x80146959
+	SIOCDELMULTI                      = 0x80206932
+	SIOCDIFADDR                       = 0x80206919
+	SIOCDIFGROUP                      = 0x80246989
+	SIOCDIFPHYADDR                    = 0x80206949
+	SIOCDLIFADDR                      = 0x8218691e
+	SIOCGETKALIVE                     = 0xc01869a4
+	SIOCGETLABEL                      = 0x8020699a
+	SIOCGETPFLOW                      = 0xc02069fe
+	SIOCGETPFSYNC                     = 0xc02069f8
+	SIOCGETSGCNT                      = 0xc0147534
+	SIOCGETVIFCNT                     = 0xc0147533
+	SIOCGETVLAN                       = 0xc0206990
+	SIOCGHIWAT                        = 0x40047301
+	SIOCGIFADDR                       = 0xc0206921
+	SIOCGIFASYNCMAP                   = 0xc020697c
+	SIOCGIFBRDADDR                    = 0xc0206923
+	SIOCGIFCONF                       = 0xc0086924
+	SIOCGIFDATA                       = 0xc020691b
+	SIOCGIFDESCR                      = 0xc0206981
+	SIOCGIFDSTADDR                    = 0xc0206922
+	SIOCGIFFLAGS                      = 0xc0206911
+	SIOCGIFGATTR                      = 0xc024698b
+	SIOCGIFGENERIC                    = 0xc020693a
+	SIOCGIFGMEMB                      = 0xc024698a
+	SIOCGIFGROUP                      = 0xc0246988
+	SIOCGIFHARDMTU                    = 0xc02069a5
+	SIOCGIFMEDIA                      = 0xc0286936
+	SIOCGIFMETRIC                     = 0xc0206917
+	SIOCGIFMTU                        = 0xc020697e
+	SIOCGIFNETMASK                    = 0xc0206925
+	SIOCGIFPDSTADDR                   = 0xc0206948
+	SIOCGIFPRIORITY                   = 0xc020699c
+	SIOCGIFPSRCADDR                   = 0xc0206947
+	SIOCGIFRDOMAIN                    = 0xc02069a0
+	SIOCGIFRTLABEL                    = 0xc0206983
+	SIOCGIFRXR                        = 0x802069aa
+	SIOCGIFTIMESLOT                   = 0xc0206986
+	SIOCGIFXFLAGS                     = 0xc020699e
+	SIOCGLIFADDR                      = 0xc218691d
+	SIOCGLIFPHYADDR                   = 0xc218694b
+	SIOCGLIFPHYRTABLE                 = 0xc02069a2
+	SIOCGLIFPHYTTL                    = 0xc02069a9
+	SIOCGLOWAT                        = 0x40047303
+	SIOCGPGRP                         = 0x40047309
+	SIOCGSPPPPARAMS                   = 0xc0206994
+	SIOCGVH                           = 0xc02069f6
+	SIOCGVNETID                       = 0xc02069a7
+	SIOCIFCREATE                      = 0x8020697a
+	SIOCIFDESTROY                     = 0x80206979
+	SIOCIFGCLONERS                    = 0xc00c6978
+	SIOCSETKALIVE                     = 0x801869a3
+	SIOCSETLABEL                      = 0x80206999
+	SIOCSETPFLOW                      = 0x802069fd
+	SIOCSETPFSYNC                     = 0x802069f7
+	SIOCSETVLAN                       = 0x8020698f
+	SIOCSHIWAT                        = 0x80047300
+	SIOCSIFADDR                       = 0x8020690c
+	SIOCSIFASYNCMAP                   = 0x8020697d
+	SIOCSIFBRDADDR                    = 0x80206913
+	SIOCSIFDESCR                      = 0x80206980
+	SIOCSIFDSTADDR                    = 0x8020690e
+	SIOCSIFFLAGS                      = 0x80206910
+	SIOCSIFGATTR                      = 0x8024698c
+	SIOCSIFGENERIC                    = 0x80206939
+	SIOCSIFLLADDR                     = 0x8020691f
+	SIOCSIFMEDIA                      = 0xc0206935
+	SIOCSIFMETRIC                     = 0x80206918
+	SIOCSIFMTU                        = 0x8020697f
+	SIOCSIFNETMASK                    = 0x80206916
+	SIOCSIFPHYADDR                    = 0x80406946
+	SIOCSIFPRIORITY                   = 0x8020699b
+	SIOCSIFRDOMAIN                    = 0x8020699f
+	SIOCSIFRTLABEL                    = 0x80206982
+	SIOCSIFTIMESLOT                   = 0x80206985
+	SIOCSIFXFLAGS                     = 0x8020699d
+	SIOCSLIFPHYADDR                   = 0x8218694a
+	SIOCSLIFPHYRTABLE                 = 0x802069a1
+	SIOCSLIFPHYTTL                    = 0x802069a8
+	SIOCSLOWAT                        = 0x80047302
+	SIOCSPGRP                         = 0x80047308
+	SIOCSSPPPPARAMS                   = 0x80206993
+	SIOCSVH                           = 0xc02069f5
+	SIOCSVNETID                       = 0x802069a6
+	SOCK_CLOEXEC                      = 0x8000
+	SOCK_DGRAM                        = 0x2
+	SOCK_NONBLOCK                     = 0x4000
+	SOCK_RAW                          = 0x3
+	SOCK_RDM                          = 0x4
+	SOCK_SEQPACKET                    = 0x5
+	SOCK_STREAM                       = 0x1
+	SOL_SOCKET                        = 0xffff
+	SOMAXCONN                         = 0x80
+	SO_ACCEPTCONN                     = 0x2
+	SO_BINDANY                        = 0x1000
+	SO_BROADCAST                      = 0x20
+	SO_DEBUG                          = 0x1
+	SO_DONTROUTE                      = 0x10
+	SO_ERROR                          = 0x1007
+	SO_KEEPALIVE                      = 0x8
+	SO_LINGER                         = 0x80
+	SO_NETPROC                        = 0x1020
+	SO_OOBINLINE                      = 0x100
+	SO_PEERCRED                       = 0x1022
+	SO_RCVBUF                         = 0x1002
+	SO_RCVLOWAT                       = 0x1004
+	SO_RCVTIMEO                       = 0x1006
+	SO_REUSEADDR                      = 0x4
+	SO_REUSEPORT                      = 0x200
+	SO_RTABLE                         = 0x1021
+	SO_SNDBUF                         = 0x1001
+	SO_SNDLOWAT                       = 0x1003
+	SO_SNDTIMEO                       = 0x1005
+	SO_SPLICE                         = 0x1023
+	SO_TIMESTAMP                      = 0x800
+	SO_TYPE                           = 0x1008
+	SO_USELOOPBACK                    = 0x40
+	TCIFLUSH                          = 0x1
+	TCIOFLUSH                         = 0x3
+	TCOFLUSH                          = 0x2
+	TCP_MAXBURST                      = 0x4
+	TCP_MAXSEG                        = 0x2
+	TCP_MAXWIN                        = 0xffff
+	TCP_MAX_SACK                      = 0x3
+	TCP_MAX_WINSHIFT                  = 0xe
+	TCP_MD5SIG                        = 0x4
+	TCP_MSS                           = 0x200
+	TCP_NODELAY                       = 0x1
+	TCP_NOPUSH                        = 0x10
+	TCP_NSTATES                       = 0xb
+	TCP_SACK_ENABLE                   = 0x8
+	TCSAFLUSH                         = 0x2
+	TIOCCBRK                          = 0x2000747a
+	TIOCCDTR                          = 0x20007478
+	TIOCCONS                          = 0x80047462
+	TIOCDRAIN                         = 0x2000745e
+	TIOCEXCL                          = 0x2000740d
+	TIOCEXT                           = 0x80047460
+	TIOCFLAG_CLOCAL                   = 0x2
+	TIOCFLAG_CRTSCTS                  = 0x4
+	TIOCFLAG_MDMBUF                   = 0x8
+	TIOCFLAG_PPS                      = 0x10
+	TIOCFLAG_SOFTCAR                  = 0x1
+	TIOCFLUSH                         = 0x80047410
+	TIOCGETA                          = 0x402c7413
+	TIOCGETD                          = 0x4004741a
+	TIOCGFLAGS                        = 0x4004745d
+	TIOCGPGRP                         = 0x40047477
+	TIOCGSID                          = 0x40047463
+	TIOCGTSTAMP                       = 0x400c745b
+	TIOCGWINSZ                        = 0x40087468
+	TIOCMBIC                          = 0x8004746b
+	TIOCMBIS                          = 0x8004746c
+	TIOCMGET                          = 0x4004746a
+	TIOCMODG                          = 0x4004746a
+	TIOCMODS                          = 0x8004746d
+	TIOCMSET                          = 0x8004746d
+	TIOCM_CAR                         = 0x40
+	TIOCM_CD                          = 0x40
+	TIOCM_CTS                         = 0x20
+	TIOCM_DSR                         = 0x100
+	TIOCM_DTR                         = 0x2
+	TIOCM_LE                          = 0x1
+	TIOCM_RI                          = 0x80
+	TIOCM_RNG                         = 0x80
+	TIOCM_RTS                         = 0x4
+	TIOCM_SR                          = 0x10
+	TIOCM_ST                          = 0x8
+	TIOCNOTTY                         = 0x20007471
+	TIOCNXCL                          = 0x2000740e
+	TIOCOUTQ                          = 0x40047473
+	TIOCPKT                           = 0x80047470
+	TIOCPKT_DATA                      = 0x0
+	TIOCPKT_DOSTOP                    = 0x20
+	TIOCPKT_FLUSHREAD                 = 0x1
+	TIOCPKT_FLUSHWRITE                = 0x2
+	TIOCPKT_IOCTL                     = 0x40
+	TIOCPKT_NOSTOP                    = 0x10
+	TIOCPKT_START                     = 0x8
+	TIOCPKT_STOP                      = 0x4
+	TIOCREMOTE                        = 0x80047469
+	TIOCSBRK                          = 0x2000747b
+	TIOCSCTTY                         = 0x20007461
+	TIOCSDTR                          = 0x20007479
+	TIOCSETA                          = 0x802c7414
+	TIOCSETAF                         = 0x802c7416
+	TIOCSETAW                         = 0x802c7415
+	TIOCSETD                          = 0x8004741b
+	TIOCSFLAGS                        = 0x8004745c
+	TIOCSIG                           = 0x8004745f
+	TIOCSPGRP                         = 0x80047476
+	TIOCSTART                         = 0x2000746e
+	TIOCSTAT                          = 0x80047465
+	TIOCSTI                           = 0x80017472
+	TIOCSTOP                          = 0x2000746f
+	TIOCSTSTAMP                       = 0x8008745a
+	TIOCSWINSZ                        = 0x80087467
+	TIOCUCNTL                         = 0x80047466
+	TOSTOP                            = 0x400000
+	VDISCARD                          = 0xf
+	VDSUSP                            = 0xb
+	VEOF                              = 0x0
+	VEOL                              = 0x1
+	VEOL2                             = 0x2
+	VERASE                            = 0x3
+	VINTR                             = 0x8
+	VKILL                             = 0x5
+	VLNEXT                            = 0xe
+	VMIN                              = 0x10
+	VQUIT                             = 0x9
+	VREPRINT                          = 0x6
+	VSTART                            = 0xc
+	VSTATUS                           = 0x12
+	VSTOP                             = 0xd
+	VSUSP                             = 0xa
+	VTIME                             = 0x11
+	VWERASE                           = 0x4
+	WALTSIG                           = 0x4
+	WCONTINUED                        = 0x8
+	WCOREFLAG                         = 0x80
+	WNOHANG                           = 0x1
+	WUNTRACED                         = 0x2
+)
+
+// Errors
+const (
+	E2BIG           = syscall.Errno(0x7)
+	EACCES          = syscall.Errno(0xd)
+	EADDRINUSE      = syscall.Errno(0x30)
+	EADDRNOTAVAIL   = syscall.Errno(0x31)
+	EAFNOSUPPORT    = syscall.Errno(0x2f)
+	EAGAIN          = syscall.Errno(0x23)
+	EALREADY        = syscall.Errno(0x25)
+	EAUTH           = syscall.Errno(0x50)
+	EBADF           = syscall.Errno(0x9)
+	EBADRPC         = syscall.Errno(0x48)
+	EBUSY           = syscall.Errno(0x10)
+	ECANCELED       = syscall.Errno(0x58)
+	ECHILD          = syscall.Errno(0xa)
+	ECONNABORTED    = syscall.Errno(0x35)
+	ECONNREFUSED    = syscall.Errno(0x3d)
+	ECONNRESET      = syscall.Errno(0x36)
+	EDEADLK         = syscall.Errno(0xb)
+	EDESTADDRREQ    = syscall.Errno(0x27)
+	EDOM            = syscall.Errno(0x21)
+	EDQUOT          = syscall.Errno(0x45)
+	EEXIST          = syscall.Errno(0x11)
+	EFAULT          = syscall.Errno(0xe)
+	EFBIG           = syscall.Errno(0x1b)
+	EFTYPE          = syscall.Errno(0x4f)
+	EHOSTDOWN       = syscall.Errno(0x40)
+	EHOSTUNREACH    = syscall.Errno(0x41)
+	EIDRM           = syscall.Errno(0x59)
+	EILSEQ          = syscall.Errno(0x54)
+	EINPROGRESS     = syscall.Errno(0x24)
+	EINTR           = syscall.Errno(0x4)
+	EINVAL          = syscall.Errno(0x16)
+	EIO             = syscall.Errno(0x5)
+	EIPSEC          = syscall.Errno(0x52)
+	EISCONN         = syscall.Errno(0x38)
+	EISDIR          = syscall.Errno(0x15)
+	ELAST           = syscall.Errno(0x5b)
+	ELOOP           = syscall.Errno(0x3e)
+	EMEDIUMTYPE     = syscall.Errno(0x56)
+	EMFILE          = syscall.Errno(0x18)
+	EMLINK          = syscall.Errno(0x1f)
+	EMSGSIZE        = syscall.Errno(0x28)
+	ENAMETOOLONG    = syscall.Errno(0x3f)
+	ENEEDAUTH       = syscall.Errno(0x51)
+	ENETDOWN        = syscall.Errno(0x32)
+	ENETRESET       = syscall.Errno(0x34)
+	ENETUNREACH     = syscall.Errno(0x33)
+	ENFILE          = syscall.Errno(0x17)
+	ENOATTR         = syscall.Errno(0x53)
+	ENOBUFS         = syscall.Errno(0x37)
+	ENODEV          = syscall.Errno(0x13)
+	ENOENT          = syscall.Errno(0x2)
+	ENOEXEC         = syscall.Errno(0x8)
+	ENOLCK          = syscall.Errno(0x4d)
+	ENOMEDIUM       = syscall.Errno(0x55)
+	ENOMEM          = syscall.Errno(0xc)
+	ENOMSG          = syscall.Errno(0x5a)
+	ENOPROTOOPT     = syscall.Errno(0x2a)
+	ENOSPC          = syscall.Errno(0x1c)
+	ENOSYS          = syscall.Errno(0x4e)
+	ENOTBLK         = syscall.Errno(0xf)
+	ENOTCONN        = syscall.Errno(0x39)
+	ENOTDIR         = syscall.Errno(0x14)
+	ENOTEMPTY       = syscall.Errno(0x42)
+	ENOTSOCK        = syscall.Errno(0x26)
+	ENOTSUP         = syscall.Errno(0x5b)
+	ENOTTY          = syscall.Errno(0x19)
+	ENXIO           = syscall.Errno(0x6)
+	EOPNOTSUPP      = syscall.Errno(0x2d)
+	EOVERFLOW       = syscall.Errno(0x57)
+	EPERM           = syscall.Errno(0x1)
+	EPFNOSUPPORT    = syscall.Errno(0x2e)
+	EPIPE           = syscall.Errno(0x20)
+	EPROCLIM        = syscall.Errno(0x43)
+	EPROCUNAVAIL    = syscall.Errno(0x4c)
+	EPROGMISMATCH   = syscall.Errno(0x4b)
+	EPROGUNAVAIL    = syscall.Errno(0x4a)
+	EPROTONOSUPPORT = syscall.Errno(0x2b)
+	EPROTOTYPE      = syscall.Errno(0x29)
+	ERANGE          = syscall.Errno(0x22)
+	EREMOTE         = syscall.Errno(0x47)
+	EROFS           = syscall.Errno(0x1e)
+	ERPCMISMATCH    = syscall.Errno(0x49)
+	ESHUTDOWN       = syscall.Errno(0x3a)
+	ESOCKTNOSUPPORT = syscall.Errno(0x2c)
+	ESPIPE          = syscall.Errno(0x1d)
+	ESRCH           = syscall.Errno(0x3)
+	ESTALE          = syscall.Errno(0x46)
+	ETIMEDOUT       = syscall.Errno(0x3c)
+	ETOOMANYREFS    = syscall.Errno(0x3b)
+	ETXTBSY         = syscall.Errno(0x1a)
+	EUSERS          = syscall.Errno(0x44)
+	EWOULDBLOCK     = syscall.Errno(0x23)
+	EXDEV           = syscall.Errno(0x12)
+)
+
+// Signals
+const (
+	SIGABRT   = syscall.Signal(0x6)
+	SIGALRM   = syscall.Signal(0xe)
+	SIGBUS    = syscall.Signal(0xa)
+	SIGCHLD   = syscall.Signal(0x14)
+	SIGCONT   = syscall.Signal(0x13)
+	SIGEMT    = syscall.Signal(0x7)
+	SIGFPE    = syscall.Signal(0x8)
+	SIGHUP    = syscall.Signal(0x1)
+	SIGILL    = syscall.Signal(0x4)
+	SIGINFO   = syscall.Signal(0x1d)
+	SIGINT    = syscall.Signal(0x2)
+	SIGIO     = syscall.Signal(0x17)
+	SIGIOT    = syscall.Signal(0x6)
+	SIGKILL   = syscall.Signal(0x9)
+	SIGPIPE   = syscall.Signal(0xd)
+	SIGPROF   = syscall.Signal(0x1b)
+	SIGQUIT   = syscall.Signal(0x3)
+	SIGSEGV   = syscall.Signal(0xb)
+	SIGSTOP   = syscall.Signal(0x11)
+	SIGSYS    = syscall.Signal(0xc)
+	SIGTERM   = syscall.Signal(0xf)
+	SIGTHR    = syscall.Signal(0x20)
+	SIGTRAP   = syscall.Signal(0x5)
+	SIGTSTP   = syscall.Signal(0x12)
+	SIGTTIN   = syscall.Signal(0x15)
+	SIGTTOU   = syscall.Signal(0x16)
+	SIGURG    = syscall.Signal(0x10)
+	SIGUSR1   = syscall.Signal(0x1e)
+	SIGUSR2   = syscall.Signal(0x1f)
+	SIGVTALRM = syscall.Signal(0x1a)
+	SIGWINCH  = syscall.Signal(0x1c)
+	SIGXCPU   = syscall.Signal(0x18)
+	SIGXFSZ   = syscall.Signal(0x19)
+)
+
+// Error table
+var errors = [...]string{
+	1:  "operation not permitted",
+	2:  "no such file or directory",
+	3:  "no such process",
+	4:  "interrupted system call",
+	5:  "input/output error",
+	6:  "device not configured",
+	7:  "argument list too long",
+	8:  "exec format error",
+	9:  "bad file descriptor",
+	10: "no child processes",
+	11: "resource deadlock avoided",
+	12: "cannot allocate memory",
+	13: "permission denied",
+	14: "bad address",
+	15: "block device required",
+	16: "device busy",
+	17: "file exists",
+	18: "cross-device link",
+	19: "operation not supported by device",
+	20: "not a directory",
+	21: "is a directory",
+	22: "invalid argument",
+	23: "too many open files in system",
+	24: "too many open files",
+	25: "inappropriate ioctl for device",
+	26: "text file busy",
+	27: "file too large",
+	28: "no space left on device",
+	29: "illegal seek",
+	30: "read-only file system",
+	31: "too many links",
+	32: "broken pipe",
+	33: "numerical argument out of domain",
+	34: "result too large",
+	35: "resource temporarily unavailable",
+	36: "operation now in progress",
+	37: "operation already in progress",
+	38: "socket operation on non-socket",
+	39: "destination address required",
+	40: "message too long",
+	41: "protocol wrong type for socket",
+	42: "protocol not available",
+	43: "protocol not supported",
+	44: "socket type not supported",
+	45: "operation not supported",
+	46: "protocol family not supported",
+	47: "address family not supported by protocol family",
+	48: "address already in use",
+	49: "can't assign requested address",
+	50: "network is down",
+	51: "network is unreachable",
+	52: "network dropped connection on reset",
+	53: "software caused connection abort",
+	54: "connection reset by peer",
+	55: "no buffer space available",
+	56: "socket is already connected",
+	57: "socket is not connected",
+	58: "can't send after socket shutdown",
+	59: "too many references: can't splice",
+	60: "connection timed out",
+	61: "connection refused",
+	62: "too many levels of symbolic links",
+	63: "file name too long",
+	64: "host is down",
+	65: "no route to host",
+	66: "directory not empty",
+	67: "too many processes",
+	68: "too many users",
+	69: "disc quota exceeded",
+	70: "stale NFS file handle",
+	71: "too many levels of remote in path",
+	72: "RPC struct is bad",
+	73: "RPC version wrong",
+	74: "RPC prog. not avail",
+	75: "program version wrong",
+	76: "bad procedure for program",
+	77: "no locks available",
+	78: "function not implemented",
+	79: "inappropriate file type or format",
+	80: "authentication error",
+	81: "need authenticator",
+	82: "IPsec processing failure",
+	83: "attribute not found",
+	84: "illegal byte sequence",
+	85: "no medium found",
+	86: "wrong medium type",
+	87: "value too large to be stored in data type",
+	88: "operation canceled",
+	89: "identifier removed",
+	90: "no message of desired type",
+	91: "not supported",
+}
+
+// Signal table
+var signals = [...]string{
+	1:  "hangup",
+	2:  "interrupt",
+	3:  "quit",
+	4:  "illegal instruction",
+	5:  "trace/BPT trap",
+	6:  "abort trap",
+	7:  "EMT trap",
+	8:  "floating point exception",
+	9:  "killed",
+	10: "bus error",
+	11: "segmentation fault",
+	12: "bad system call",
+	13: "broken pipe",
+	14: "alarm clock",
+	15: "terminated",
+	16: "urgent I/O condition",
+	17: "stopped (signal)",
+	18: "stopped",
+	19: "continued",
+	20: "child exited",
+	21: "stopped (tty input)",
+	22: "stopped (tty output)",
+	23: "I/O possible",
+	24: "cputime limit exceeded",
+	25: "filesize limit exceeded",
+	26: "virtual timer expired",
+	27: "profiling timer expired",
+	28: "window size changes",
+	29: "information request",
+	30: "user defined signal 1",
+	31: "user defined signal 2",
+	32: "thread AST",
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
index e48f4a5..10491e9 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -l32 -tags darwin,386 syscall_bsd.go syscall_darwin.go syscall_darwin_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build darwin,386
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
 	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
@@ -298,6 +398,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -456,6 +566,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -486,6 +611,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -496,6 +636,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
@@ -745,6 +900,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Listen(s int, backlog int) (err error) {
 	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
@@ -785,6 +960,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Mkfifo(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -815,74 +1005,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Open(path string, mode int, perm uint32) (fd int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -899,6 +1021,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Pathconf(path string, name int) (val int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -988,6 +1126,28 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Rename(from string, to string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(from)
@@ -1008,6 +1168,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Revoke(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1245,6 +1425,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() (err error) {
 	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
 	if e1 != 0 {
@@ -1308,6 +1508,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Unmount(path string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
index 672ada0..5f1f6bf 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build darwin,amd64
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
 	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
@@ -298,6 +398,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -456,6 +566,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -486,6 +611,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -496,6 +636,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
@@ -745,6 +900,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Listen(s int, backlog int) (err error) {
 	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
@@ -785,6 +960,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Mkfifo(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -815,74 +1005,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Open(path string, mode int, perm uint32) (fd int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -899,6 +1021,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Pathconf(path string, name int) (val int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -988,6 +1126,28 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Rename(from string, to string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(from)
@@ -1008,6 +1168,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Revoke(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1245,6 +1425,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() (err error) {
 	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
 	if e1 != 0 {
@@ -1308,6 +1508,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Unmount(path string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1383,21 +1598,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
 	r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
 	sec = int64(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
index d516409..7a40974 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.go
@@ -1,5 +1,5 @@
-// mksyscall.pl -l32 -tags darwin,arm syscall_bsd.go syscall_darwin.go syscall_darwin_arm.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// mksyscall.pl -tags darwin,arm syscall_bsd.go syscall_darwin.go syscall_darwin_arm.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build darwin,arm
 
@@ -221,7 +221,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := Syscall6(SYS_SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
 	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
@@ -298,6 +398,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -456,6 +566,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -486,6 +611,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -496,6 +636,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
@@ -745,6 +900,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Listen(s int, backlog int) (err error) {
 	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
@@ -785,6 +960,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Mkfifo(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -815,74 +1005,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Open(path string, mode int, perm uint32) (fd int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -899,6 +1021,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Pathconf(path string, name int) (val int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -988,6 +1126,28 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Rename(from string, to string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(from)
@@ -1008,6 +1168,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Revoke(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1245,6 +1425,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() (err error) {
 	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
 	if e1 != 0 {
@@ -1308,6 +1508,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Unmount(path string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
index e97759c..07c6ebc 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -tags darwin,arm64 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build darwin,arm64
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
 	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
@@ -298,6 +398,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -456,6 +566,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -486,6 +611,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -496,6 +636,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
@@ -745,6 +900,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Listen(s int, backlog int) (err error) {
 	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
@@ -785,6 +960,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Mkfifo(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -815,74 +1005,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Open(path string, mode int, perm uint32) (fd int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -899,6 +1021,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Pathconf(path string, name int) (val int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -988,6 +1126,28 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Rename(from string, to string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(from)
@@ -1008,6 +1168,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Revoke(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1245,6 +1425,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() (err error) {
 	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
 	if e1 != 0 {
@@ -1308,6 +1508,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Unmount(path string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
index eafceb8..7fa205c 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe() (r int, w int, err error) {
 	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
 	r = int(r0)
@@ -829,74 +929,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1391,3 +1423,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
index f53801c..1a0bb4c 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -l32 -tags freebsd,386 syscall_bsd.go syscall_freebsd.go syscall_freebsd_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build freebsd,386
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe() (r int, w int, err error) {
 	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
 	r = int(r0)
@@ -278,6 +378,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -303,6 +413,36 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func CapEnter() (err error) {
+	_, _, e1 := Syscall(SYS_CAP_ENTER, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsGet(version int, fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS___CAP_RIGHTS_GET, uintptr(version), uintptr(fd), uintptr(unsafe.Pointer(rightsp)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsLimit(fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS_CAP_RIGHTS_LIMIT, uintptr(fd), uintptr(unsafe.Pointer(rightsp)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Chdir(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -640,6 +780,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -670,6 +825,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -680,6 +850,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
@@ -949,6 +1134,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Listen(s int, backlog int) (err error) {
 	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
@@ -989,6 +1194,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Mkfifo(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1019,74 +1239,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1113,6 +1265,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(fdat), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Pathconf(path string, name int) (val int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1202,6 +1370,28 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Rename(from string, to string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(from)
@@ -1222,6 +1412,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Revoke(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1469,6 +1679,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() (err error) {
 	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
 	if e1 != 0 {
@@ -1532,6 +1762,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Unmount(path string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1615,3 +1860,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
index 55b0741..ac1e8e0 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -tags freebsd,amd64 syscall_bsd.go syscall_freebsd.go syscall_freebsd_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build freebsd,amd64
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe() (r int, w int, err error) {
 	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
 	r = int(r0)
@@ -278,6 +378,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -303,6 +413,36 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func CapEnter() (err error) {
+	_, _, e1 := Syscall(SYS_CAP_ENTER, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsGet(version int, fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS___CAP_RIGHTS_GET, uintptr(version), uintptr(fd), uintptr(unsafe.Pointer(rightsp)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsLimit(fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS_CAP_RIGHTS_LIMIT, uintptr(fd), uintptr(unsafe.Pointer(rightsp)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Chdir(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -640,6 +780,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -670,6 +825,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -680,6 +850,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
@@ -949,6 +1134,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Listen(s int, backlog int) (err error) {
 	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
@@ -989,6 +1194,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Mkfifo(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1019,74 +1239,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1113,6 +1265,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(fdat), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Pathconf(path string, name int) (val int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1202,6 +1370,28 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Rename(from string, to string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(from)
@@ -1222,6 +1412,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Revoke(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1469,6 +1679,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() (err error) {
 	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
 	if e1 != 0 {
@@ -1532,6 +1762,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Unmount(path string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1615,3 +1860,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
index 0e9b42b..2b4e6ac 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -l32 -arm -tags freebsd,arm syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build freebsd,arm
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe() (r int, w int, err error) {
 	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
 	r = int(r0)
@@ -278,6 +378,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -303,6 +413,36 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func CapEnter() (err error) {
+	_, _, e1 := Syscall(SYS_CAP_ENTER, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsGet(version int, fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS___CAP_RIGHTS_GET, uintptr(version), uintptr(fd), uintptr(unsafe.Pointer(rightsp)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsLimit(fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS_CAP_RIGHTS_LIMIT, uintptr(fd), uintptr(unsafe.Pointer(rightsp)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Chdir(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -640,6 +780,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchdir(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -670,6 +825,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -680,6 +850,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Flock(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
@@ -949,6 +1134,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Listen(s int, backlog int) (err error) {
 	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
@@ -989,6 +1194,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Mkfifo(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1019,74 +1239,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1113,6 +1265,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(fdat), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Pathconf(path string, name int) (val int, err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1202,6 +1370,28 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Rename(from string, to string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(from)
@@ -1222,6 +1412,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Revoke(path string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1469,6 +1679,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sync() (err error) {
 	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
 	if e1 != 0 {
@@ -1532,6 +1762,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Unmount(path string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1615,3 +1860,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
index 6c08450..38c1bbd 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
index f34418d..dc8fe0a 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
index 92b4716..4d28042 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
index ec55920..20ad4b6 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
index e6c2bf5..9f194dc 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
index f77f1d0..4fde3ef 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
index d6ce861..f646342 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
index c013406..964591e 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
index 6b7a291..204ab1a 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
index 7585277..a8a2b0b 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
index 987ce86..b6ff9e3 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
@@ -1234,6 +1234,16 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Syncfs(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Sysinfo(info *Sysinfo_t) (err error) {
 	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
 	if e1 != 0 {
@@ -1462,6 +1472,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlockall() (err error) {
 	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
 	if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
index 3182345..db99fd0 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -l32 -netbsd -tags netbsd,386 syscall_bsd.go syscall_netbsd.go syscall_netbsd_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build netbsd,386
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe() (fd1 int, fd2 int, err error) {
 	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
 	fd1 = int(r0)
@@ -777,74 +877,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1297,3 +1329,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
index 74ba818..7b6c2c8 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -netbsd -tags netbsd,amd64 syscall_bsd.go syscall_netbsd.go syscall_netbsd_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build netbsd,amd64
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe() (fd1 int, fd2 int, err error) {
 	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
 	fd1 = int(r0)
@@ -777,74 +877,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1297,3 +1329,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
index 1f346e2..0f4cc3b 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go
@@ -1,5 +1,5 @@
-// mksyscall.pl -l32 -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// mksyscall.pl -l32 -netbsd -arm -tags netbsd,arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build netbsd,arm
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe() (fd1 int, fd2 int, err error) {
 	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
 	fd1 = int(r0)
@@ -777,74 +877,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1297,3 +1329,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
index ca3e813..7baea87 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -l32 -openbsd -tags openbsd,386 syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build openbsd,386
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe(p *[2]_C_int) (err error) {
 	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
@@ -785,74 +885,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1355,3 +1387,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
index bf63d55..0d69ce6 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
@@ -1,5 +1,5 @@
 // mksyscall.pl -openbsd -tags openbsd,amd64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build openbsd,amd64
 
@@ -266,6 +266,106 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe(p *[2]_C_int) (err error) {
 	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
@@ -785,74 +885,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1355,3 +1387,18 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
new file mode 100644
index 0000000..41572c2
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
@@ -0,0 +1,1404 @@
+// mksyscall.pl -l32 -openbsd -arm -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+// +build openbsd,arm
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var _ syscall.Errno
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum syscall.Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
index d1ed021..4287133 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
@@ -43,6 +43,7 @@
 //go:cgo_import_dynamic libc_fchown fchown "libc.so"
 //go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
 //go:cgo_import_dynamic libc_fdatasync fdatasync "libc.so"
+//go:cgo_import_dynamic libc_flock flock "libc.so"
 //go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
 //go:cgo_import_dynamic libc_fstat fstat "libc.so"
 //go:cgo_import_dynamic libc_fstatvfs fstatvfs "libc.so"
@@ -163,6 +164,7 @@
 //go:linkname procFchown libc_fchown
 //go:linkname procFchownat libc_fchownat
 //go:linkname procFdatasync libc_fdatasync
+//go:linkname procFlock libc_flock
 //go:linkname procFpathconf libc_fpathconf
 //go:linkname procFstat libc_fstat
 //go:linkname procFstatvfs libc_fstatvfs
@@ -284,6 +286,7 @@
 	procFchown,
 	procFchownat,
 	procFdatasync,
+	procFlock,
 	procFpathconf,
 	procFstat,
 	procFstatvfs,
@@ -702,6 +705,14 @@
 	return
 }
 
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFlock)), 2, uintptr(fd), uintptr(how), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
 func Fpathconf(fd int, name int) (val int, err error) {
 	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFpathconf)), 2, uintptr(fd), uintptr(name), 0, 0, 0, 0)
 	val = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go
index b8c9aea..41cb6ed 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm.go
@@ -1,5 +1,5 @@
-// mksysnum_darwin.pl /usr/include/sys/syscall.h
-// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk/usr/include/sys/syscall.h
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build arm,darwin
 
@@ -121,12 +121,14 @@
 	SYS_CSOPS                          = 169
 	SYS_CSOPS_AUDITTOKEN               = 170
 	SYS_WAITID                         = 173
+	SYS_KDEBUG_TYPEFILTER              = 177
+	SYS_KDEBUG_TRACE_STRING            = 178
+	SYS_KDEBUG_TRACE64                 = 179
 	SYS_KDEBUG_TRACE                   = 180
 	SYS_SETGID                         = 181
 	SYS_SETEGID                        = 182
 	SYS_SETEUID                        = 183
 	SYS_SIGRETURN                      = 184
-	SYS_CHUD                           = 185
 	SYS_FDATASYNC                      = 187
 	SYS_STAT                           = 188
 	SYS_FSTAT                          = 189
@@ -140,17 +142,10 @@
 	SYS_LSEEK                          = 199
 	SYS_TRUNCATE                       = 200
 	SYS_FTRUNCATE                      = 201
-	SYS___SYSCTL                       = 202
+	SYS_SYSCTL                         = 202
 	SYS_MLOCK                          = 203
 	SYS_MUNLOCK                        = 204
 	SYS_UNDELETE                       = 205
-	SYS_ATSOCKET                       = 206
-	SYS_ATGETMSG                       = 207
-	SYS_ATPUTMSG                       = 208
-	SYS_ATPSNDREQ                      = 209
-	SYS_ATPSNDRSP                      = 210
-	SYS_ATPGETREQ                      = 211
-	SYS_ATPGETRSP                      = 212
 	SYS_OPEN_DPROTECTED_NP             = 216
 	SYS_GETATTRLIST                    = 220
 	SYS_SETATTRLIST                    = 221
@@ -202,9 +197,7 @@
 	SYS_SEM_WAIT                       = 271
 	SYS_SEM_TRYWAIT                    = 272
 	SYS_SEM_POST                       = 273
-	SYS_SEM_GETVALUE                   = 274
-	SYS_SEM_INIT                       = 275
-	SYS_SEM_DESTROY                    = 276
+	SYS_SYSCTLBYNAME                   = 274
 	SYS_OPEN_EXTENDED                  = 277
 	SYS_UMASK_EXTENDED                 = 278
 	SYS_STAT_EXTENDED                  = 279
@@ -286,7 +279,6 @@
 	SYS_KQUEUE                         = 362
 	SYS_KEVENT                         = 363
 	SYS_LCHOWN                         = 364
-	SYS_STACK_SNAPSHOT                 = 365
 	SYS_BSDTHREAD_REGISTER             = 366
 	SYS_WORKQ_OPEN                     = 367
 	SYS_WORKQ_KERNRETURN               = 368
@@ -295,6 +287,7 @@
 	SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL  = 371
 	SYS_THREAD_SELFID                  = 372
 	SYS_LEDGER                         = 373
+	SYS_KEVENT_QOS                     = 374
 	SYS___MAC_EXECVE                   = 380
 	SYS___MAC_SYSCALL                  = 381
 	SYS___MAC_GET_FILE                 = 382
@@ -306,11 +299,8 @@
 	SYS___MAC_GET_FD                   = 388
 	SYS___MAC_SET_FD                   = 389
 	SYS___MAC_GET_PID                  = 390
-	SYS___MAC_GET_LCID                 = 391
-	SYS___MAC_GET_LCTX                 = 392
-	SYS___MAC_SET_LCTX                 = 393
-	SYS_SETLCID                        = 394
-	SYS_GETLCID                        = 395
+	SYS_PSELECT                        = 394
+	SYS_PSELECT_NOCANCEL               = 395
 	SYS_READ_NOCANCEL                  = 396
 	SYS_WRITE_NOCANCEL                 = 397
 	SYS_OPEN_NOCANCEL                  = 398
@@ -354,5 +344,83 @@
 	SYS_PID_SHUTDOWN_SOCKETS           = 436
 	SYS_SHARED_REGION_MAP_AND_SLIDE_NP = 438
 	SYS_KAS_INFO                       = 439
-	SYS_MAXSYSCALL                     = 440
+	SYS_MEMORYSTATUS_CONTROL           = 440
+	SYS_GUARDED_OPEN_NP                = 441
+	SYS_GUARDED_CLOSE_NP               = 442
+	SYS_GUARDED_KQUEUE_NP              = 443
+	SYS_CHANGE_FDGUARD_NP              = 444
+	SYS_USRCTL                         = 445
+	SYS_PROC_RLIMIT_CONTROL            = 446
+	SYS_CONNECTX                       = 447
+	SYS_DISCONNECTX                    = 448
+	SYS_PEELOFF                        = 449
+	SYS_SOCKET_DELEGATE                = 450
+	SYS_TELEMETRY                      = 451
+	SYS_PROC_UUID_POLICY               = 452
+	SYS_MEMORYSTATUS_GET_LEVEL         = 453
+	SYS_SYSTEM_OVERRIDE                = 454
+	SYS_VFS_PURGE                      = 455
+	SYS_SFI_CTL                        = 456
+	SYS_SFI_PIDCTL                     = 457
+	SYS_COALITION                      = 458
+	SYS_COALITION_INFO                 = 459
+	SYS_NECP_MATCH_POLICY              = 460
+	SYS_GETATTRLISTBULK                = 461
+	SYS_CLONEFILEAT                    = 462
+	SYS_OPENAT                         = 463
+	SYS_OPENAT_NOCANCEL                = 464
+	SYS_RENAMEAT                       = 465
+	SYS_FACCESSAT                      = 466
+	SYS_FCHMODAT                       = 467
+	SYS_FCHOWNAT                       = 468
+	SYS_FSTATAT                        = 469
+	SYS_FSTATAT64                      = 470
+	SYS_LINKAT                         = 471
+	SYS_UNLINKAT                       = 472
+	SYS_READLINKAT                     = 473
+	SYS_SYMLINKAT                      = 474
+	SYS_MKDIRAT                        = 475
+	SYS_GETATTRLISTAT                  = 476
+	SYS_PROC_TRACE_LOG                 = 477
+	SYS_BSDTHREAD_CTL                  = 478
+	SYS_OPENBYID_NP                    = 479
+	SYS_RECVMSG_X                      = 480
+	SYS_SENDMSG_X                      = 481
+	SYS_THREAD_SELFUSAGE               = 482
+	SYS_CSRCTL                         = 483
+	SYS_GUARDED_OPEN_DPROTECTED_NP     = 484
+	SYS_GUARDED_WRITE_NP               = 485
+	SYS_GUARDED_PWRITE_NP              = 486
+	SYS_GUARDED_WRITEV_NP              = 487
+	SYS_RENAMEATX_NP                   = 488
+	SYS_MREMAP_ENCRYPTED               = 489
+	SYS_NETAGENT_TRIGGER               = 490
+	SYS_STACK_SNAPSHOT_WITH_CONFIG     = 491
+	SYS_MICROSTACKSHOT                 = 492
+	SYS_GRAB_PGO_DATA                  = 493
+	SYS_PERSONA                        = 494
+	SYS_WORK_INTERVAL_CTL              = 499
+	SYS_GETENTROPY                     = 500
+	SYS_NECP_OPEN                      = 501
+	SYS_NECP_CLIENT_ACTION             = 502
+	SYS___NEXUS_OPEN                   = 503
+	SYS___NEXUS_REGISTER               = 504
+	SYS___NEXUS_DEREGISTER             = 505
+	SYS___NEXUS_CREATE                 = 506
+	SYS___NEXUS_DESTROY                = 507
+	SYS___NEXUS_GET_OPT                = 508
+	SYS___NEXUS_SET_OPT                = 509
+	SYS___CHANNEL_OPEN                 = 510
+	SYS___CHANNEL_GET_INFO             = 511
+	SYS___CHANNEL_SYNC                 = 512
+	SYS___CHANNEL_GET_OPT              = 513
+	SYS___CHANNEL_SET_OPT              = 514
+	SYS_ULOCK_WAIT                     = 515
+	SYS_ULOCK_WAKE                     = 516
+	SYS_FCLONEFILEAT                   = 517
+	SYS_FS_SNAPSHOT                    = 518
+	SYS_TERMINATE_WITH_PAYLOAD         = 520
+	SYS_ABORT_WITH_PAYLOAD             = 521
+	SYS_MAXSYSCALL                     = 522
+	SYS_INVALID                        = 63
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go
index 26677eb..075816c 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_darwin_arm64.go
@@ -1,5 +1,5 @@
-// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk/usr/include/sys/syscall.h
-// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+// mksysnum_darwin.pl /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk/usr/include/sys/syscall.h
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build arm64,darwin
 
@@ -121,13 +121,14 @@
 	SYS_CSOPS                          = 169
 	SYS_CSOPS_AUDITTOKEN               = 170
 	SYS_WAITID                         = 173
+	SYS_KDEBUG_TYPEFILTER              = 177
+	SYS_KDEBUG_TRACE_STRING            = 178
 	SYS_KDEBUG_TRACE64                 = 179
 	SYS_KDEBUG_TRACE                   = 180
 	SYS_SETGID                         = 181
 	SYS_SETEGID                        = 182
 	SYS_SETEUID                        = 183
 	SYS_SIGRETURN                      = 184
-	SYS_CHUD                           = 185
 	SYS_FDATASYNC                      = 187
 	SYS_STAT                           = 188
 	SYS_FSTAT                          = 189
@@ -278,7 +279,6 @@
 	SYS_KQUEUE                         = 362
 	SYS_KEVENT                         = 363
 	SYS_LCHOWN                         = 364
-	SYS_STACK_SNAPSHOT                 = 365
 	SYS_BSDTHREAD_REGISTER             = 366
 	SYS_WORKQ_OPEN                     = 367
 	SYS_WORKQ_KERNRETURN               = 368
@@ -287,6 +287,7 @@
 	SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL  = 371
 	SYS_THREAD_SELFID                  = 372
 	SYS_LEDGER                         = 373
+	SYS_KEVENT_QOS                     = 374
 	SYS___MAC_EXECVE                   = 380
 	SYS___MAC_SYSCALL                  = 381
 	SYS___MAC_GET_FILE                 = 382
@@ -298,11 +299,8 @@
 	SYS___MAC_GET_FD                   = 388
 	SYS___MAC_SET_FD                   = 389
 	SYS___MAC_GET_PID                  = 390
-	SYS___MAC_GET_LCID                 = 391
-	SYS___MAC_GET_LCTX                 = 392
-	SYS___MAC_SET_LCTX                 = 393
-	SYS_SETLCID                        = 394
-	SYS_GETLCID                        = 395
+	SYS_PSELECT                        = 394
+	SYS_PSELECT_NOCANCEL               = 395
 	SYS_READ_NOCANCEL                  = 396
 	SYS_WRITE_NOCANCEL                 = 397
 	SYS_OPEN_NOCANCEL                  = 398
@@ -351,6 +349,7 @@
 	SYS_GUARDED_CLOSE_NP               = 442
 	SYS_GUARDED_KQUEUE_NP              = 443
 	SYS_CHANGE_FDGUARD_NP              = 444
+	SYS_USRCTL                         = 445
 	SYS_PROC_RLIMIT_CONTROL            = 446
 	SYS_CONNECTX                       = 447
 	SYS_DISCONNECTX                    = 448
@@ -367,6 +366,7 @@
 	SYS_COALITION_INFO                 = 459
 	SYS_NECP_MATCH_POLICY              = 460
 	SYS_GETATTRLISTBULK                = 461
+	SYS_CLONEFILEAT                    = 462
 	SYS_OPENAT                         = 463
 	SYS_OPENAT_NOCANCEL                = 464
 	SYS_RENAMEAT                       = 465
@@ -392,7 +392,35 @@
 	SYS_GUARDED_WRITE_NP               = 485
 	SYS_GUARDED_PWRITE_NP              = 486
 	SYS_GUARDED_WRITEV_NP              = 487
-	SYS_RENAME_EXT                     = 488
+	SYS_RENAMEATX_NP                   = 488
 	SYS_MREMAP_ENCRYPTED               = 489
-	SYS_MAXSYSCALL                     = 490
+	SYS_NETAGENT_TRIGGER               = 490
+	SYS_STACK_SNAPSHOT_WITH_CONFIG     = 491
+	SYS_MICROSTACKSHOT                 = 492
+	SYS_GRAB_PGO_DATA                  = 493
+	SYS_PERSONA                        = 494
+	SYS_WORK_INTERVAL_CTL              = 499
+	SYS_GETENTROPY                     = 500
+	SYS_NECP_OPEN                      = 501
+	SYS_NECP_CLIENT_ACTION             = 502
+	SYS___NEXUS_OPEN                   = 503
+	SYS___NEXUS_REGISTER               = 504
+	SYS___NEXUS_DEREGISTER             = 505
+	SYS___NEXUS_CREATE                 = 506
+	SYS___NEXUS_DESTROY                = 507
+	SYS___NEXUS_GET_OPT                = 508
+	SYS___NEXUS_SET_OPT                = 509
+	SYS___CHANNEL_OPEN                 = 510
+	SYS___CHANNEL_GET_INFO             = 511
+	SYS___CHANNEL_SYNC                 = 512
+	SYS___CHANNEL_GET_OPT              = 513
+	SYS___CHANNEL_SET_OPT              = 514
+	SYS_ULOCK_WAIT                     = 515
+	SYS_ULOCK_WAKE                     = 516
+	SYS_FCLONEFILEAT                   = 517
+	SYS_FS_SNAPSHOT                    = 518
+	SYS_TERMINATE_WITH_PAYLOAD         = 520
+	SYS_ABORT_WITH_PAYLOAD             = 521
+	SYS_MAXSYSCALL                     = 522
+	SYS_INVALID                        = 63
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
index 262a845..b64a812 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
@@ -1,5 +1,5 @@
 // mksysnum_freebsd.pl
-// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build 386,freebsd
 
@@ -7,345 +7,347 @@
 
 const (
 	// SYS_NOSYS = 0;  // { int nosys(void); } syscall nosys_args int
-	SYS_EXIT                     = 1   // { void sys_exit(int rval); } exit \
-	SYS_FORK                     = 2   // { int fork(void); }
-	SYS_READ                     = 3   // { ssize_t read(int fd, void *buf, \
-	SYS_WRITE                    = 4   // { ssize_t write(int fd, const void *buf, \
-	SYS_OPEN                     = 5   // { int open(char *path, int flags, int mode); }
-	SYS_CLOSE                    = 6   // { int close(int fd); }
-	SYS_WAIT4                    = 7   // { int wait4(int pid, int *status, \
-	SYS_LINK                     = 9   // { int link(char *path, char *link); }
-	SYS_UNLINK                   = 10  // { int unlink(char *path); }
-	SYS_CHDIR                    = 12  // { int chdir(char *path); }
-	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
-	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
-	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
-	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
-	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break \
-	SYS_GETPID                   = 20  // { pid_t getpid(void); }
-	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, \
-	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
-	SYS_SETUID                   = 23  // { int setuid(uid_t uid); }
-	SYS_GETUID                   = 24  // { uid_t getuid(void); }
-	SYS_GETEUID                  = 25  // { uid_t geteuid(void); }
-	SYS_PTRACE                   = 26  // { int ptrace(int req, pid_t pid, \
-	SYS_RECVMSG                  = 27  // { int recvmsg(int s, struct msghdr *msg, \
-	SYS_SENDMSG                  = 28  // { int sendmsg(int s, struct msghdr *msg, \
-	SYS_RECVFROM                 = 29  // { int recvfrom(int s, caddr_t buf, \
-	SYS_ACCEPT                   = 30  // { int accept(int s, \
-	SYS_GETPEERNAME              = 31  // { int getpeername(int fdes, \
-	SYS_GETSOCKNAME              = 32  // { int getsockname(int fdes, \
-	SYS_ACCESS                   = 33  // { int access(char *path, int amode); }
-	SYS_CHFLAGS                  = 34  // { int chflags(const char *path, u_long flags); }
-	SYS_FCHFLAGS                 = 35  // { int fchflags(int fd, u_long flags); }
-	SYS_SYNC                     = 36  // { int sync(void); }
-	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
-	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
-	SYS_DUP                      = 41  // { int dup(u_int fd); }
-	SYS_PIPE                     = 42  // { int pipe(void); }
-	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
-	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, \
-	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, \
-	SYS_GETGID                   = 47  // { gid_t getgid(void); }
-	SYS_GETLOGIN                 = 49  // { int getlogin(char *namebuf, u_int \
-	SYS_SETLOGIN                 = 50  // { int setlogin(char *namebuf); }
-	SYS_ACCT                     = 51  // { int acct(char *path); }
-	SYS_SIGALTSTACK              = 53  // { int sigaltstack(stack_t *ss, \
-	SYS_IOCTL                    = 54  // { int ioctl(int fd, u_long com, \
-	SYS_REBOOT                   = 55  // { int reboot(int opt); }
-	SYS_REVOKE                   = 56  // { int revoke(char *path); }
-	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
-	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, \
-	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, \
-	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args \
-	SYS_CHROOT                   = 61  // { int chroot(char *path); }
-	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, \
-	SYS_VFORK                    = 66  // { int vfork(void); }
-	SYS_SBRK                     = 69  // { int sbrk(int incr); }
-	SYS_SSTK                     = 70  // { int sstk(int incr); }
-	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise \
-	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
-	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, \
-	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, \
-	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, \
-	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, \
-	SYS_SETGROUPS                = 80  // { int setgroups(u_int gidsetsize, \
-	SYS_GETPGRP                  = 81  // { int getpgrp(void); }
-	SYS_SETPGID                  = 82  // { int setpgid(int pid, int pgid); }
-	SYS_SETITIMER                = 83  // { int setitimer(u_int which, struct \
-	SYS_SWAPON                   = 85  // { int swapon(char *name); }
-	SYS_GETITIMER                = 86  // { int getitimer(u_int which, \
-	SYS_GETDTABLESIZE            = 89  // { int getdtablesize(void); }
-	SYS_DUP2                     = 90  // { int dup2(u_int from, u_int to); }
-	SYS_FCNTL                    = 92  // { int fcntl(int fd, int cmd, long arg); }
-	SYS_SELECT                   = 93  // { int select(int nd, fd_set *in, fd_set *ou, \
-	SYS_FSYNC                    = 95  // { int fsync(int fd); }
-	SYS_SETPRIORITY              = 96  // { int setpriority(int which, int who, \
-	SYS_SOCKET                   = 97  // { int socket(int domain, int type, \
-	SYS_CONNECT                  = 98  // { int connect(int s, caddr_t name, \
-	SYS_GETPRIORITY              = 100 // { int getpriority(int which, int who); }
-	SYS_BIND                     = 104 // { int bind(int s, caddr_t name, \
-	SYS_SETSOCKOPT               = 105 // { int setsockopt(int s, int level, int name, \
-	SYS_LISTEN                   = 106 // { int listen(int s, int backlog); }
-	SYS_GETTIMEOFDAY             = 116 // { int gettimeofday(struct timeval *tp, \
-	SYS_GETRUSAGE                = 117 // { int getrusage(int who, \
-	SYS_GETSOCKOPT               = 118 // { int getsockopt(int s, int level, int name, \
-	SYS_READV                    = 120 // { int readv(int fd, struct iovec *iovp, \
-	SYS_WRITEV                   = 121 // { int writev(int fd, struct iovec *iovp, \
-	SYS_SETTIMEOFDAY             = 122 // { int settimeofday(struct timeval *tv, \
-	SYS_FCHOWN                   = 123 // { int fchown(int fd, int uid, int gid); }
-	SYS_FCHMOD                   = 124 // { int fchmod(int fd, int mode); }
-	SYS_SETREUID                 = 126 // { int setreuid(int ruid, int euid); }
-	SYS_SETREGID                 = 127 // { int setregid(int rgid, int egid); }
-	SYS_RENAME                   = 128 // { int rename(char *from, char *to); }
-	SYS_FLOCK                    = 131 // { int flock(int fd, int how); }
-	SYS_MKFIFO                   = 132 // { int mkfifo(char *path, int mode); }
-	SYS_SENDTO                   = 133 // { int sendto(int s, caddr_t buf, size_t len, \
-	SYS_SHUTDOWN                 = 134 // { int shutdown(int s, int how); }
-	SYS_SOCKETPAIR               = 135 // { int socketpair(int domain, int type, \
-	SYS_MKDIR                    = 136 // { int mkdir(char *path, int mode); }
-	SYS_RMDIR                    = 137 // { int rmdir(char *path); }
-	SYS_UTIMES                   = 138 // { int utimes(char *path, \
-	SYS_ADJTIME                  = 140 // { int adjtime(struct timeval *delta, \
-	SYS_SETSID                   = 147 // { int setsid(void); }
-	SYS_QUOTACTL                 = 148 // { int quotactl(char *path, int cmd, int uid, \
-	SYS_LGETFH                   = 160 // { int lgetfh(char *fname, \
-	SYS_GETFH                    = 161 // { int getfh(char *fname, \
-	SYS_SYSARCH                  = 165 // { int sysarch(int op, char *parms); }
-	SYS_RTPRIO                   = 166 // { int rtprio(int function, pid_t pid, \
-	SYS_FREEBSD6_PREAD           = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \
-	SYS_FREEBSD6_PWRITE          = 174 // { ssize_t freebsd6_pwrite(int fd, \
-	SYS_SETFIB                   = 175 // { int setfib(int fibnum); }
-	SYS_NTP_ADJTIME              = 176 // { int ntp_adjtime(struct timex *tp); }
-	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
-	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
-	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
-	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
-	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
-	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, \
-	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, \
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, \
-	SYS_FREEBSD6_MMAP            = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
-	SYS_FREEBSD6_LSEEK           = 199 // { off_t freebsd6_lseek(int fd, int pad, \
-	SYS_FREEBSD6_TRUNCATE        = 200 // { int freebsd6_truncate(char *path, int pad, \
-	SYS_FREEBSD6_FTRUNCATE       = 201 // { int freebsd6_ftruncate(int fd, int pad, \
-	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, \
-	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
-	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
-	SYS_UNDELETE                 = 205 // { int undelete(char *path); }
-	SYS_FUTIMES                  = 206 // { int futimes(int fd, struct timeval *tptr); }
-	SYS_GETPGID                  = 207 // { int getpgid(pid_t pid); }
-	SYS_POLL                     = 209 // { int poll(struct pollfd *fds, u_int nfds, \
-	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, \
-	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( \
-	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, \
-	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, \
-	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
-	SYS_KTIMER_SETTIME           = 237 // { int ktimer_settime(int timerid, int flags, \
-	SYS_KTIMER_GETTIME           = 238 // { int ktimer_gettime(int timerid, struct \
-	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
-	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, \
-	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
-	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( \
-	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( \
-	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,\
-	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
-	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, \
-	SYS_RFORK                    = 251 // { int rfork(int flags); }
-	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, \
-	SYS_ISSETUGID                = 253 // { int issetugid(void); }
-	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
-	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, \
-	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
-	SYS_LUTIMES                  = 276 // { int lutimes(char *path, \
-	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
-	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
-	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
-	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \
-	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \
-	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, \
-	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, \
-	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
-	SYS_MODSTAT                  = 301 // { int modstat(int modid, \
-	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
-	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
-	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
-	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
-	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
-	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
-	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct \
-	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
-	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
-	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, \
-	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, \
-	SYS_YIELD                    = 321 // { int yield(void); }
-	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
-	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
-	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
-	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, \
-	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct \
-	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int \
-	SYS_SCHED_GETSCHEDULER       = 330 // { int sched_getscheduler (pid_t pid); }
-	SYS_SCHED_YIELD              = 331 // { int sched_yield (void); }
-	SYS_SCHED_GET_PRIORITY_MAX   = 332 // { int sched_get_priority_max (int policy); }
-	SYS_SCHED_GET_PRIORITY_MIN   = 333 // { int sched_get_priority_min (int policy); }
-	SYS_SCHED_RR_GET_INTERVAL    = 334 // { int sched_rr_get_interval (pid_t pid, \
-	SYS_UTRACE                   = 335 // { int utrace(const void *addr, size_t len); }
-	SYS_KLDSYM                   = 337 // { int kldsym(int fileid, int cmd, \
-	SYS_JAIL                     = 338 // { int jail(struct jail *jail); }
-	SYS_SIGPROCMASK              = 340 // { int sigprocmask(int how, \
-	SYS_SIGSUSPEND               = 341 // { int sigsuspend(const sigset_t *sigmask); }
-	SYS_SIGPENDING               = 343 // { int sigpending(sigset_t *set); }
-	SYS_SIGTIMEDWAIT             = 345 // { int sigtimedwait(const sigset_t *set, \
-	SYS_SIGWAITINFO              = 346 // { int sigwaitinfo(const sigset_t *set, \
-	SYS___ACL_GET_FILE           = 347 // { int __acl_get_file(const char *path, \
-	SYS___ACL_SET_FILE           = 348 // { int __acl_set_file(const char *path, \
-	SYS___ACL_GET_FD             = 349 // { int __acl_get_fd(int filedes, \
-	SYS___ACL_SET_FD             = 350 // { int __acl_set_fd(int filedes, \
-	SYS___ACL_DELETE_FILE        = 351 // { int __acl_delete_file(const char *path, \
-	SYS___ACL_DELETE_FD          = 352 // { int __acl_delete_fd(int filedes, \
-	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, \
-	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, \
-	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, \
-	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( \
-	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( \
-	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, \
-	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \
-	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \
-	SYS_KQUEUE                   = 362 // { int kqueue(void); }
-	SYS_KEVENT                   = 363 // { int kevent(int fd, \
-	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, \
-	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, \
-	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, \
-	SYS___SETUGID                = 374 // { int __setugid(int flag); }
-	SYS_EACCESS                  = 376 // { int eaccess(char *path, int amode); }
-	SYS_NMOUNT                   = 378 // { int nmount(struct iovec *iovp, \
-	SYS___MAC_GET_PROC           = 384 // { int __mac_get_proc(struct mac *mac_p); }
-	SYS___MAC_SET_PROC           = 385 // { int __mac_set_proc(struct mac *mac_p); }
-	SYS___MAC_GET_FD             = 386 // { int __mac_get_fd(int fd, \
-	SYS___MAC_GET_FILE           = 387 // { int __mac_get_file(const char *path_p, \
-	SYS___MAC_SET_FD             = 388 // { int __mac_set_fd(int fd, \
-	SYS___MAC_SET_FILE           = 389 // { int __mac_set_file(const char *path_p, \
-	SYS_KENV                     = 390 // { int kenv(int what, const char *name, \
-	SYS_LCHFLAGS                 = 391 // { int lchflags(const char *path, \
-	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, \
-	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, \
-	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, \
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, \
-	SYS_STATFS                   = 396 // { int statfs(char *path, \
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
-	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
-	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, \
-	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, \
-	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, \
-	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( \
-	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( \
-	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( \
-	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, \
-	SYS_SIGACTION                = 416 // { int sigaction(int sig, \
-	SYS_SIGRETURN                = 417 // { int sigreturn( \
-	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
-	SYS_SETCONTEXT               = 422 // { int setcontext( \
-	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, \
-	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
-	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, \
-	SYS___ACL_SET_LINK           = 426 // { int __acl_set_link(const char *path, \
-	SYS___ACL_DELETE_LINK        = 427 // { int __acl_delete_link(const char *path, \
-	SYS___ACL_ACLCHECK_LINK      = 428 // { int __acl_aclcheck_link(const char *path, \
-	SYS_SIGWAIT                  = 429 // { int sigwait(const sigset_t *set, \
-	SYS_THR_CREATE               = 430 // { int thr_create(ucontext_t *ctx, long *id, \
-	SYS_THR_EXIT                 = 431 // { void thr_exit(long *state); }
-	SYS_THR_SELF                 = 432 // { int thr_self(long *id); }
-	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
-	SYS__UMTX_LOCK               = 434 // { int _umtx_lock(struct umtx *umtx); }
-	SYS__UMTX_UNLOCK             = 435 // { int _umtx_unlock(struct umtx *umtx); }
-	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
-	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, \
-	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( \
-	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( \
-	SYS_THR_SUSPEND              = 442 // { int thr_suspend( \
-	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
-	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
-	SYS_AUDIT                    = 445 // { int audit(const void *record, \
-	SYS_AUDITON                  = 446 // { int auditon(int cmd, void *data, \
-	SYS_GETAUID                  = 447 // { int getauid(uid_t *auid); }
-	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
-	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
-	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
-	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( \
-	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( \
-	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
-	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, \
-	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, \
-	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
-	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
-	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
-	SYS_RTPRIO_THREAD            = 466 // { int rtprio_thread(int function, \
-	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
-	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
-	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
-	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
-	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, \
-	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, \
-	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, \
-	SYS_LSEEK                    = 478 // { off_t lseek(int fd, off_t offset, \
-	SYS_TRUNCATE                 = 479 // { int truncate(char *path, off_t length); }
-	SYS_FTRUNCATE                = 480 // { int ftruncate(int fd, off_t length); }
-	SYS_THR_KILL2                = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
-	SYS_SHM_OPEN                 = 482 // { int shm_open(const char *path, int flags, \
-	SYS_SHM_UNLINK               = 483 // { int shm_unlink(const char *path); }
-	SYS_CPUSET                   = 484 // { int cpuset(cpusetid_t *setid); }
-	SYS_CPUSET_SETID             = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \
-	SYS_CPUSET_GETID             = 486 // { int cpuset_getid(cpulevel_t level, \
-	SYS_CPUSET_GETAFFINITY       = 487 // { int cpuset_getaffinity(cpulevel_t level, \
-	SYS_CPUSET_SETAFFINITY       = 488 // { int cpuset_setaffinity(cpulevel_t level, \
-	SYS_FACCESSAT                = 489 // { int faccessat(int fd, char *path, int amode, \
-	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
-	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, \
-	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, \
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, \
-	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, \
-	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, \
-	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
-	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, \
-	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, \
-	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, \
-	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, \
-	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, \
-	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
-	SYS_POSIX_OPENPT             = 504 // { int posix_openpt(int flags); }
-	SYS_JAIL_GET                 = 506 // { int jail_get(struct iovec *iovp, \
-	SYS_JAIL_SET                 = 507 // { int jail_set(struct iovec *iovp, \
-	SYS_JAIL_REMOVE              = 508 // { int jail_remove(int jid); }
-	SYS_CLOSEFROM                = 509 // { int closefrom(int lowfd); }
-	SYS_LPATHCONF                = 513 // { int lpathconf(char *path, int name); }
-	SYS_CAP_NEW                  = 514 // { int cap_new(int fd, uint64_t rights); }
-	SYS_CAP_GETRIGHTS            = 515 // { int cap_getrights(int fd, \
-	SYS_CAP_ENTER                = 516 // { int cap_enter(void); }
-	SYS_CAP_GETMODE              = 517 // { int cap_getmode(u_int *modep); }
-	SYS_PDFORK                   = 518 // { int pdfork(int *fdp, int flags); }
-	SYS_PDKILL                   = 519 // { int pdkill(int fd, int signum); }
-	SYS_PDGETPID                 = 520 // { int pdgetpid(int fd, pid_t *pidp); }
-	SYS_PSELECT                  = 522 // { int pselect(int nd, fd_set *in, \
-	SYS_GETLOGINCLASS            = 523 // { int getloginclass(char *namebuf, \
-	SYS_SETLOGINCLASS            = 524 // { int setloginclass(const char *namebuf); }
-	SYS_RCTL_GET_RACCT           = 525 // { int rctl_get_racct(const void *inbufp, \
-	SYS_RCTL_GET_RULES           = 526 // { int rctl_get_rules(const void *inbufp, \
-	SYS_RCTL_GET_LIMITS          = 527 // { int rctl_get_limits(const void *inbufp, \
-	SYS_RCTL_ADD_RULE            = 528 // { int rctl_add_rule(const void *inbufp, \
-	SYS_RCTL_REMOVE_RULE         = 529 // { int rctl_remove_rule(const void *inbufp, \
-	SYS_POSIX_FALLOCATE          = 530 // { int posix_fallocate(int fd, \
-	SYS_POSIX_FADVISE            = 531 // { int posix_fadvise(int fd, off_t offset, \
-	SYS_WAIT6                    = 532 // { int wait6(idtype_t idtype, id_t id, \
-	SYS_BINDAT                   = 538 // { int bindat(int fd, int s, caddr_t name, \
-	SYS_CONNECTAT                = 539 // { int connectat(int fd, int s, caddr_t name, \
-	SYS_CHFLAGSAT                = 540 // { int chflagsat(int fd, const char *path, \
-	SYS_ACCEPT4                  = 541 // { int accept4(int s, \
-	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
-	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
-	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \
+	SYS_EXIT                   = 1   // { void sys_exit(int rval); } exit \
+	SYS_FORK                   = 2   // { int fork(void); }
+	SYS_READ                   = 3   // { ssize_t read(int fd, void *buf, \
+	SYS_WRITE                  = 4   // { ssize_t write(int fd, const void *buf, \
+	SYS_OPEN                   = 5   // { int open(char *path, int flags, int mode); }
+	SYS_CLOSE                  = 6   // { int close(int fd); }
+	SYS_WAIT4                  = 7   // { int wait4(int pid, int *status, \
+	SYS_LINK                   = 9   // { int link(char *path, char *link); }
+	SYS_UNLINK                 = 10  // { int unlink(char *path); }
+	SYS_CHDIR                  = 12  // { int chdir(char *path); }
+	SYS_FCHDIR                 = 13  // { int fchdir(int fd); }
+	SYS_MKNOD                  = 14  // { int mknod(char *path, int mode, int dev); }
+	SYS_CHMOD                  = 15  // { int chmod(char *path, int mode); }
+	SYS_CHOWN                  = 16  // { int chown(char *path, int uid, int gid); }
+	SYS_OBREAK                 = 17  // { int obreak(char *nsize); } break \
+	SYS_GETPID                 = 20  // { pid_t getpid(void); }
+	SYS_MOUNT                  = 21  // { int mount(char *type, char *path, \
+	SYS_UNMOUNT                = 22  // { int unmount(char *path, int flags); }
+	SYS_SETUID                 = 23  // { int setuid(uid_t uid); }
+	SYS_GETUID                 = 24  // { uid_t getuid(void); }
+	SYS_GETEUID                = 25  // { uid_t geteuid(void); }
+	SYS_PTRACE                 = 26  // { int ptrace(int req, pid_t pid, \
+	SYS_RECVMSG                = 27  // { int recvmsg(int s, struct msghdr *msg, \
+	SYS_SENDMSG                = 28  // { int sendmsg(int s, struct msghdr *msg, \
+	SYS_RECVFROM               = 29  // { int recvfrom(int s, caddr_t buf, \
+	SYS_ACCEPT                 = 30  // { int accept(int s, \
+	SYS_GETPEERNAME            = 31  // { int getpeername(int fdes, \
+	SYS_GETSOCKNAME            = 32  // { int getsockname(int fdes, \
+	SYS_ACCESS                 = 33  // { int access(char *path, int amode); }
+	SYS_CHFLAGS                = 34  // { int chflags(const char *path, u_long flags); }
+	SYS_FCHFLAGS               = 35  // { int fchflags(int fd, u_long flags); }
+	SYS_SYNC                   = 36  // { int sync(void); }
+	SYS_KILL                   = 37  // { int kill(int pid, int signum); }
+	SYS_GETPPID                = 39  // { pid_t getppid(void); }
+	SYS_DUP                    = 41  // { int dup(u_int fd); }
+	SYS_PIPE                   = 42  // { int pipe(void); }
+	SYS_GETEGID                = 43  // { gid_t getegid(void); }
+	SYS_PROFIL                 = 44  // { int profil(caddr_t samples, size_t size, \
+	SYS_KTRACE                 = 45  // { int ktrace(const char *fname, int ops, \
+	SYS_GETGID                 = 47  // { gid_t getgid(void); }
+	SYS_GETLOGIN               = 49  // { int getlogin(char *namebuf, u_int \
+	SYS_SETLOGIN               = 50  // { int setlogin(char *namebuf); }
+	SYS_ACCT                   = 51  // { int acct(char *path); }
+	SYS_SIGALTSTACK            = 53  // { int sigaltstack(stack_t *ss, \
+	SYS_IOCTL                  = 54  // { int ioctl(int fd, u_long com, \
+	SYS_REBOOT                 = 55  // { int reboot(int opt); }
+	SYS_REVOKE                 = 56  // { int revoke(char *path); }
+	SYS_SYMLINK                = 57  // { int symlink(char *path, char *link); }
+	SYS_READLINK               = 58  // { ssize_t readlink(char *path, char *buf, \
+	SYS_EXECVE                 = 59  // { int execve(char *fname, char **argv, \
+	SYS_UMASK                  = 60  // { int umask(int newmask); } umask umask_args \
+	SYS_CHROOT                 = 61  // { int chroot(char *path); }
+	SYS_MSYNC                  = 65  // { int msync(void *addr, size_t len, \
+	SYS_VFORK                  = 66  // { int vfork(void); }
+	SYS_SBRK                   = 69  // { int sbrk(int incr); }
+	SYS_SSTK                   = 70  // { int sstk(int incr); }
+	SYS_OVADVISE               = 72  // { int ovadvise(int anom); } vadvise \
+	SYS_MUNMAP                 = 73  // { int munmap(void *addr, size_t len); }
+	SYS_MPROTECT               = 74  // { int mprotect(const void *addr, size_t len, \
+	SYS_MADVISE                = 75  // { int madvise(void *addr, size_t len, \
+	SYS_MINCORE                = 78  // { int mincore(const void *addr, size_t len, \
+	SYS_GETGROUPS              = 79  // { int getgroups(u_int gidsetsize, \
+	SYS_SETGROUPS              = 80  // { int setgroups(u_int gidsetsize, \
+	SYS_GETPGRP                = 81  // { int getpgrp(void); }
+	SYS_SETPGID                = 82  // { int setpgid(int pid, int pgid); }
+	SYS_SETITIMER              = 83  // { int setitimer(u_int which, struct \
+	SYS_SWAPON                 = 85  // { int swapon(char *name); }
+	SYS_GETITIMER              = 86  // { int getitimer(u_int which, \
+	SYS_GETDTABLESIZE          = 89  // { int getdtablesize(void); }
+	SYS_DUP2                   = 90  // { int dup2(u_int from, u_int to); }
+	SYS_FCNTL                  = 92  // { int fcntl(int fd, int cmd, long arg); }
+	SYS_SELECT                 = 93  // { int select(int nd, fd_set *in, fd_set *ou, \
+	SYS_FSYNC                  = 95  // { int fsync(int fd); }
+	SYS_SETPRIORITY            = 96  // { int setpriority(int which, int who, \
+	SYS_SOCKET                 = 97  // { int socket(int domain, int type, \
+	SYS_CONNECT                = 98  // { int connect(int s, caddr_t name, \
+	SYS_GETPRIORITY            = 100 // { int getpriority(int which, int who); }
+	SYS_BIND                   = 104 // { int bind(int s, caddr_t name, \
+	SYS_SETSOCKOPT             = 105 // { int setsockopt(int s, int level, int name, \
+	SYS_LISTEN                 = 106 // { int listen(int s, int backlog); }
+	SYS_GETTIMEOFDAY           = 116 // { int gettimeofday(struct timeval *tp, \
+	SYS_GETRUSAGE              = 117 // { int getrusage(int who, \
+	SYS_GETSOCKOPT             = 118 // { int getsockopt(int s, int level, int name, \
+	SYS_READV                  = 120 // { int readv(int fd, struct iovec *iovp, \
+	SYS_WRITEV                 = 121 // { int writev(int fd, struct iovec *iovp, \
+	SYS_SETTIMEOFDAY           = 122 // { int settimeofday(struct timeval *tv, \
+	SYS_FCHOWN                 = 123 // { int fchown(int fd, int uid, int gid); }
+	SYS_FCHMOD                 = 124 // { int fchmod(int fd, int mode); }
+	SYS_SETREUID               = 126 // { int setreuid(int ruid, int euid); }
+	SYS_SETREGID               = 127 // { int setregid(int rgid, int egid); }
+	SYS_RENAME                 = 128 // { int rename(char *from, char *to); }
+	SYS_FLOCK                  = 131 // { int flock(int fd, int how); }
+	SYS_MKFIFO                 = 132 // { int mkfifo(char *path, int mode); }
+	SYS_SENDTO                 = 133 // { int sendto(int s, caddr_t buf, size_t len, \
+	SYS_SHUTDOWN               = 134 // { int shutdown(int s, int how); }
+	SYS_SOCKETPAIR             = 135 // { int socketpair(int domain, int type, \
+	SYS_MKDIR                  = 136 // { int mkdir(char *path, int mode); }
+	SYS_RMDIR                  = 137 // { int rmdir(char *path); }
+	SYS_UTIMES                 = 138 // { int utimes(char *path, \
+	SYS_ADJTIME                = 140 // { int adjtime(struct timeval *delta, \
+	SYS_SETSID                 = 147 // { int setsid(void); }
+	SYS_QUOTACTL               = 148 // { int quotactl(char *path, int cmd, int uid, \
+	SYS_LGETFH                 = 160 // { int lgetfh(char *fname, \
+	SYS_GETFH                  = 161 // { int getfh(char *fname, \
+	SYS_SYSARCH                = 165 // { int sysarch(int op, char *parms); }
+	SYS_RTPRIO                 = 166 // { int rtprio(int function, pid_t pid, \
+	SYS_FREEBSD6_PREAD         = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \
+	SYS_FREEBSD6_PWRITE        = 174 // { ssize_t freebsd6_pwrite(int fd, \
+	SYS_SETFIB                 = 175 // { int setfib(int fibnum); }
+	SYS_NTP_ADJTIME            = 176 // { int ntp_adjtime(struct timex *tp); }
+	SYS_SETGID                 = 181 // { int setgid(gid_t gid); }
+	SYS_SETEGID                = 182 // { int setegid(gid_t egid); }
+	SYS_SETEUID                = 183 // { int seteuid(uid_t euid); }
+	SYS_STAT                   = 188 // { int stat(char *path, struct stat *ub); }
+	SYS_FSTAT                  = 189 // { int fstat(int fd, struct stat *sb); }
+	SYS_LSTAT                  = 190 // { int lstat(char *path, struct stat *ub); }
+	SYS_PATHCONF               = 191 // { int pathconf(char *path, int name); }
+	SYS_FPATHCONF              = 192 // { int fpathconf(int fd, int name); }
+	SYS_GETRLIMIT              = 194 // { int getrlimit(u_int which, \
+	SYS_SETRLIMIT              = 195 // { int setrlimit(u_int which, \
+	SYS_GETDIRENTRIES          = 196 // { int getdirentries(int fd, char *buf, \
+	SYS_FREEBSD6_MMAP          = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
+	SYS_FREEBSD6_LSEEK         = 199 // { off_t freebsd6_lseek(int fd, int pad, \
+	SYS_FREEBSD6_TRUNCATE      = 200 // { int freebsd6_truncate(char *path, int pad, \
+	SYS_FREEBSD6_FTRUNCATE     = 201 // { int freebsd6_ftruncate(int fd, int pad, \
+	SYS___SYSCTL               = 202 // { int __sysctl(int *name, u_int namelen, \
+	SYS_MLOCK                  = 203 // { int mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK                = 204 // { int munlock(const void *addr, size_t len); }
+	SYS_UNDELETE               = 205 // { int undelete(char *path); }
+	SYS_FUTIMES                = 206 // { int futimes(int fd, struct timeval *tptr); }
+	SYS_GETPGID                = 207 // { int getpgid(pid_t pid); }
+	SYS_POLL                   = 209 // { int poll(struct pollfd *fds, u_int nfds, \
+	SYS_CLOCK_GETTIME          = 232 // { int clock_gettime(clockid_t clock_id, \
+	SYS_CLOCK_SETTIME          = 233 // { int clock_settime( \
+	SYS_CLOCK_GETRES           = 234 // { int clock_getres(clockid_t clock_id, \
+	SYS_KTIMER_CREATE          = 235 // { int ktimer_create(clockid_t clock_id, \
+	SYS_KTIMER_DELETE          = 236 // { int ktimer_delete(int timerid); }
+	SYS_KTIMER_SETTIME         = 237 // { int ktimer_settime(int timerid, int flags, \
+	SYS_KTIMER_GETTIME         = 238 // { int ktimer_gettime(int timerid, struct \
+	SYS_KTIMER_GETOVERRUN      = 239 // { int ktimer_getoverrun(int timerid); }
+	SYS_NANOSLEEP              = 240 // { int nanosleep(const struct timespec *rqtp, \
+	SYS_FFCLOCK_GETCOUNTER     = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
+	SYS_FFCLOCK_SETESTIMATE    = 242 // { int ffclock_setestimate( \
+	SYS_FFCLOCK_GETESTIMATE    = 243 // { int ffclock_getestimate( \
+	SYS_CLOCK_GETCPUCLOCKID2   = 247 // { int clock_getcpuclockid2(id_t id,\
+	SYS_NTP_GETTIME            = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
+	SYS_MINHERIT               = 250 // { int minherit(void *addr, size_t len, \
+	SYS_RFORK                  = 251 // { int rfork(int flags); }
+	SYS_OPENBSD_POLL           = 252 // { int openbsd_poll(struct pollfd *fds, \
+	SYS_ISSETUGID              = 253 // { int issetugid(void); }
+	SYS_LCHOWN                 = 254 // { int lchown(char *path, int uid, int gid); }
+	SYS_GETDENTS               = 272 // { int getdents(int fd, char *buf, \
+	SYS_LCHMOD                 = 274 // { int lchmod(char *path, mode_t mode); }
+	SYS_LUTIMES                = 276 // { int lutimes(char *path, \
+	SYS_NSTAT                  = 278 // { int nstat(char *path, struct nstat *ub); }
+	SYS_NFSTAT                 = 279 // { int nfstat(int fd, struct nstat *sb); }
+	SYS_NLSTAT                 = 280 // { int nlstat(char *path, struct nstat *ub); }
+	SYS_PREADV                 = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \
+	SYS_PWRITEV                = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \
+	SYS_FHOPEN                 = 298 // { int fhopen(const struct fhandle *u_fhp, \
+	SYS_FHSTAT                 = 299 // { int fhstat(const struct fhandle *u_fhp, \
+	SYS_MODNEXT                = 300 // { int modnext(int modid); }
+	SYS_MODSTAT                = 301 // { int modstat(int modid, \
+	SYS_MODFNEXT               = 302 // { int modfnext(int modid); }
+	SYS_MODFIND                = 303 // { int modfind(const char *name); }
+	SYS_KLDLOAD                = 304 // { int kldload(const char *file); }
+	SYS_KLDUNLOAD              = 305 // { int kldunload(int fileid); }
+	SYS_KLDFIND                = 306 // { int kldfind(const char *file); }
+	SYS_KLDNEXT                = 307 // { int kldnext(int fileid); }
+	SYS_KLDSTAT                = 308 // { int kldstat(int fileid, struct \
+	SYS_KLDFIRSTMOD            = 309 // { int kldfirstmod(int fileid); }
+	SYS_GETSID                 = 310 // { int getsid(pid_t pid); }
+	SYS_SETRESUID              = 311 // { int setresuid(uid_t ruid, uid_t euid, \
+	SYS_SETRESGID              = 312 // { int setresgid(gid_t rgid, gid_t egid, \
+	SYS_YIELD                  = 321 // { int yield(void); }
+	SYS_MLOCKALL               = 324 // { int mlockall(int how); }
+	SYS_MUNLOCKALL             = 325 // { int munlockall(void); }
+	SYS___GETCWD               = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS_SCHED_SETPARAM         = 327 // { int sched_setparam (pid_t pid, \
+	SYS_SCHED_GETPARAM         = 328 // { int sched_getparam (pid_t pid, struct \
+	SYS_SCHED_SETSCHEDULER     = 329 // { int sched_setscheduler (pid_t pid, int \
+	SYS_SCHED_GETSCHEDULER     = 330 // { int sched_getscheduler (pid_t pid); }
+	SYS_SCHED_YIELD            = 331 // { int sched_yield (void); }
+	SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); }
+	SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); }
+	SYS_SCHED_RR_GET_INTERVAL  = 334 // { int sched_rr_get_interval (pid_t pid, \
+	SYS_UTRACE                 = 335 // { int utrace(const void *addr, size_t len); }
+	SYS_KLDSYM                 = 337 // { int kldsym(int fileid, int cmd, \
+	SYS_JAIL                   = 338 // { int jail(struct jail *jail); }
+	SYS_SIGPROCMASK            = 340 // { int sigprocmask(int how, \
+	SYS_SIGSUSPEND             = 341 // { int sigsuspend(const sigset_t *sigmask); }
+	SYS_SIGPENDING             = 343 // { int sigpending(sigset_t *set); }
+	SYS_SIGTIMEDWAIT           = 345 // { int sigtimedwait(const sigset_t *set, \
+	SYS_SIGWAITINFO            = 346 // { int sigwaitinfo(const sigset_t *set, \
+	SYS___ACL_GET_FILE         = 347 // { int __acl_get_file(const char *path, \
+	SYS___ACL_SET_FILE         = 348 // { int __acl_set_file(const char *path, \
+	SYS___ACL_GET_FD           = 349 // { int __acl_get_fd(int filedes, \
+	SYS___ACL_SET_FD           = 350 // { int __acl_set_fd(int filedes, \
+	SYS___ACL_DELETE_FILE      = 351 // { int __acl_delete_file(const char *path, \
+	SYS___ACL_DELETE_FD        = 352 // { int __acl_delete_fd(int filedes, \
+	SYS___ACL_ACLCHECK_FILE    = 353 // { int __acl_aclcheck_file(const char *path, \
+	SYS___ACL_ACLCHECK_FD      = 354 // { int __acl_aclcheck_fd(int filedes, \
+	SYS_EXTATTRCTL             = 355 // { int extattrctl(const char *path, int cmd, \
+	SYS_EXTATTR_SET_FILE       = 356 // { ssize_t extattr_set_file( \
+	SYS_EXTATTR_GET_FILE       = 357 // { ssize_t extattr_get_file( \
+	SYS_EXTATTR_DELETE_FILE    = 358 // { int extattr_delete_file(const char *path, \
+	SYS_GETRESUID              = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \
+	SYS_GETRESGID              = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \
+	SYS_KQUEUE                 = 362 // { int kqueue(void); }
+	SYS_KEVENT                 = 363 // { int kevent(int fd, \
+	SYS_EXTATTR_SET_FD         = 371 // { ssize_t extattr_set_fd(int fd, \
+	SYS_EXTATTR_GET_FD         = 372 // { ssize_t extattr_get_fd(int fd, \
+	SYS_EXTATTR_DELETE_FD      = 373 // { int extattr_delete_fd(int fd, \
+	SYS___SETUGID              = 374 // { int __setugid(int flag); }
+	SYS_EACCESS                = 376 // { int eaccess(char *path, int amode); }
+	SYS_NMOUNT                 = 378 // { int nmount(struct iovec *iovp, \
+	SYS___MAC_GET_PROC         = 384 // { int __mac_get_proc(struct mac *mac_p); }
+	SYS___MAC_SET_PROC         = 385 // { int __mac_set_proc(struct mac *mac_p); }
+	SYS___MAC_GET_FD           = 386 // { int __mac_get_fd(int fd, \
+	SYS___MAC_GET_FILE         = 387 // { int __mac_get_file(const char *path_p, \
+	SYS___MAC_SET_FD           = 388 // { int __mac_set_fd(int fd, \
+	SYS___MAC_SET_FILE         = 389 // { int __mac_set_file(const char *path_p, \
+	SYS_KENV                   = 390 // { int kenv(int what, const char *name, \
+	SYS_LCHFLAGS               = 391 // { int lchflags(const char *path, \
+	SYS_UUIDGEN                = 392 // { int uuidgen(struct uuid *store, \
+	SYS_SENDFILE               = 393 // { int sendfile(int fd, int s, off_t offset, \
+	SYS_MAC_SYSCALL            = 394 // { int mac_syscall(const char *policy, \
+	SYS_GETFSSTAT              = 395 // { int getfsstat(struct statfs *buf, \
+	SYS_STATFS                 = 396 // { int statfs(char *path, \
+	SYS_FSTATFS                = 397 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_FHSTATFS               = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
+	SYS___MAC_GET_PID          = 409 // { int __mac_get_pid(pid_t pid, \
+	SYS___MAC_GET_LINK         = 410 // { int __mac_get_link(const char *path_p, \
+	SYS___MAC_SET_LINK         = 411 // { int __mac_set_link(const char *path_p, \
+	SYS_EXTATTR_SET_LINK       = 412 // { ssize_t extattr_set_link( \
+	SYS_EXTATTR_GET_LINK       = 413 // { ssize_t extattr_get_link( \
+	SYS_EXTATTR_DELETE_LINK    = 414 // { int extattr_delete_link( \
+	SYS___MAC_EXECVE           = 415 // { int __mac_execve(char *fname, char **argv, \
+	SYS_SIGACTION              = 416 // { int sigaction(int sig, \
+	SYS_SIGRETURN              = 417 // { int sigreturn( \
+	SYS_GETCONTEXT             = 421 // { int getcontext(struct __ucontext *ucp); }
+	SYS_SETCONTEXT             = 422 // { int setcontext( \
+	SYS_SWAPCONTEXT            = 423 // { int swapcontext(struct __ucontext *oucp, \
+	SYS_SWAPOFF                = 424 // { int swapoff(const char *name); }
+	SYS___ACL_GET_LINK         = 425 // { int __acl_get_link(const char *path, \
+	SYS___ACL_SET_LINK         = 426 // { int __acl_set_link(const char *path, \
+	SYS___ACL_DELETE_LINK      = 427 // { int __acl_delete_link(const char *path, \
+	SYS___ACL_ACLCHECK_LINK    = 428 // { int __acl_aclcheck_link(const char *path, \
+	SYS_SIGWAIT                = 429 // { int sigwait(const sigset_t *set, \
+	SYS_THR_CREATE             = 430 // { int thr_create(ucontext_t *ctx, long *id, \
+	SYS_THR_EXIT               = 431 // { void thr_exit(long *state); }
+	SYS_THR_SELF               = 432 // { int thr_self(long *id); }
+	SYS_THR_KILL               = 433 // { int thr_kill(long id, int sig); }
+	SYS__UMTX_LOCK             = 434 // { int _umtx_lock(struct umtx *umtx); }
+	SYS__UMTX_UNLOCK           = 435 // { int _umtx_unlock(struct umtx *umtx); }
+	SYS_JAIL_ATTACH            = 436 // { int jail_attach(int jid); }
+	SYS_EXTATTR_LIST_FD        = 437 // { ssize_t extattr_list_fd(int fd, \
+	SYS_EXTATTR_LIST_FILE      = 438 // { ssize_t extattr_list_file( \
+	SYS_EXTATTR_LIST_LINK      = 439 // { ssize_t extattr_list_link( \
+	SYS_THR_SUSPEND            = 442 // { int thr_suspend( \
+	SYS_THR_WAKE               = 443 // { int thr_wake(long id); }
+	SYS_KLDUNLOADF             = 444 // { int kldunloadf(int fileid, int flags); }
+	SYS_AUDIT                  = 445 // { int audit(const void *record, \
+	SYS_AUDITON                = 446 // { int auditon(int cmd, void *data, \
+	SYS_GETAUID                = 447 // { int getauid(uid_t *auid); }
+	SYS_SETAUID                = 448 // { int setauid(uid_t *auid); }
+	SYS_GETAUDIT               = 449 // { int getaudit(struct auditinfo *auditinfo); }
+	SYS_SETAUDIT               = 450 // { int setaudit(struct auditinfo *auditinfo); }
+	SYS_GETAUDIT_ADDR          = 451 // { int getaudit_addr( \
+	SYS_SETAUDIT_ADDR          = 452 // { int setaudit_addr( \
+	SYS_AUDITCTL               = 453 // { int auditctl(char *path); }
+	SYS__UMTX_OP               = 454 // { int _umtx_op(void *obj, int op, \
+	SYS_THR_NEW                = 455 // { int thr_new(struct thr_param *param, \
+	SYS_SIGQUEUE               = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
+	SYS_ABORT2                 = 463 // { int abort2(const char *why, int nargs, void **args); }
+	SYS_THR_SET_NAME           = 464 // { int thr_set_name(long id, const char *name); }
+	SYS_RTPRIO_THREAD          = 466 // { int rtprio_thread(int function, \
+	SYS_PREAD                  = 475 // { ssize_t pread(int fd, void *buf, \
+	SYS_PWRITE                 = 476 // { ssize_t pwrite(int fd, const void *buf, \
+	SYS_MMAP                   = 477 // { caddr_t mmap(caddr_t addr, size_t len, \
+	SYS_LSEEK                  = 478 // { off_t lseek(int fd, off_t offset, \
+	SYS_TRUNCATE               = 479 // { int truncate(char *path, off_t length); }
+	SYS_FTRUNCATE              = 480 // { int ftruncate(int fd, off_t length); }
+	SYS_THR_KILL2              = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
+	SYS_SHM_OPEN               = 482 // { int shm_open(const char *path, int flags, \
+	SYS_SHM_UNLINK             = 483 // { int shm_unlink(const char *path); }
+	SYS_CPUSET                 = 484 // { int cpuset(cpusetid_t *setid); }
+	SYS_CPUSET_SETID           = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \
+	SYS_CPUSET_GETID           = 486 // { int cpuset_getid(cpulevel_t level, \
+	SYS_CPUSET_GETAFFINITY     = 487 // { int cpuset_getaffinity(cpulevel_t level, \
+	SYS_CPUSET_SETAFFINITY     = 488 // { int cpuset_setaffinity(cpulevel_t level, \
+	SYS_FACCESSAT              = 489 // { int faccessat(int fd, char *path, int amode, \
+	SYS_FCHMODAT               = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
+	SYS_FCHOWNAT               = 491 // { int fchownat(int fd, char *path, uid_t uid, \
+	SYS_FEXECVE                = 492 // { int fexecve(int fd, char **argv, \
+	SYS_FSTATAT                = 493 // { int fstatat(int fd, char *path, \
+	SYS_FUTIMESAT              = 494 // { int futimesat(int fd, char *path, \
+	SYS_LINKAT                 = 495 // { int linkat(int fd1, char *path1, int fd2, \
+	SYS_MKDIRAT                = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
+	SYS_MKFIFOAT               = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
+	SYS_MKNODAT                = 498 // { int mknodat(int fd, char *path, mode_t mode, \
+	SYS_OPENAT                 = 499 // { int openat(int fd, char *path, int flag, \
+	SYS_READLINKAT             = 500 // { int readlinkat(int fd, char *path, char *buf, \
+	SYS_RENAMEAT               = 501 // { int renameat(int oldfd, char *old, int newfd, \
+	SYS_SYMLINKAT              = 502 // { int symlinkat(char *path1, int fd, \
+	SYS_UNLINKAT               = 503 // { int unlinkat(int fd, char *path, int flag); }
+	SYS_POSIX_OPENPT           = 504 // { int posix_openpt(int flags); }
+	SYS_JAIL_GET               = 506 // { int jail_get(struct iovec *iovp, \
+	SYS_JAIL_SET               = 507 // { int jail_set(struct iovec *iovp, \
+	SYS_JAIL_REMOVE            = 508 // { int jail_remove(int jid); }
+	SYS_CLOSEFROM              = 509 // { int closefrom(int lowfd); }
+	SYS_LPATHCONF              = 513 // { int lpathconf(char *path, int name); }
+	SYS___CAP_RIGHTS_GET       = 515 // { int __cap_rights_get(int version, \
+	SYS_CAP_ENTER              = 516 // { int cap_enter(void); }
+	SYS_CAP_GETMODE            = 517 // { int cap_getmode(u_int *modep); }
+	SYS_PDFORK                 = 518 // { int pdfork(int *fdp, int flags); }
+	SYS_PDKILL                 = 519 // { int pdkill(int fd, int signum); }
+	SYS_PDGETPID               = 520 // { int pdgetpid(int fd, pid_t *pidp); }
+	SYS_PSELECT                = 522 // { int pselect(int nd, fd_set *in, \
+	SYS_GETLOGINCLASS          = 523 // { int getloginclass(char *namebuf, \
+	SYS_SETLOGINCLASS          = 524 // { int setloginclass(const char *namebuf); }
+	SYS_RCTL_GET_RACCT         = 525 // { int rctl_get_racct(const void *inbufp, \
+	SYS_RCTL_GET_RULES         = 526 // { int rctl_get_rules(const void *inbufp, \
+	SYS_RCTL_GET_LIMITS        = 527 // { int rctl_get_limits(const void *inbufp, \
+	SYS_RCTL_ADD_RULE          = 528 // { int rctl_add_rule(const void *inbufp, \
+	SYS_RCTL_REMOVE_RULE       = 529 // { int rctl_remove_rule(const void *inbufp, \
+	SYS_POSIX_FALLOCATE        = 530 // { int posix_fallocate(int fd, \
+	SYS_POSIX_FADVISE          = 531 // { int posix_fadvise(int fd, off_t offset, \
+	SYS_WAIT6                  = 532 // { int wait6(idtype_t idtype, id_t id, \
+	SYS_CAP_RIGHTS_LIMIT       = 533 // { int cap_rights_limit(int fd, \
+	SYS_CAP_IOCTLS_LIMIT       = 534 // { int cap_ioctls_limit(int fd, \
+	SYS_CAP_IOCTLS_GET         = 535 // { ssize_t cap_ioctls_get(int fd, \
+	SYS_CAP_FCNTLS_LIMIT       = 536 // { int cap_fcntls_limit(int fd, \
+	SYS_CAP_FCNTLS_GET         = 537 // { int cap_fcntls_get(int fd, \
+	SYS_BINDAT                 = 538 // { int bindat(int fd, int s, caddr_t name, \
+	SYS_CONNECTAT              = 539 // { int connectat(int fd, int s, caddr_t name, \
+	SYS_CHFLAGSAT              = 540 // { int chflagsat(int fd, const char *path, \
+	SYS_ACCEPT4                = 541 // { int accept4(int s, \
+	SYS_PIPE2                  = 542 // { int pipe2(int *fildes, int flags); }
+	SYS_PROCCTL                = 544 // { int procctl(idtype_t idtype, id_t id, \
+	SYS_PPOLL                  = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \
+	SYS_FUTIMENS               = 546 // { int futimens(int fd, \
+	SYS_UTIMENSAT              = 547 // { int utimensat(int fd, \
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
index 57a60ea..81722ac 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
@@ -1,5 +1,5 @@
 // mksysnum_freebsd.pl
-// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build amd64,freebsd
 
@@ -7,345 +7,347 @@
 
 const (
 	// SYS_NOSYS = 0;  // { int nosys(void); } syscall nosys_args int
-	SYS_EXIT                     = 1   // { void sys_exit(int rval); } exit \
-	SYS_FORK                     = 2   // { int fork(void); }
-	SYS_READ                     = 3   // { ssize_t read(int fd, void *buf, \
-	SYS_WRITE                    = 4   // { ssize_t write(int fd, const void *buf, \
-	SYS_OPEN                     = 5   // { int open(char *path, int flags, int mode); }
-	SYS_CLOSE                    = 6   // { int close(int fd); }
-	SYS_WAIT4                    = 7   // { int wait4(int pid, int *status, \
-	SYS_LINK                     = 9   // { int link(char *path, char *link); }
-	SYS_UNLINK                   = 10  // { int unlink(char *path); }
-	SYS_CHDIR                    = 12  // { int chdir(char *path); }
-	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
-	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
-	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
-	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
-	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break \
-	SYS_GETPID                   = 20  // { pid_t getpid(void); }
-	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, \
-	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
-	SYS_SETUID                   = 23  // { int setuid(uid_t uid); }
-	SYS_GETUID                   = 24  // { uid_t getuid(void); }
-	SYS_GETEUID                  = 25  // { uid_t geteuid(void); }
-	SYS_PTRACE                   = 26  // { int ptrace(int req, pid_t pid, \
-	SYS_RECVMSG                  = 27  // { int recvmsg(int s, struct msghdr *msg, \
-	SYS_SENDMSG                  = 28  // { int sendmsg(int s, struct msghdr *msg, \
-	SYS_RECVFROM                 = 29  // { int recvfrom(int s, caddr_t buf, \
-	SYS_ACCEPT                   = 30  // { int accept(int s, \
-	SYS_GETPEERNAME              = 31  // { int getpeername(int fdes, \
-	SYS_GETSOCKNAME              = 32  // { int getsockname(int fdes, \
-	SYS_ACCESS                   = 33  // { int access(char *path, int amode); }
-	SYS_CHFLAGS                  = 34  // { int chflags(const char *path, u_long flags); }
-	SYS_FCHFLAGS                 = 35  // { int fchflags(int fd, u_long flags); }
-	SYS_SYNC                     = 36  // { int sync(void); }
-	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
-	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
-	SYS_DUP                      = 41  // { int dup(u_int fd); }
-	SYS_PIPE                     = 42  // { int pipe(void); }
-	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
-	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, \
-	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, \
-	SYS_GETGID                   = 47  // { gid_t getgid(void); }
-	SYS_GETLOGIN                 = 49  // { int getlogin(char *namebuf, u_int \
-	SYS_SETLOGIN                 = 50  // { int setlogin(char *namebuf); }
-	SYS_ACCT                     = 51  // { int acct(char *path); }
-	SYS_SIGALTSTACK              = 53  // { int sigaltstack(stack_t *ss, \
-	SYS_IOCTL                    = 54  // { int ioctl(int fd, u_long com, \
-	SYS_REBOOT                   = 55  // { int reboot(int opt); }
-	SYS_REVOKE                   = 56  // { int revoke(char *path); }
-	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
-	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, \
-	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, \
-	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args \
-	SYS_CHROOT                   = 61  // { int chroot(char *path); }
-	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, \
-	SYS_VFORK                    = 66  // { int vfork(void); }
-	SYS_SBRK                     = 69  // { int sbrk(int incr); }
-	SYS_SSTK                     = 70  // { int sstk(int incr); }
-	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise \
-	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
-	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, \
-	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, \
-	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, \
-	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, \
-	SYS_SETGROUPS                = 80  // { int setgroups(u_int gidsetsize, \
-	SYS_GETPGRP                  = 81  // { int getpgrp(void); }
-	SYS_SETPGID                  = 82  // { int setpgid(int pid, int pgid); }
-	SYS_SETITIMER                = 83  // { int setitimer(u_int which, struct \
-	SYS_SWAPON                   = 85  // { int swapon(char *name); }
-	SYS_GETITIMER                = 86  // { int getitimer(u_int which, \
-	SYS_GETDTABLESIZE            = 89  // { int getdtablesize(void); }
-	SYS_DUP2                     = 90  // { int dup2(u_int from, u_int to); }
-	SYS_FCNTL                    = 92  // { int fcntl(int fd, int cmd, long arg); }
-	SYS_SELECT                   = 93  // { int select(int nd, fd_set *in, fd_set *ou, \
-	SYS_FSYNC                    = 95  // { int fsync(int fd); }
-	SYS_SETPRIORITY              = 96  // { int setpriority(int which, int who, \
-	SYS_SOCKET                   = 97  // { int socket(int domain, int type, \
-	SYS_CONNECT                  = 98  // { int connect(int s, caddr_t name, \
-	SYS_GETPRIORITY              = 100 // { int getpriority(int which, int who); }
-	SYS_BIND                     = 104 // { int bind(int s, caddr_t name, \
-	SYS_SETSOCKOPT               = 105 // { int setsockopt(int s, int level, int name, \
-	SYS_LISTEN                   = 106 // { int listen(int s, int backlog); }
-	SYS_GETTIMEOFDAY             = 116 // { int gettimeofday(struct timeval *tp, \
-	SYS_GETRUSAGE                = 117 // { int getrusage(int who, \
-	SYS_GETSOCKOPT               = 118 // { int getsockopt(int s, int level, int name, \
-	SYS_READV                    = 120 // { int readv(int fd, struct iovec *iovp, \
-	SYS_WRITEV                   = 121 // { int writev(int fd, struct iovec *iovp, \
-	SYS_SETTIMEOFDAY             = 122 // { int settimeofday(struct timeval *tv, \
-	SYS_FCHOWN                   = 123 // { int fchown(int fd, int uid, int gid); }
-	SYS_FCHMOD                   = 124 // { int fchmod(int fd, int mode); }
-	SYS_SETREUID                 = 126 // { int setreuid(int ruid, int euid); }
-	SYS_SETREGID                 = 127 // { int setregid(int rgid, int egid); }
-	SYS_RENAME                   = 128 // { int rename(char *from, char *to); }
-	SYS_FLOCK                    = 131 // { int flock(int fd, int how); }
-	SYS_MKFIFO                   = 132 // { int mkfifo(char *path, int mode); }
-	SYS_SENDTO                   = 133 // { int sendto(int s, caddr_t buf, size_t len, \
-	SYS_SHUTDOWN                 = 134 // { int shutdown(int s, int how); }
-	SYS_SOCKETPAIR               = 135 // { int socketpair(int domain, int type, \
-	SYS_MKDIR                    = 136 // { int mkdir(char *path, int mode); }
-	SYS_RMDIR                    = 137 // { int rmdir(char *path); }
-	SYS_UTIMES                   = 138 // { int utimes(char *path, \
-	SYS_ADJTIME                  = 140 // { int adjtime(struct timeval *delta, \
-	SYS_SETSID                   = 147 // { int setsid(void); }
-	SYS_QUOTACTL                 = 148 // { int quotactl(char *path, int cmd, int uid, \
-	SYS_LGETFH                   = 160 // { int lgetfh(char *fname, \
-	SYS_GETFH                    = 161 // { int getfh(char *fname, \
-	SYS_SYSARCH                  = 165 // { int sysarch(int op, char *parms); }
-	SYS_RTPRIO                   = 166 // { int rtprio(int function, pid_t pid, \
-	SYS_FREEBSD6_PREAD           = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \
-	SYS_FREEBSD6_PWRITE          = 174 // { ssize_t freebsd6_pwrite(int fd, \
-	SYS_SETFIB                   = 175 // { int setfib(int fibnum); }
-	SYS_NTP_ADJTIME              = 176 // { int ntp_adjtime(struct timex *tp); }
-	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
-	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
-	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
-	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
-	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
-	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, \
-	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, \
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, \
-	SYS_FREEBSD6_MMAP            = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
-	SYS_FREEBSD6_LSEEK           = 199 // { off_t freebsd6_lseek(int fd, int pad, \
-	SYS_FREEBSD6_TRUNCATE        = 200 // { int freebsd6_truncate(char *path, int pad, \
-	SYS_FREEBSD6_FTRUNCATE       = 201 // { int freebsd6_ftruncate(int fd, int pad, \
-	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, \
-	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
-	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
-	SYS_UNDELETE                 = 205 // { int undelete(char *path); }
-	SYS_FUTIMES                  = 206 // { int futimes(int fd, struct timeval *tptr); }
-	SYS_GETPGID                  = 207 // { int getpgid(pid_t pid); }
-	SYS_POLL                     = 209 // { int poll(struct pollfd *fds, u_int nfds, \
-	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, \
-	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( \
-	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, \
-	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, \
-	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
-	SYS_KTIMER_SETTIME           = 237 // { int ktimer_settime(int timerid, int flags, \
-	SYS_KTIMER_GETTIME           = 238 // { int ktimer_gettime(int timerid, struct \
-	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
-	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, \
-	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
-	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( \
-	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( \
-	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,\
-	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
-	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, \
-	SYS_RFORK                    = 251 // { int rfork(int flags); }
-	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, \
-	SYS_ISSETUGID                = 253 // { int issetugid(void); }
-	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
-	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, \
-	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
-	SYS_LUTIMES                  = 276 // { int lutimes(char *path, \
-	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
-	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
-	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
-	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \
-	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \
-	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, \
-	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, \
-	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
-	SYS_MODSTAT                  = 301 // { int modstat(int modid, \
-	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
-	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
-	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
-	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
-	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
-	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
-	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct \
-	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
-	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
-	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, \
-	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, \
-	SYS_YIELD                    = 321 // { int yield(void); }
-	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
-	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
-	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
-	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, \
-	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct \
-	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int \
-	SYS_SCHED_GETSCHEDULER       = 330 // { int sched_getscheduler (pid_t pid); }
-	SYS_SCHED_YIELD              = 331 // { int sched_yield (void); }
-	SYS_SCHED_GET_PRIORITY_MAX   = 332 // { int sched_get_priority_max (int policy); }
-	SYS_SCHED_GET_PRIORITY_MIN   = 333 // { int sched_get_priority_min (int policy); }
-	SYS_SCHED_RR_GET_INTERVAL    = 334 // { int sched_rr_get_interval (pid_t pid, \
-	SYS_UTRACE                   = 335 // { int utrace(const void *addr, size_t len); }
-	SYS_KLDSYM                   = 337 // { int kldsym(int fileid, int cmd, \
-	SYS_JAIL                     = 338 // { int jail(struct jail *jail); }
-	SYS_SIGPROCMASK              = 340 // { int sigprocmask(int how, \
-	SYS_SIGSUSPEND               = 341 // { int sigsuspend(const sigset_t *sigmask); }
-	SYS_SIGPENDING               = 343 // { int sigpending(sigset_t *set); }
-	SYS_SIGTIMEDWAIT             = 345 // { int sigtimedwait(const sigset_t *set, \
-	SYS_SIGWAITINFO              = 346 // { int sigwaitinfo(const sigset_t *set, \
-	SYS___ACL_GET_FILE           = 347 // { int __acl_get_file(const char *path, \
-	SYS___ACL_SET_FILE           = 348 // { int __acl_set_file(const char *path, \
-	SYS___ACL_GET_FD             = 349 // { int __acl_get_fd(int filedes, \
-	SYS___ACL_SET_FD             = 350 // { int __acl_set_fd(int filedes, \
-	SYS___ACL_DELETE_FILE        = 351 // { int __acl_delete_file(const char *path, \
-	SYS___ACL_DELETE_FD          = 352 // { int __acl_delete_fd(int filedes, \
-	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, \
-	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, \
-	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, \
-	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( \
-	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( \
-	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, \
-	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \
-	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \
-	SYS_KQUEUE                   = 362 // { int kqueue(void); }
-	SYS_KEVENT                   = 363 // { int kevent(int fd, \
-	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, \
-	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, \
-	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, \
-	SYS___SETUGID                = 374 // { int __setugid(int flag); }
-	SYS_EACCESS                  = 376 // { int eaccess(char *path, int amode); }
-	SYS_NMOUNT                   = 378 // { int nmount(struct iovec *iovp, \
-	SYS___MAC_GET_PROC           = 384 // { int __mac_get_proc(struct mac *mac_p); }
-	SYS___MAC_SET_PROC           = 385 // { int __mac_set_proc(struct mac *mac_p); }
-	SYS___MAC_GET_FD             = 386 // { int __mac_get_fd(int fd, \
-	SYS___MAC_GET_FILE           = 387 // { int __mac_get_file(const char *path_p, \
-	SYS___MAC_SET_FD             = 388 // { int __mac_set_fd(int fd, \
-	SYS___MAC_SET_FILE           = 389 // { int __mac_set_file(const char *path_p, \
-	SYS_KENV                     = 390 // { int kenv(int what, const char *name, \
-	SYS_LCHFLAGS                 = 391 // { int lchflags(const char *path, \
-	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, \
-	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, \
-	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, \
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, \
-	SYS_STATFS                   = 396 // { int statfs(char *path, \
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
-	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
-	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, \
-	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, \
-	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, \
-	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( \
-	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( \
-	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( \
-	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, \
-	SYS_SIGACTION                = 416 // { int sigaction(int sig, \
-	SYS_SIGRETURN                = 417 // { int sigreturn( \
-	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
-	SYS_SETCONTEXT               = 422 // { int setcontext( \
-	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, \
-	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
-	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, \
-	SYS___ACL_SET_LINK           = 426 // { int __acl_set_link(const char *path, \
-	SYS___ACL_DELETE_LINK        = 427 // { int __acl_delete_link(const char *path, \
-	SYS___ACL_ACLCHECK_LINK      = 428 // { int __acl_aclcheck_link(const char *path, \
-	SYS_SIGWAIT                  = 429 // { int sigwait(const sigset_t *set, \
-	SYS_THR_CREATE               = 430 // { int thr_create(ucontext_t *ctx, long *id, \
-	SYS_THR_EXIT                 = 431 // { void thr_exit(long *state); }
-	SYS_THR_SELF                 = 432 // { int thr_self(long *id); }
-	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
-	SYS__UMTX_LOCK               = 434 // { int _umtx_lock(struct umtx *umtx); }
-	SYS__UMTX_UNLOCK             = 435 // { int _umtx_unlock(struct umtx *umtx); }
-	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
-	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, \
-	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( \
-	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( \
-	SYS_THR_SUSPEND              = 442 // { int thr_suspend( \
-	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
-	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
-	SYS_AUDIT                    = 445 // { int audit(const void *record, \
-	SYS_AUDITON                  = 446 // { int auditon(int cmd, void *data, \
-	SYS_GETAUID                  = 447 // { int getauid(uid_t *auid); }
-	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
-	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
-	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
-	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( \
-	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( \
-	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
-	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, \
-	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, \
-	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
-	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
-	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
-	SYS_RTPRIO_THREAD            = 466 // { int rtprio_thread(int function, \
-	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
-	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
-	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
-	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
-	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, \
-	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, \
-	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, \
-	SYS_LSEEK                    = 478 // { off_t lseek(int fd, off_t offset, \
-	SYS_TRUNCATE                 = 479 // { int truncate(char *path, off_t length); }
-	SYS_FTRUNCATE                = 480 // { int ftruncate(int fd, off_t length); }
-	SYS_THR_KILL2                = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
-	SYS_SHM_OPEN                 = 482 // { int shm_open(const char *path, int flags, \
-	SYS_SHM_UNLINK               = 483 // { int shm_unlink(const char *path); }
-	SYS_CPUSET                   = 484 // { int cpuset(cpusetid_t *setid); }
-	SYS_CPUSET_SETID             = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \
-	SYS_CPUSET_GETID             = 486 // { int cpuset_getid(cpulevel_t level, \
-	SYS_CPUSET_GETAFFINITY       = 487 // { int cpuset_getaffinity(cpulevel_t level, \
-	SYS_CPUSET_SETAFFINITY       = 488 // { int cpuset_setaffinity(cpulevel_t level, \
-	SYS_FACCESSAT                = 489 // { int faccessat(int fd, char *path, int amode, \
-	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
-	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, \
-	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, \
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, \
-	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, \
-	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, \
-	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
-	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, \
-	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, \
-	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, \
-	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, \
-	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, \
-	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
-	SYS_POSIX_OPENPT             = 504 // { int posix_openpt(int flags); }
-	SYS_JAIL_GET                 = 506 // { int jail_get(struct iovec *iovp, \
-	SYS_JAIL_SET                 = 507 // { int jail_set(struct iovec *iovp, \
-	SYS_JAIL_REMOVE              = 508 // { int jail_remove(int jid); }
-	SYS_CLOSEFROM                = 509 // { int closefrom(int lowfd); }
-	SYS_LPATHCONF                = 513 // { int lpathconf(char *path, int name); }
-	SYS_CAP_NEW                  = 514 // { int cap_new(int fd, uint64_t rights); }
-	SYS_CAP_GETRIGHTS            = 515 // { int cap_getrights(int fd, \
-	SYS_CAP_ENTER                = 516 // { int cap_enter(void); }
-	SYS_CAP_GETMODE              = 517 // { int cap_getmode(u_int *modep); }
-	SYS_PDFORK                   = 518 // { int pdfork(int *fdp, int flags); }
-	SYS_PDKILL                   = 519 // { int pdkill(int fd, int signum); }
-	SYS_PDGETPID                 = 520 // { int pdgetpid(int fd, pid_t *pidp); }
-	SYS_PSELECT                  = 522 // { int pselect(int nd, fd_set *in, \
-	SYS_GETLOGINCLASS            = 523 // { int getloginclass(char *namebuf, \
-	SYS_SETLOGINCLASS            = 524 // { int setloginclass(const char *namebuf); }
-	SYS_RCTL_GET_RACCT           = 525 // { int rctl_get_racct(const void *inbufp, \
-	SYS_RCTL_GET_RULES           = 526 // { int rctl_get_rules(const void *inbufp, \
-	SYS_RCTL_GET_LIMITS          = 527 // { int rctl_get_limits(const void *inbufp, \
-	SYS_RCTL_ADD_RULE            = 528 // { int rctl_add_rule(const void *inbufp, \
-	SYS_RCTL_REMOVE_RULE         = 529 // { int rctl_remove_rule(const void *inbufp, \
-	SYS_POSIX_FALLOCATE          = 530 // { int posix_fallocate(int fd, \
-	SYS_POSIX_FADVISE            = 531 // { int posix_fadvise(int fd, off_t offset, \
-	SYS_WAIT6                    = 532 // { int wait6(idtype_t idtype, id_t id, \
-	SYS_BINDAT                   = 538 // { int bindat(int fd, int s, caddr_t name, \
-	SYS_CONNECTAT                = 539 // { int connectat(int fd, int s, caddr_t name, \
-	SYS_CHFLAGSAT                = 540 // { int chflagsat(int fd, const char *path, \
-	SYS_ACCEPT4                  = 541 // { int accept4(int s, \
-	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
-	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
-	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \
+	SYS_EXIT                   = 1   // { void sys_exit(int rval); } exit \
+	SYS_FORK                   = 2   // { int fork(void); }
+	SYS_READ                   = 3   // { ssize_t read(int fd, void *buf, \
+	SYS_WRITE                  = 4   // { ssize_t write(int fd, const void *buf, \
+	SYS_OPEN                   = 5   // { int open(char *path, int flags, int mode); }
+	SYS_CLOSE                  = 6   // { int close(int fd); }
+	SYS_WAIT4                  = 7   // { int wait4(int pid, int *status, \
+	SYS_LINK                   = 9   // { int link(char *path, char *link); }
+	SYS_UNLINK                 = 10  // { int unlink(char *path); }
+	SYS_CHDIR                  = 12  // { int chdir(char *path); }
+	SYS_FCHDIR                 = 13  // { int fchdir(int fd); }
+	SYS_MKNOD                  = 14  // { int mknod(char *path, int mode, int dev); }
+	SYS_CHMOD                  = 15  // { int chmod(char *path, int mode); }
+	SYS_CHOWN                  = 16  // { int chown(char *path, int uid, int gid); }
+	SYS_OBREAK                 = 17  // { int obreak(char *nsize); } break \
+	SYS_GETPID                 = 20  // { pid_t getpid(void); }
+	SYS_MOUNT                  = 21  // { int mount(char *type, char *path, \
+	SYS_UNMOUNT                = 22  // { int unmount(char *path, int flags); }
+	SYS_SETUID                 = 23  // { int setuid(uid_t uid); }
+	SYS_GETUID                 = 24  // { uid_t getuid(void); }
+	SYS_GETEUID                = 25  // { uid_t geteuid(void); }
+	SYS_PTRACE                 = 26  // { int ptrace(int req, pid_t pid, \
+	SYS_RECVMSG                = 27  // { int recvmsg(int s, struct msghdr *msg, \
+	SYS_SENDMSG                = 28  // { int sendmsg(int s, struct msghdr *msg, \
+	SYS_RECVFROM               = 29  // { int recvfrom(int s, caddr_t buf, \
+	SYS_ACCEPT                 = 30  // { int accept(int s, \
+	SYS_GETPEERNAME            = 31  // { int getpeername(int fdes, \
+	SYS_GETSOCKNAME            = 32  // { int getsockname(int fdes, \
+	SYS_ACCESS                 = 33  // { int access(char *path, int amode); }
+	SYS_CHFLAGS                = 34  // { int chflags(const char *path, u_long flags); }
+	SYS_FCHFLAGS               = 35  // { int fchflags(int fd, u_long flags); }
+	SYS_SYNC                   = 36  // { int sync(void); }
+	SYS_KILL                   = 37  // { int kill(int pid, int signum); }
+	SYS_GETPPID                = 39  // { pid_t getppid(void); }
+	SYS_DUP                    = 41  // { int dup(u_int fd); }
+	SYS_PIPE                   = 42  // { int pipe(void); }
+	SYS_GETEGID                = 43  // { gid_t getegid(void); }
+	SYS_PROFIL                 = 44  // { int profil(caddr_t samples, size_t size, \
+	SYS_KTRACE                 = 45  // { int ktrace(const char *fname, int ops, \
+	SYS_GETGID                 = 47  // { gid_t getgid(void); }
+	SYS_GETLOGIN               = 49  // { int getlogin(char *namebuf, u_int \
+	SYS_SETLOGIN               = 50  // { int setlogin(char *namebuf); }
+	SYS_ACCT                   = 51  // { int acct(char *path); }
+	SYS_SIGALTSTACK            = 53  // { int sigaltstack(stack_t *ss, \
+	SYS_IOCTL                  = 54  // { int ioctl(int fd, u_long com, \
+	SYS_REBOOT                 = 55  // { int reboot(int opt); }
+	SYS_REVOKE                 = 56  // { int revoke(char *path); }
+	SYS_SYMLINK                = 57  // { int symlink(char *path, char *link); }
+	SYS_READLINK               = 58  // { ssize_t readlink(char *path, char *buf, \
+	SYS_EXECVE                 = 59  // { int execve(char *fname, char **argv, \
+	SYS_UMASK                  = 60  // { int umask(int newmask); } umask umask_args \
+	SYS_CHROOT                 = 61  // { int chroot(char *path); }
+	SYS_MSYNC                  = 65  // { int msync(void *addr, size_t len, \
+	SYS_VFORK                  = 66  // { int vfork(void); }
+	SYS_SBRK                   = 69  // { int sbrk(int incr); }
+	SYS_SSTK                   = 70  // { int sstk(int incr); }
+	SYS_OVADVISE               = 72  // { int ovadvise(int anom); } vadvise \
+	SYS_MUNMAP                 = 73  // { int munmap(void *addr, size_t len); }
+	SYS_MPROTECT               = 74  // { int mprotect(const void *addr, size_t len, \
+	SYS_MADVISE                = 75  // { int madvise(void *addr, size_t len, \
+	SYS_MINCORE                = 78  // { int mincore(const void *addr, size_t len, \
+	SYS_GETGROUPS              = 79  // { int getgroups(u_int gidsetsize, \
+	SYS_SETGROUPS              = 80  // { int setgroups(u_int gidsetsize, \
+	SYS_GETPGRP                = 81  // { int getpgrp(void); }
+	SYS_SETPGID                = 82  // { int setpgid(int pid, int pgid); }
+	SYS_SETITIMER              = 83  // { int setitimer(u_int which, struct \
+	SYS_SWAPON                 = 85  // { int swapon(char *name); }
+	SYS_GETITIMER              = 86  // { int getitimer(u_int which, \
+	SYS_GETDTABLESIZE          = 89  // { int getdtablesize(void); }
+	SYS_DUP2                   = 90  // { int dup2(u_int from, u_int to); }
+	SYS_FCNTL                  = 92  // { int fcntl(int fd, int cmd, long arg); }
+	SYS_SELECT                 = 93  // { int select(int nd, fd_set *in, fd_set *ou, \
+	SYS_FSYNC                  = 95  // { int fsync(int fd); }
+	SYS_SETPRIORITY            = 96  // { int setpriority(int which, int who, \
+	SYS_SOCKET                 = 97  // { int socket(int domain, int type, \
+	SYS_CONNECT                = 98  // { int connect(int s, caddr_t name, \
+	SYS_GETPRIORITY            = 100 // { int getpriority(int which, int who); }
+	SYS_BIND                   = 104 // { int bind(int s, caddr_t name, \
+	SYS_SETSOCKOPT             = 105 // { int setsockopt(int s, int level, int name, \
+	SYS_LISTEN                 = 106 // { int listen(int s, int backlog); }
+	SYS_GETTIMEOFDAY           = 116 // { int gettimeofday(struct timeval *tp, \
+	SYS_GETRUSAGE              = 117 // { int getrusage(int who, \
+	SYS_GETSOCKOPT             = 118 // { int getsockopt(int s, int level, int name, \
+	SYS_READV                  = 120 // { int readv(int fd, struct iovec *iovp, \
+	SYS_WRITEV                 = 121 // { int writev(int fd, struct iovec *iovp, \
+	SYS_SETTIMEOFDAY           = 122 // { int settimeofday(struct timeval *tv, \
+	SYS_FCHOWN                 = 123 // { int fchown(int fd, int uid, int gid); }
+	SYS_FCHMOD                 = 124 // { int fchmod(int fd, int mode); }
+	SYS_SETREUID               = 126 // { int setreuid(int ruid, int euid); }
+	SYS_SETREGID               = 127 // { int setregid(int rgid, int egid); }
+	SYS_RENAME                 = 128 // { int rename(char *from, char *to); }
+	SYS_FLOCK                  = 131 // { int flock(int fd, int how); }
+	SYS_MKFIFO                 = 132 // { int mkfifo(char *path, int mode); }
+	SYS_SENDTO                 = 133 // { int sendto(int s, caddr_t buf, size_t len, \
+	SYS_SHUTDOWN               = 134 // { int shutdown(int s, int how); }
+	SYS_SOCKETPAIR             = 135 // { int socketpair(int domain, int type, \
+	SYS_MKDIR                  = 136 // { int mkdir(char *path, int mode); }
+	SYS_RMDIR                  = 137 // { int rmdir(char *path); }
+	SYS_UTIMES                 = 138 // { int utimes(char *path, \
+	SYS_ADJTIME                = 140 // { int adjtime(struct timeval *delta, \
+	SYS_SETSID                 = 147 // { int setsid(void); }
+	SYS_QUOTACTL               = 148 // { int quotactl(char *path, int cmd, int uid, \
+	SYS_LGETFH                 = 160 // { int lgetfh(char *fname, \
+	SYS_GETFH                  = 161 // { int getfh(char *fname, \
+	SYS_SYSARCH                = 165 // { int sysarch(int op, char *parms); }
+	SYS_RTPRIO                 = 166 // { int rtprio(int function, pid_t pid, \
+	SYS_FREEBSD6_PREAD         = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \
+	SYS_FREEBSD6_PWRITE        = 174 // { ssize_t freebsd6_pwrite(int fd, \
+	SYS_SETFIB                 = 175 // { int setfib(int fibnum); }
+	SYS_NTP_ADJTIME            = 176 // { int ntp_adjtime(struct timex *tp); }
+	SYS_SETGID                 = 181 // { int setgid(gid_t gid); }
+	SYS_SETEGID                = 182 // { int setegid(gid_t egid); }
+	SYS_SETEUID                = 183 // { int seteuid(uid_t euid); }
+	SYS_STAT                   = 188 // { int stat(char *path, struct stat *ub); }
+	SYS_FSTAT                  = 189 // { int fstat(int fd, struct stat *sb); }
+	SYS_LSTAT                  = 190 // { int lstat(char *path, struct stat *ub); }
+	SYS_PATHCONF               = 191 // { int pathconf(char *path, int name); }
+	SYS_FPATHCONF              = 192 // { int fpathconf(int fd, int name); }
+	SYS_GETRLIMIT              = 194 // { int getrlimit(u_int which, \
+	SYS_SETRLIMIT              = 195 // { int setrlimit(u_int which, \
+	SYS_GETDIRENTRIES          = 196 // { int getdirentries(int fd, char *buf, \
+	SYS_FREEBSD6_MMAP          = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
+	SYS_FREEBSD6_LSEEK         = 199 // { off_t freebsd6_lseek(int fd, int pad, \
+	SYS_FREEBSD6_TRUNCATE      = 200 // { int freebsd6_truncate(char *path, int pad, \
+	SYS_FREEBSD6_FTRUNCATE     = 201 // { int freebsd6_ftruncate(int fd, int pad, \
+	SYS___SYSCTL               = 202 // { int __sysctl(int *name, u_int namelen, \
+	SYS_MLOCK                  = 203 // { int mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK                = 204 // { int munlock(const void *addr, size_t len); }
+	SYS_UNDELETE               = 205 // { int undelete(char *path); }
+	SYS_FUTIMES                = 206 // { int futimes(int fd, struct timeval *tptr); }
+	SYS_GETPGID                = 207 // { int getpgid(pid_t pid); }
+	SYS_POLL                   = 209 // { int poll(struct pollfd *fds, u_int nfds, \
+	SYS_CLOCK_GETTIME          = 232 // { int clock_gettime(clockid_t clock_id, \
+	SYS_CLOCK_SETTIME          = 233 // { int clock_settime( \
+	SYS_CLOCK_GETRES           = 234 // { int clock_getres(clockid_t clock_id, \
+	SYS_KTIMER_CREATE          = 235 // { int ktimer_create(clockid_t clock_id, \
+	SYS_KTIMER_DELETE          = 236 // { int ktimer_delete(int timerid); }
+	SYS_KTIMER_SETTIME         = 237 // { int ktimer_settime(int timerid, int flags, \
+	SYS_KTIMER_GETTIME         = 238 // { int ktimer_gettime(int timerid, struct \
+	SYS_KTIMER_GETOVERRUN      = 239 // { int ktimer_getoverrun(int timerid); }
+	SYS_NANOSLEEP              = 240 // { int nanosleep(const struct timespec *rqtp, \
+	SYS_FFCLOCK_GETCOUNTER     = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
+	SYS_FFCLOCK_SETESTIMATE    = 242 // { int ffclock_setestimate( \
+	SYS_FFCLOCK_GETESTIMATE    = 243 // { int ffclock_getestimate( \
+	SYS_CLOCK_GETCPUCLOCKID2   = 247 // { int clock_getcpuclockid2(id_t id,\
+	SYS_NTP_GETTIME            = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
+	SYS_MINHERIT               = 250 // { int minherit(void *addr, size_t len, \
+	SYS_RFORK                  = 251 // { int rfork(int flags); }
+	SYS_OPENBSD_POLL           = 252 // { int openbsd_poll(struct pollfd *fds, \
+	SYS_ISSETUGID              = 253 // { int issetugid(void); }
+	SYS_LCHOWN                 = 254 // { int lchown(char *path, int uid, int gid); }
+	SYS_GETDENTS               = 272 // { int getdents(int fd, char *buf, \
+	SYS_LCHMOD                 = 274 // { int lchmod(char *path, mode_t mode); }
+	SYS_LUTIMES                = 276 // { int lutimes(char *path, \
+	SYS_NSTAT                  = 278 // { int nstat(char *path, struct nstat *ub); }
+	SYS_NFSTAT                 = 279 // { int nfstat(int fd, struct nstat *sb); }
+	SYS_NLSTAT                 = 280 // { int nlstat(char *path, struct nstat *ub); }
+	SYS_PREADV                 = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \
+	SYS_PWRITEV                = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \
+	SYS_FHOPEN                 = 298 // { int fhopen(const struct fhandle *u_fhp, \
+	SYS_FHSTAT                 = 299 // { int fhstat(const struct fhandle *u_fhp, \
+	SYS_MODNEXT                = 300 // { int modnext(int modid); }
+	SYS_MODSTAT                = 301 // { int modstat(int modid, \
+	SYS_MODFNEXT               = 302 // { int modfnext(int modid); }
+	SYS_MODFIND                = 303 // { int modfind(const char *name); }
+	SYS_KLDLOAD                = 304 // { int kldload(const char *file); }
+	SYS_KLDUNLOAD              = 305 // { int kldunload(int fileid); }
+	SYS_KLDFIND                = 306 // { int kldfind(const char *file); }
+	SYS_KLDNEXT                = 307 // { int kldnext(int fileid); }
+	SYS_KLDSTAT                = 308 // { int kldstat(int fileid, struct \
+	SYS_KLDFIRSTMOD            = 309 // { int kldfirstmod(int fileid); }
+	SYS_GETSID                 = 310 // { int getsid(pid_t pid); }
+	SYS_SETRESUID              = 311 // { int setresuid(uid_t ruid, uid_t euid, \
+	SYS_SETRESGID              = 312 // { int setresgid(gid_t rgid, gid_t egid, \
+	SYS_YIELD                  = 321 // { int yield(void); }
+	SYS_MLOCKALL               = 324 // { int mlockall(int how); }
+	SYS_MUNLOCKALL             = 325 // { int munlockall(void); }
+	SYS___GETCWD               = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS_SCHED_SETPARAM         = 327 // { int sched_setparam (pid_t pid, \
+	SYS_SCHED_GETPARAM         = 328 // { int sched_getparam (pid_t pid, struct \
+	SYS_SCHED_SETSCHEDULER     = 329 // { int sched_setscheduler (pid_t pid, int \
+	SYS_SCHED_GETSCHEDULER     = 330 // { int sched_getscheduler (pid_t pid); }
+	SYS_SCHED_YIELD            = 331 // { int sched_yield (void); }
+	SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); }
+	SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); }
+	SYS_SCHED_RR_GET_INTERVAL  = 334 // { int sched_rr_get_interval (pid_t pid, \
+	SYS_UTRACE                 = 335 // { int utrace(const void *addr, size_t len); }
+	SYS_KLDSYM                 = 337 // { int kldsym(int fileid, int cmd, \
+	SYS_JAIL                   = 338 // { int jail(struct jail *jail); }
+	SYS_SIGPROCMASK            = 340 // { int sigprocmask(int how, \
+	SYS_SIGSUSPEND             = 341 // { int sigsuspend(const sigset_t *sigmask); }
+	SYS_SIGPENDING             = 343 // { int sigpending(sigset_t *set); }
+	SYS_SIGTIMEDWAIT           = 345 // { int sigtimedwait(const sigset_t *set, \
+	SYS_SIGWAITINFO            = 346 // { int sigwaitinfo(const sigset_t *set, \
+	SYS___ACL_GET_FILE         = 347 // { int __acl_get_file(const char *path, \
+	SYS___ACL_SET_FILE         = 348 // { int __acl_set_file(const char *path, \
+	SYS___ACL_GET_FD           = 349 // { int __acl_get_fd(int filedes, \
+	SYS___ACL_SET_FD           = 350 // { int __acl_set_fd(int filedes, \
+	SYS___ACL_DELETE_FILE      = 351 // { int __acl_delete_file(const char *path, \
+	SYS___ACL_DELETE_FD        = 352 // { int __acl_delete_fd(int filedes, \
+	SYS___ACL_ACLCHECK_FILE    = 353 // { int __acl_aclcheck_file(const char *path, \
+	SYS___ACL_ACLCHECK_FD      = 354 // { int __acl_aclcheck_fd(int filedes, \
+	SYS_EXTATTRCTL             = 355 // { int extattrctl(const char *path, int cmd, \
+	SYS_EXTATTR_SET_FILE       = 356 // { ssize_t extattr_set_file( \
+	SYS_EXTATTR_GET_FILE       = 357 // { ssize_t extattr_get_file( \
+	SYS_EXTATTR_DELETE_FILE    = 358 // { int extattr_delete_file(const char *path, \
+	SYS_GETRESUID              = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \
+	SYS_GETRESGID              = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \
+	SYS_KQUEUE                 = 362 // { int kqueue(void); }
+	SYS_KEVENT                 = 363 // { int kevent(int fd, \
+	SYS_EXTATTR_SET_FD         = 371 // { ssize_t extattr_set_fd(int fd, \
+	SYS_EXTATTR_GET_FD         = 372 // { ssize_t extattr_get_fd(int fd, \
+	SYS_EXTATTR_DELETE_FD      = 373 // { int extattr_delete_fd(int fd, \
+	SYS___SETUGID              = 374 // { int __setugid(int flag); }
+	SYS_EACCESS                = 376 // { int eaccess(char *path, int amode); }
+	SYS_NMOUNT                 = 378 // { int nmount(struct iovec *iovp, \
+	SYS___MAC_GET_PROC         = 384 // { int __mac_get_proc(struct mac *mac_p); }
+	SYS___MAC_SET_PROC         = 385 // { int __mac_set_proc(struct mac *mac_p); }
+	SYS___MAC_GET_FD           = 386 // { int __mac_get_fd(int fd, \
+	SYS___MAC_GET_FILE         = 387 // { int __mac_get_file(const char *path_p, \
+	SYS___MAC_SET_FD           = 388 // { int __mac_set_fd(int fd, \
+	SYS___MAC_SET_FILE         = 389 // { int __mac_set_file(const char *path_p, \
+	SYS_KENV                   = 390 // { int kenv(int what, const char *name, \
+	SYS_LCHFLAGS               = 391 // { int lchflags(const char *path, \
+	SYS_UUIDGEN                = 392 // { int uuidgen(struct uuid *store, \
+	SYS_SENDFILE               = 393 // { int sendfile(int fd, int s, off_t offset, \
+	SYS_MAC_SYSCALL            = 394 // { int mac_syscall(const char *policy, \
+	SYS_GETFSSTAT              = 395 // { int getfsstat(struct statfs *buf, \
+	SYS_STATFS                 = 396 // { int statfs(char *path, \
+	SYS_FSTATFS                = 397 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_FHSTATFS               = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
+	SYS___MAC_GET_PID          = 409 // { int __mac_get_pid(pid_t pid, \
+	SYS___MAC_GET_LINK         = 410 // { int __mac_get_link(const char *path_p, \
+	SYS___MAC_SET_LINK         = 411 // { int __mac_set_link(const char *path_p, \
+	SYS_EXTATTR_SET_LINK       = 412 // { ssize_t extattr_set_link( \
+	SYS_EXTATTR_GET_LINK       = 413 // { ssize_t extattr_get_link( \
+	SYS_EXTATTR_DELETE_LINK    = 414 // { int extattr_delete_link( \
+	SYS___MAC_EXECVE           = 415 // { int __mac_execve(char *fname, char **argv, \
+	SYS_SIGACTION              = 416 // { int sigaction(int sig, \
+	SYS_SIGRETURN              = 417 // { int sigreturn( \
+	SYS_GETCONTEXT             = 421 // { int getcontext(struct __ucontext *ucp); }
+	SYS_SETCONTEXT             = 422 // { int setcontext( \
+	SYS_SWAPCONTEXT            = 423 // { int swapcontext(struct __ucontext *oucp, \
+	SYS_SWAPOFF                = 424 // { int swapoff(const char *name); }
+	SYS___ACL_GET_LINK         = 425 // { int __acl_get_link(const char *path, \
+	SYS___ACL_SET_LINK         = 426 // { int __acl_set_link(const char *path, \
+	SYS___ACL_DELETE_LINK      = 427 // { int __acl_delete_link(const char *path, \
+	SYS___ACL_ACLCHECK_LINK    = 428 // { int __acl_aclcheck_link(const char *path, \
+	SYS_SIGWAIT                = 429 // { int sigwait(const sigset_t *set, \
+	SYS_THR_CREATE             = 430 // { int thr_create(ucontext_t *ctx, long *id, \
+	SYS_THR_EXIT               = 431 // { void thr_exit(long *state); }
+	SYS_THR_SELF               = 432 // { int thr_self(long *id); }
+	SYS_THR_KILL               = 433 // { int thr_kill(long id, int sig); }
+	SYS__UMTX_LOCK             = 434 // { int _umtx_lock(struct umtx *umtx); }
+	SYS__UMTX_UNLOCK           = 435 // { int _umtx_unlock(struct umtx *umtx); }
+	SYS_JAIL_ATTACH            = 436 // { int jail_attach(int jid); }
+	SYS_EXTATTR_LIST_FD        = 437 // { ssize_t extattr_list_fd(int fd, \
+	SYS_EXTATTR_LIST_FILE      = 438 // { ssize_t extattr_list_file( \
+	SYS_EXTATTR_LIST_LINK      = 439 // { ssize_t extattr_list_link( \
+	SYS_THR_SUSPEND            = 442 // { int thr_suspend( \
+	SYS_THR_WAKE               = 443 // { int thr_wake(long id); }
+	SYS_KLDUNLOADF             = 444 // { int kldunloadf(int fileid, int flags); }
+	SYS_AUDIT                  = 445 // { int audit(const void *record, \
+	SYS_AUDITON                = 446 // { int auditon(int cmd, void *data, \
+	SYS_GETAUID                = 447 // { int getauid(uid_t *auid); }
+	SYS_SETAUID                = 448 // { int setauid(uid_t *auid); }
+	SYS_GETAUDIT               = 449 // { int getaudit(struct auditinfo *auditinfo); }
+	SYS_SETAUDIT               = 450 // { int setaudit(struct auditinfo *auditinfo); }
+	SYS_GETAUDIT_ADDR          = 451 // { int getaudit_addr( \
+	SYS_SETAUDIT_ADDR          = 452 // { int setaudit_addr( \
+	SYS_AUDITCTL               = 453 // { int auditctl(char *path); }
+	SYS__UMTX_OP               = 454 // { int _umtx_op(void *obj, int op, \
+	SYS_THR_NEW                = 455 // { int thr_new(struct thr_param *param, \
+	SYS_SIGQUEUE               = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
+	SYS_ABORT2                 = 463 // { int abort2(const char *why, int nargs, void **args); }
+	SYS_THR_SET_NAME           = 464 // { int thr_set_name(long id, const char *name); }
+	SYS_RTPRIO_THREAD          = 466 // { int rtprio_thread(int function, \
+	SYS_PREAD                  = 475 // { ssize_t pread(int fd, void *buf, \
+	SYS_PWRITE                 = 476 // { ssize_t pwrite(int fd, const void *buf, \
+	SYS_MMAP                   = 477 // { caddr_t mmap(caddr_t addr, size_t len, \
+	SYS_LSEEK                  = 478 // { off_t lseek(int fd, off_t offset, \
+	SYS_TRUNCATE               = 479 // { int truncate(char *path, off_t length); }
+	SYS_FTRUNCATE              = 480 // { int ftruncate(int fd, off_t length); }
+	SYS_THR_KILL2              = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
+	SYS_SHM_OPEN               = 482 // { int shm_open(const char *path, int flags, \
+	SYS_SHM_UNLINK             = 483 // { int shm_unlink(const char *path); }
+	SYS_CPUSET                 = 484 // { int cpuset(cpusetid_t *setid); }
+	SYS_CPUSET_SETID           = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \
+	SYS_CPUSET_GETID           = 486 // { int cpuset_getid(cpulevel_t level, \
+	SYS_CPUSET_GETAFFINITY     = 487 // { int cpuset_getaffinity(cpulevel_t level, \
+	SYS_CPUSET_SETAFFINITY     = 488 // { int cpuset_setaffinity(cpulevel_t level, \
+	SYS_FACCESSAT              = 489 // { int faccessat(int fd, char *path, int amode, \
+	SYS_FCHMODAT               = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
+	SYS_FCHOWNAT               = 491 // { int fchownat(int fd, char *path, uid_t uid, \
+	SYS_FEXECVE                = 492 // { int fexecve(int fd, char **argv, \
+	SYS_FSTATAT                = 493 // { int fstatat(int fd, char *path, \
+	SYS_FUTIMESAT              = 494 // { int futimesat(int fd, char *path, \
+	SYS_LINKAT                 = 495 // { int linkat(int fd1, char *path1, int fd2, \
+	SYS_MKDIRAT                = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
+	SYS_MKFIFOAT               = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
+	SYS_MKNODAT                = 498 // { int mknodat(int fd, char *path, mode_t mode, \
+	SYS_OPENAT                 = 499 // { int openat(int fd, char *path, int flag, \
+	SYS_READLINKAT             = 500 // { int readlinkat(int fd, char *path, char *buf, \
+	SYS_RENAMEAT               = 501 // { int renameat(int oldfd, char *old, int newfd, \
+	SYS_SYMLINKAT              = 502 // { int symlinkat(char *path1, int fd, \
+	SYS_UNLINKAT               = 503 // { int unlinkat(int fd, char *path, int flag); }
+	SYS_POSIX_OPENPT           = 504 // { int posix_openpt(int flags); }
+	SYS_JAIL_GET               = 506 // { int jail_get(struct iovec *iovp, \
+	SYS_JAIL_SET               = 507 // { int jail_set(struct iovec *iovp, \
+	SYS_JAIL_REMOVE            = 508 // { int jail_remove(int jid); }
+	SYS_CLOSEFROM              = 509 // { int closefrom(int lowfd); }
+	SYS_LPATHCONF              = 513 // { int lpathconf(char *path, int name); }
+	SYS___CAP_RIGHTS_GET       = 515 // { int __cap_rights_get(int version, \
+	SYS_CAP_ENTER              = 516 // { int cap_enter(void); }
+	SYS_CAP_GETMODE            = 517 // { int cap_getmode(u_int *modep); }
+	SYS_PDFORK                 = 518 // { int pdfork(int *fdp, int flags); }
+	SYS_PDKILL                 = 519 // { int pdkill(int fd, int signum); }
+	SYS_PDGETPID               = 520 // { int pdgetpid(int fd, pid_t *pidp); }
+	SYS_PSELECT                = 522 // { int pselect(int nd, fd_set *in, \
+	SYS_GETLOGINCLASS          = 523 // { int getloginclass(char *namebuf, \
+	SYS_SETLOGINCLASS          = 524 // { int setloginclass(const char *namebuf); }
+	SYS_RCTL_GET_RACCT         = 525 // { int rctl_get_racct(const void *inbufp, \
+	SYS_RCTL_GET_RULES         = 526 // { int rctl_get_rules(const void *inbufp, \
+	SYS_RCTL_GET_LIMITS        = 527 // { int rctl_get_limits(const void *inbufp, \
+	SYS_RCTL_ADD_RULE          = 528 // { int rctl_add_rule(const void *inbufp, \
+	SYS_RCTL_REMOVE_RULE       = 529 // { int rctl_remove_rule(const void *inbufp, \
+	SYS_POSIX_FALLOCATE        = 530 // { int posix_fallocate(int fd, \
+	SYS_POSIX_FADVISE          = 531 // { int posix_fadvise(int fd, off_t offset, \
+	SYS_WAIT6                  = 532 // { int wait6(idtype_t idtype, id_t id, \
+	SYS_CAP_RIGHTS_LIMIT       = 533 // { int cap_rights_limit(int fd, \
+	SYS_CAP_IOCTLS_LIMIT       = 534 // { int cap_ioctls_limit(int fd, \
+	SYS_CAP_IOCTLS_GET         = 535 // { ssize_t cap_ioctls_get(int fd, \
+	SYS_CAP_FCNTLS_LIMIT       = 536 // { int cap_fcntls_limit(int fd, \
+	SYS_CAP_FCNTLS_GET         = 537 // { int cap_fcntls_get(int fd, \
+	SYS_BINDAT                 = 538 // { int bindat(int fd, int s, caddr_t name, \
+	SYS_CONNECTAT              = 539 // { int connectat(int fd, int s, caddr_t name, \
+	SYS_CHFLAGSAT              = 540 // { int chflagsat(int fd, const char *path, \
+	SYS_ACCEPT4                = 541 // { int accept4(int s, \
+	SYS_PIPE2                  = 542 // { int pipe2(int *fildes, int flags); }
+	SYS_PROCCTL                = 544 // { int procctl(idtype_t idtype, id_t id, \
+	SYS_PPOLL                  = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \
+	SYS_FUTIMENS               = 546 // { int futimens(int fd, \
+	SYS_UTIMENSAT              = 547 // { int utimensat(int fd, \
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
index 206b9f6..4488314 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
@@ -1,5 +1,5 @@
 // mksysnum_freebsd.pl
-// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build arm,freebsd
 
@@ -7,345 +7,347 @@
 
 const (
 	// SYS_NOSYS = 0;  // { int nosys(void); } syscall nosys_args int
-	SYS_EXIT                     = 1   // { void sys_exit(int rval); } exit \
-	SYS_FORK                     = 2   // { int fork(void); }
-	SYS_READ                     = 3   // { ssize_t read(int fd, void *buf, \
-	SYS_WRITE                    = 4   // { ssize_t write(int fd, const void *buf, \
-	SYS_OPEN                     = 5   // { int open(char *path, int flags, int mode); }
-	SYS_CLOSE                    = 6   // { int close(int fd); }
-	SYS_WAIT4                    = 7   // { int wait4(int pid, int *status, \
-	SYS_LINK                     = 9   // { int link(char *path, char *link); }
-	SYS_UNLINK                   = 10  // { int unlink(char *path); }
-	SYS_CHDIR                    = 12  // { int chdir(char *path); }
-	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
-	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
-	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
-	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
-	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break \
-	SYS_GETPID                   = 20  // { pid_t getpid(void); }
-	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, \
-	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
-	SYS_SETUID                   = 23  // { int setuid(uid_t uid); }
-	SYS_GETUID                   = 24  // { uid_t getuid(void); }
-	SYS_GETEUID                  = 25  // { uid_t geteuid(void); }
-	SYS_PTRACE                   = 26  // { int ptrace(int req, pid_t pid, \
-	SYS_RECVMSG                  = 27  // { int recvmsg(int s, struct msghdr *msg, \
-	SYS_SENDMSG                  = 28  // { int sendmsg(int s, struct msghdr *msg, \
-	SYS_RECVFROM                 = 29  // { int recvfrom(int s, caddr_t buf, \
-	SYS_ACCEPT                   = 30  // { int accept(int s, \
-	SYS_GETPEERNAME              = 31  // { int getpeername(int fdes, \
-	SYS_GETSOCKNAME              = 32  // { int getsockname(int fdes, \
-	SYS_ACCESS                   = 33  // { int access(char *path, int amode); }
-	SYS_CHFLAGS                  = 34  // { int chflags(const char *path, u_long flags); }
-	SYS_FCHFLAGS                 = 35  // { int fchflags(int fd, u_long flags); }
-	SYS_SYNC                     = 36  // { int sync(void); }
-	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
-	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
-	SYS_DUP                      = 41  // { int dup(u_int fd); }
-	SYS_PIPE                     = 42  // { int pipe(void); }
-	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
-	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, \
-	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, \
-	SYS_GETGID                   = 47  // { gid_t getgid(void); }
-	SYS_GETLOGIN                 = 49  // { int getlogin(char *namebuf, u_int \
-	SYS_SETLOGIN                 = 50  // { int setlogin(char *namebuf); }
-	SYS_ACCT                     = 51  // { int acct(char *path); }
-	SYS_SIGALTSTACK              = 53  // { int sigaltstack(stack_t *ss, \
-	SYS_IOCTL                    = 54  // { int ioctl(int fd, u_long com, \
-	SYS_REBOOT                   = 55  // { int reboot(int opt); }
-	SYS_REVOKE                   = 56  // { int revoke(char *path); }
-	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
-	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, \
-	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, \
-	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args \
-	SYS_CHROOT                   = 61  // { int chroot(char *path); }
-	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, \
-	SYS_VFORK                    = 66  // { int vfork(void); }
-	SYS_SBRK                     = 69  // { int sbrk(int incr); }
-	SYS_SSTK                     = 70  // { int sstk(int incr); }
-	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise \
-	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
-	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, \
-	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, \
-	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, \
-	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, \
-	SYS_SETGROUPS                = 80  // { int setgroups(u_int gidsetsize, \
-	SYS_GETPGRP                  = 81  // { int getpgrp(void); }
-	SYS_SETPGID                  = 82  // { int setpgid(int pid, int pgid); }
-	SYS_SETITIMER                = 83  // { int setitimer(u_int which, struct \
-	SYS_SWAPON                   = 85  // { int swapon(char *name); }
-	SYS_GETITIMER                = 86  // { int getitimer(u_int which, \
-	SYS_GETDTABLESIZE            = 89  // { int getdtablesize(void); }
-	SYS_DUP2                     = 90  // { int dup2(u_int from, u_int to); }
-	SYS_FCNTL                    = 92  // { int fcntl(int fd, int cmd, long arg); }
-	SYS_SELECT                   = 93  // { int select(int nd, fd_set *in, fd_set *ou, \
-	SYS_FSYNC                    = 95  // { int fsync(int fd); }
-	SYS_SETPRIORITY              = 96  // { int setpriority(int which, int who, \
-	SYS_SOCKET                   = 97  // { int socket(int domain, int type, \
-	SYS_CONNECT                  = 98  // { int connect(int s, caddr_t name, \
-	SYS_GETPRIORITY              = 100 // { int getpriority(int which, int who); }
-	SYS_BIND                     = 104 // { int bind(int s, caddr_t name, \
-	SYS_SETSOCKOPT               = 105 // { int setsockopt(int s, int level, int name, \
-	SYS_LISTEN                   = 106 // { int listen(int s, int backlog); }
-	SYS_GETTIMEOFDAY             = 116 // { int gettimeofday(struct timeval *tp, \
-	SYS_GETRUSAGE                = 117 // { int getrusage(int who, \
-	SYS_GETSOCKOPT               = 118 // { int getsockopt(int s, int level, int name, \
-	SYS_READV                    = 120 // { int readv(int fd, struct iovec *iovp, \
-	SYS_WRITEV                   = 121 // { int writev(int fd, struct iovec *iovp, \
-	SYS_SETTIMEOFDAY             = 122 // { int settimeofday(struct timeval *tv, \
-	SYS_FCHOWN                   = 123 // { int fchown(int fd, int uid, int gid); }
-	SYS_FCHMOD                   = 124 // { int fchmod(int fd, int mode); }
-	SYS_SETREUID                 = 126 // { int setreuid(int ruid, int euid); }
-	SYS_SETREGID                 = 127 // { int setregid(int rgid, int egid); }
-	SYS_RENAME                   = 128 // { int rename(char *from, char *to); }
-	SYS_FLOCK                    = 131 // { int flock(int fd, int how); }
-	SYS_MKFIFO                   = 132 // { int mkfifo(char *path, int mode); }
-	SYS_SENDTO                   = 133 // { int sendto(int s, caddr_t buf, size_t len, \
-	SYS_SHUTDOWN                 = 134 // { int shutdown(int s, int how); }
-	SYS_SOCKETPAIR               = 135 // { int socketpair(int domain, int type, \
-	SYS_MKDIR                    = 136 // { int mkdir(char *path, int mode); }
-	SYS_RMDIR                    = 137 // { int rmdir(char *path); }
-	SYS_UTIMES                   = 138 // { int utimes(char *path, \
-	SYS_ADJTIME                  = 140 // { int adjtime(struct timeval *delta, \
-	SYS_SETSID                   = 147 // { int setsid(void); }
-	SYS_QUOTACTL                 = 148 // { int quotactl(char *path, int cmd, int uid, \
-	SYS_LGETFH                   = 160 // { int lgetfh(char *fname, \
-	SYS_GETFH                    = 161 // { int getfh(char *fname, \
-	SYS_SYSARCH                  = 165 // { int sysarch(int op, char *parms); }
-	SYS_RTPRIO                   = 166 // { int rtprio(int function, pid_t pid, \
-	SYS_FREEBSD6_PREAD           = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \
-	SYS_FREEBSD6_PWRITE          = 174 // { ssize_t freebsd6_pwrite(int fd, \
-	SYS_SETFIB                   = 175 // { int setfib(int fibnum); }
-	SYS_NTP_ADJTIME              = 176 // { int ntp_adjtime(struct timex *tp); }
-	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
-	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
-	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
-	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
-	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
-	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, \
-	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, \
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, \
-	SYS_FREEBSD6_MMAP            = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
-	SYS_FREEBSD6_LSEEK           = 199 // { off_t freebsd6_lseek(int fd, int pad, \
-	SYS_FREEBSD6_TRUNCATE        = 200 // { int freebsd6_truncate(char *path, int pad, \
-	SYS_FREEBSD6_FTRUNCATE       = 201 // { int freebsd6_ftruncate(int fd, int pad, \
-	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, \
-	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
-	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
-	SYS_UNDELETE                 = 205 // { int undelete(char *path); }
-	SYS_FUTIMES                  = 206 // { int futimes(int fd, struct timeval *tptr); }
-	SYS_GETPGID                  = 207 // { int getpgid(pid_t pid); }
-	SYS_POLL                     = 209 // { int poll(struct pollfd *fds, u_int nfds, \
-	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, \
-	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( \
-	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, \
-	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, \
-	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
-	SYS_KTIMER_SETTIME           = 237 // { int ktimer_settime(int timerid, int flags, \
-	SYS_KTIMER_GETTIME           = 238 // { int ktimer_gettime(int timerid, struct \
-	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
-	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, \
-	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
-	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( \
-	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( \
-	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,\
-	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
-	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, \
-	SYS_RFORK                    = 251 // { int rfork(int flags); }
-	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, \
-	SYS_ISSETUGID                = 253 // { int issetugid(void); }
-	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
-	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, \
-	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
-	SYS_LUTIMES                  = 276 // { int lutimes(char *path, \
-	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
-	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
-	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
-	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \
-	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \
-	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, \
-	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, \
-	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
-	SYS_MODSTAT                  = 301 // { int modstat(int modid, \
-	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
-	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
-	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
-	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
-	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
-	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
-	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct \
-	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
-	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
-	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, \
-	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, \
-	SYS_YIELD                    = 321 // { int yield(void); }
-	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
-	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
-	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
-	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, \
-	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct \
-	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int \
-	SYS_SCHED_GETSCHEDULER       = 330 // { int sched_getscheduler (pid_t pid); }
-	SYS_SCHED_YIELD              = 331 // { int sched_yield (void); }
-	SYS_SCHED_GET_PRIORITY_MAX   = 332 // { int sched_get_priority_max (int policy); }
-	SYS_SCHED_GET_PRIORITY_MIN   = 333 // { int sched_get_priority_min (int policy); }
-	SYS_SCHED_RR_GET_INTERVAL    = 334 // { int sched_rr_get_interval (pid_t pid, \
-	SYS_UTRACE                   = 335 // { int utrace(const void *addr, size_t len); }
-	SYS_KLDSYM                   = 337 // { int kldsym(int fileid, int cmd, \
-	SYS_JAIL                     = 338 // { int jail(struct jail *jail); }
-	SYS_SIGPROCMASK              = 340 // { int sigprocmask(int how, \
-	SYS_SIGSUSPEND               = 341 // { int sigsuspend(const sigset_t *sigmask); }
-	SYS_SIGPENDING               = 343 // { int sigpending(sigset_t *set); }
-	SYS_SIGTIMEDWAIT             = 345 // { int sigtimedwait(const sigset_t *set, \
-	SYS_SIGWAITINFO              = 346 // { int sigwaitinfo(const sigset_t *set, \
-	SYS___ACL_GET_FILE           = 347 // { int __acl_get_file(const char *path, \
-	SYS___ACL_SET_FILE           = 348 // { int __acl_set_file(const char *path, \
-	SYS___ACL_GET_FD             = 349 // { int __acl_get_fd(int filedes, \
-	SYS___ACL_SET_FD             = 350 // { int __acl_set_fd(int filedes, \
-	SYS___ACL_DELETE_FILE        = 351 // { int __acl_delete_file(const char *path, \
-	SYS___ACL_DELETE_FD          = 352 // { int __acl_delete_fd(int filedes, \
-	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, \
-	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, \
-	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, \
-	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( \
-	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( \
-	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, \
-	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \
-	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \
-	SYS_KQUEUE                   = 362 // { int kqueue(void); }
-	SYS_KEVENT                   = 363 // { int kevent(int fd, \
-	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, \
-	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, \
-	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, \
-	SYS___SETUGID                = 374 // { int __setugid(int flag); }
-	SYS_EACCESS                  = 376 // { int eaccess(char *path, int amode); }
-	SYS_NMOUNT                   = 378 // { int nmount(struct iovec *iovp, \
-	SYS___MAC_GET_PROC           = 384 // { int __mac_get_proc(struct mac *mac_p); }
-	SYS___MAC_SET_PROC           = 385 // { int __mac_set_proc(struct mac *mac_p); }
-	SYS___MAC_GET_FD             = 386 // { int __mac_get_fd(int fd, \
-	SYS___MAC_GET_FILE           = 387 // { int __mac_get_file(const char *path_p, \
-	SYS___MAC_SET_FD             = 388 // { int __mac_set_fd(int fd, \
-	SYS___MAC_SET_FILE           = 389 // { int __mac_set_file(const char *path_p, \
-	SYS_KENV                     = 390 // { int kenv(int what, const char *name, \
-	SYS_LCHFLAGS                 = 391 // { int lchflags(const char *path, \
-	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, \
-	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, \
-	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, \
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, \
-	SYS_STATFS                   = 396 // { int statfs(char *path, \
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
-	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
-	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, \
-	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, \
-	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, \
-	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( \
-	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( \
-	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( \
-	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, \
-	SYS_SIGACTION                = 416 // { int sigaction(int sig, \
-	SYS_SIGRETURN                = 417 // { int sigreturn( \
-	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
-	SYS_SETCONTEXT               = 422 // { int setcontext( \
-	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, \
-	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
-	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, \
-	SYS___ACL_SET_LINK           = 426 // { int __acl_set_link(const char *path, \
-	SYS___ACL_DELETE_LINK        = 427 // { int __acl_delete_link(const char *path, \
-	SYS___ACL_ACLCHECK_LINK      = 428 // { int __acl_aclcheck_link(const char *path, \
-	SYS_SIGWAIT                  = 429 // { int sigwait(const sigset_t *set, \
-	SYS_THR_CREATE               = 430 // { int thr_create(ucontext_t *ctx, long *id, \
-	SYS_THR_EXIT                 = 431 // { void thr_exit(long *state); }
-	SYS_THR_SELF                 = 432 // { int thr_self(long *id); }
-	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
-	SYS__UMTX_LOCK               = 434 // { int _umtx_lock(struct umtx *umtx); }
-	SYS__UMTX_UNLOCK             = 435 // { int _umtx_unlock(struct umtx *umtx); }
-	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
-	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, \
-	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( \
-	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( \
-	SYS_THR_SUSPEND              = 442 // { int thr_suspend( \
-	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
-	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
-	SYS_AUDIT                    = 445 // { int audit(const void *record, \
-	SYS_AUDITON                  = 446 // { int auditon(int cmd, void *data, \
-	SYS_GETAUID                  = 447 // { int getauid(uid_t *auid); }
-	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
-	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
-	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
-	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( \
-	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( \
-	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
-	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, \
-	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, \
-	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
-	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
-	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
-	SYS_RTPRIO_THREAD            = 466 // { int rtprio_thread(int function, \
-	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
-	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
-	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
-	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
-	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, \
-	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, \
-	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, \
-	SYS_LSEEK                    = 478 // { off_t lseek(int fd, off_t offset, \
-	SYS_TRUNCATE                 = 479 // { int truncate(char *path, off_t length); }
-	SYS_FTRUNCATE                = 480 // { int ftruncate(int fd, off_t length); }
-	SYS_THR_KILL2                = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
-	SYS_SHM_OPEN                 = 482 // { int shm_open(const char *path, int flags, \
-	SYS_SHM_UNLINK               = 483 // { int shm_unlink(const char *path); }
-	SYS_CPUSET                   = 484 // { int cpuset(cpusetid_t *setid); }
-	SYS_CPUSET_SETID             = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \
-	SYS_CPUSET_GETID             = 486 // { int cpuset_getid(cpulevel_t level, \
-	SYS_CPUSET_GETAFFINITY       = 487 // { int cpuset_getaffinity(cpulevel_t level, \
-	SYS_CPUSET_SETAFFINITY       = 488 // { int cpuset_setaffinity(cpulevel_t level, \
-	SYS_FACCESSAT                = 489 // { int faccessat(int fd, char *path, int amode, \
-	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
-	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, \
-	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, \
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, \
-	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, \
-	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, \
-	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
-	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, \
-	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, \
-	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, \
-	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, \
-	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, \
-	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
-	SYS_POSIX_OPENPT             = 504 // { int posix_openpt(int flags); }
-	SYS_JAIL_GET                 = 506 // { int jail_get(struct iovec *iovp, \
-	SYS_JAIL_SET                 = 507 // { int jail_set(struct iovec *iovp, \
-	SYS_JAIL_REMOVE              = 508 // { int jail_remove(int jid); }
-	SYS_CLOSEFROM                = 509 // { int closefrom(int lowfd); }
-	SYS_LPATHCONF                = 513 // { int lpathconf(char *path, int name); }
-	SYS_CAP_NEW                  = 514 // { int cap_new(int fd, uint64_t rights); }
-	SYS_CAP_GETRIGHTS            = 515 // { int cap_getrights(int fd, \
-	SYS_CAP_ENTER                = 516 // { int cap_enter(void); }
-	SYS_CAP_GETMODE              = 517 // { int cap_getmode(u_int *modep); }
-	SYS_PDFORK                   = 518 // { int pdfork(int *fdp, int flags); }
-	SYS_PDKILL                   = 519 // { int pdkill(int fd, int signum); }
-	SYS_PDGETPID                 = 520 // { int pdgetpid(int fd, pid_t *pidp); }
-	SYS_PSELECT                  = 522 // { int pselect(int nd, fd_set *in, \
-	SYS_GETLOGINCLASS            = 523 // { int getloginclass(char *namebuf, \
-	SYS_SETLOGINCLASS            = 524 // { int setloginclass(const char *namebuf); }
-	SYS_RCTL_GET_RACCT           = 525 // { int rctl_get_racct(const void *inbufp, \
-	SYS_RCTL_GET_RULES           = 526 // { int rctl_get_rules(const void *inbufp, \
-	SYS_RCTL_GET_LIMITS          = 527 // { int rctl_get_limits(const void *inbufp, \
-	SYS_RCTL_ADD_RULE            = 528 // { int rctl_add_rule(const void *inbufp, \
-	SYS_RCTL_REMOVE_RULE         = 529 // { int rctl_remove_rule(const void *inbufp, \
-	SYS_POSIX_FALLOCATE          = 530 // { int posix_fallocate(int fd, \
-	SYS_POSIX_FADVISE            = 531 // { int posix_fadvise(int fd, off_t offset, \
-	SYS_WAIT6                    = 532 // { int wait6(idtype_t idtype, id_t id, \
-	SYS_BINDAT                   = 538 // { int bindat(int fd, int s, caddr_t name, \
-	SYS_CONNECTAT                = 539 // { int connectat(int fd, int s, caddr_t name, \
-	SYS_CHFLAGSAT                = 540 // { int chflagsat(int fd, const char *path, \
-	SYS_ACCEPT4                  = 541 // { int accept4(int s, \
-	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
-	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
-	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \
+	SYS_EXIT                   = 1   // { void sys_exit(int rval); } exit \
+	SYS_FORK                   = 2   // { int fork(void); }
+	SYS_READ                   = 3   // { ssize_t read(int fd, void *buf, \
+	SYS_WRITE                  = 4   // { ssize_t write(int fd, const void *buf, \
+	SYS_OPEN                   = 5   // { int open(char *path, int flags, int mode); }
+	SYS_CLOSE                  = 6   // { int close(int fd); }
+	SYS_WAIT4                  = 7   // { int wait4(int pid, int *status, \
+	SYS_LINK                   = 9   // { int link(char *path, char *link); }
+	SYS_UNLINK                 = 10  // { int unlink(char *path); }
+	SYS_CHDIR                  = 12  // { int chdir(char *path); }
+	SYS_FCHDIR                 = 13  // { int fchdir(int fd); }
+	SYS_MKNOD                  = 14  // { int mknod(char *path, int mode, int dev); }
+	SYS_CHMOD                  = 15  // { int chmod(char *path, int mode); }
+	SYS_CHOWN                  = 16  // { int chown(char *path, int uid, int gid); }
+	SYS_OBREAK                 = 17  // { int obreak(char *nsize); } break \
+	SYS_GETPID                 = 20  // { pid_t getpid(void); }
+	SYS_MOUNT                  = 21  // { int mount(char *type, char *path, \
+	SYS_UNMOUNT                = 22  // { int unmount(char *path, int flags); }
+	SYS_SETUID                 = 23  // { int setuid(uid_t uid); }
+	SYS_GETUID                 = 24  // { uid_t getuid(void); }
+	SYS_GETEUID                = 25  // { uid_t geteuid(void); }
+	SYS_PTRACE                 = 26  // { int ptrace(int req, pid_t pid, \
+	SYS_RECVMSG                = 27  // { int recvmsg(int s, struct msghdr *msg, \
+	SYS_SENDMSG                = 28  // { int sendmsg(int s, struct msghdr *msg, \
+	SYS_RECVFROM               = 29  // { int recvfrom(int s, caddr_t buf, \
+	SYS_ACCEPT                 = 30  // { int accept(int s, \
+	SYS_GETPEERNAME            = 31  // { int getpeername(int fdes, \
+	SYS_GETSOCKNAME            = 32  // { int getsockname(int fdes, \
+	SYS_ACCESS                 = 33  // { int access(char *path, int amode); }
+	SYS_CHFLAGS                = 34  // { int chflags(const char *path, u_long flags); }
+	SYS_FCHFLAGS               = 35  // { int fchflags(int fd, u_long flags); }
+	SYS_SYNC                   = 36  // { int sync(void); }
+	SYS_KILL                   = 37  // { int kill(int pid, int signum); }
+	SYS_GETPPID                = 39  // { pid_t getppid(void); }
+	SYS_DUP                    = 41  // { int dup(u_int fd); }
+	SYS_PIPE                   = 42  // { int pipe(void); }
+	SYS_GETEGID                = 43  // { gid_t getegid(void); }
+	SYS_PROFIL                 = 44  // { int profil(caddr_t samples, size_t size, \
+	SYS_KTRACE                 = 45  // { int ktrace(const char *fname, int ops, \
+	SYS_GETGID                 = 47  // { gid_t getgid(void); }
+	SYS_GETLOGIN               = 49  // { int getlogin(char *namebuf, u_int \
+	SYS_SETLOGIN               = 50  // { int setlogin(char *namebuf); }
+	SYS_ACCT                   = 51  // { int acct(char *path); }
+	SYS_SIGALTSTACK            = 53  // { int sigaltstack(stack_t *ss, \
+	SYS_IOCTL                  = 54  // { int ioctl(int fd, u_long com, \
+	SYS_REBOOT                 = 55  // { int reboot(int opt); }
+	SYS_REVOKE                 = 56  // { int revoke(char *path); }
+	SYS_SYMLINK                = 57  // { int symlink(char *path, char *link); }
+	SYS_READLINK               = 58  // { ssize_t readlink(char *path, char *buf, \
+	SYS_EXECVE                 = 59  // { int execve(char *fname, char **argv, \
+	SYS_UMASK                  = 60  // { int umask(int newmask); } umask umask_args \
+	SYS_CHROOT                 = 61  // { int chroot(char *path); }
+	SYS_MSYNC                  = 65  // { int msync(void *addr, size_t len, \
+	SYS_VFORK                  = 66  // { int vfork(void); }
+	SYS_SBRK                   = 69  // { int sbrk(int incr); }
+	SYS_SSTK                   = 70  // { int sstk(int incr); }
+	SYS_OVADVISE               = 72  // { int ovadvise(int anom); } vadvise \
+	SYS_MUNMAP                 = 73  // { int munmap(void *addr, size_t len); }
+	SYS_MPROTECT               = 74  // { int mprotect(const void *addr, size_t len, \
+	SYS_MADVISE                = 75  // { int madvise(void *addr, size_t len, \
+	SYS_MINCORE                = 78  // { int mincore(const void *addr, size_t len, \
+	SYS_GETGROUPS              = 79  // { int getgroups(u_int gidsetsize, \
+	SYS_SETGROUPS              = 80  // { int setgroups(u_int gidsetsize, \
+	SYS_GETPGRP                = 81  // { int getpgrp(void); }
+	SYS_SETPGID                = 82  // { int setpgid(int pid, int pgid); }
+	SYS_SETITIMER              = 83  // { int setitimer(u_int which, struct \
+	SYS_SWAPON                 = 85  // { int swapon(char *name); }
+	SYS_GETITIMER              = 86  // { int getitimer(u_int which, \
+	SYS_GETDTABLESIZE          = 89  // { int getdtablesize(void); }
+	SYS_DUP2                   = 90  // { int dup2(u_int from, u_int to); }
+	SYS_FCNTL                  = 92  // { int fcntl(int fd, int cmd, long arg); }
+	SYS_SELECT                 = 93  // { int select(int nd, fd_set *in, fd_set *ou, \
+	SYS_FSYNC                  = 95  // { int fsync(int fd); }
+	SYS_SETPRIORITY            = 96  // { int setpriority(int which, int who, \
+	SYS_SOCKET                 = 97  // { int socket(int domain, int type, \
+	SYS_CONNECT                = 98  // { int connect(int s, caddr_t name, \
+	SYS_GETPRIORITY            = 100 // { int getpriority(int which, int who); }
+	SYS_BIND                   = 104 // { int bind(int s, caddr_t name, \
+	SYS_SETSOCKOPT             = 105 // { int setsockopt(int s, int level, int name, \
+	SYS_LISTEN                 = 106 // { int listen(int s, int backlog); }
+	SYS_GETTIMEOFDAY           = 116 // { int gettimeofday(struct timeval *tp, \
+	SYS_GETRUSAGE              = 117 // { int getrusage(int who, \
+	SYS_GETSOCKOPT             = 118 // { int getsockopt(int s, int level, int name, \
+	SYS_READV                  = 120 // { int readv(int fd, struct iovec *iovp, \
+	SYS_WRITEV                 = 121 // { int writev(int fd, struct iovec *iovp, \
+	SYS_SETTIMEOFDAY           = 122 // { int settimeofday(struct timeval *tv, \
+	SYS_FCHOWN                 = 123 // { int fchown(int fd, int uid, int gid); }
+	SYS_FCHMOD                 = 124 // { int fchmod(int fd, int mode); }
+	SYS_SETREUID               = 126 // { int setreuid(int ruid, int euid); }
+	SYS_SETREGID               = 127 // { int setregid(int rgid, int egid); }
+	SYS_RENAME                 = 128 // { int rename(char *from, char *to); }
+	SYS_FLOCK                  = 131 // { int flock(int fd, int how); }
+	SYS_MKFIFO                 = 132 // { int mkfifo(char *path, int mode); }
+	SYS_SENDTO                 = 133 // { int sendto(int s, caddr_t buf, size_t len, \
+	SYS_SHUTDOWN               = 134 // { int shutdown(int s, int how); }
+	SYS_SOCKETPAIR             = 135 // { int socketpair(int domain, int type, \
+	SYS_MKDIR                  = 136 // { int mkdir(char *path, int mode); }
+	SYS_RMDIR                  = 137 // { int rmdir(char *path); }
+	SYS_UTIMES                 = 138 // { int utimes(char *path, \
+	SYS_ADJTIME                = 140 // { int adjtime(struct timeval *delta, \
+	SYS_SETSID                 = 147 // { int setsid(void); }
+	SYS_QUOTACTL               = 148 // { int quotactl(char *path, int cmd, int uid, \
+	SYS_LGETFH                 = 160 // { int lgetfh(char *fname, \
+	SYS_GETFH                  = 161 // { int getfh(char *fname, \
+	SYS_SYSARCH                = 165 // { int sysarch(int op, char *parms); }
+	SYS_RTPRIO                 = 166 // { int rtprio(int function, pid_t pid, \
+	SYS_FREEBSD6_PREAD         = 173 // { ssize_t freebsd6_pread(int fd, void *buf, \
+	SYS_FREEBSD6_PWRITE        = 174 // { ssize_t freebsd6_pwrite(int fd, \
+	SYS_SETFIB                 = 175 // { int setfib(int fibnum); }
+	SYS_NTP_ADJTIME            = 176 // { int ntp_adjtime(struct timex *tp); }
+	SYS_SETGID                 = 181 // { int setgid(gid_t gid); }
+	SYS_SETEGID                = 182 // { int setegid(gid_t egid); }
+	SYS_SETEUID                = 183 // { int seteuid(uid_t euid); }
+	SYS_STAT                   = 188 // { int stat(char *path, struct stat *ub); }
+	SYS_FSTAT                  = 189 // { int fstat(int fd, struct stat *sb); }
+	SYS_LSTAT                  = 190 // { int lstat(char *path, struct stat *ub); }
+	SYS_PATHCONF               = 191 // { int pathconf(char *path, int name); }
+	SYS_FPATHCONF              = 192 // { int fpathconf(int fd, int name); }
+	SYS_GETRLIMIT              = 194 // { int getrlimit(u_int which, \
+	SYS_SETRLIMIT              = 195 // { int setrlimit(u_int which, \
+	SYS_GETDIRENTRIES          = 196 // { int getdirentries(int fd, char *buf, \
+	SYS_FREEBSD6_MMAP          = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
+	SYS_FREEBSD6_LSEEK         = 199 // { off_t freebsd6_lseek(int fd, int pad, \
+	SYS_FREEBSD6_TRUNCATE      = 200 // { int freebsd6_truncate(char *path, int pad, \
+	SYS_FREEBSD6_FTRUNCATE     = 201 // { int freebsd6_ftruncate(int fd, int pad, \
+	SYS___SYSCTL               = 202 // { int __sysctl(int *name, u_int namelen, \
+	SYS_MLOCK                  = 203 // { int mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK                = 204 // { int munlock(const void *addr, size_t len); }
+	SYS_UNDELETE               = 205 // { int undelete(char *path); }
+	SYS_FUTIMES                = 206 // { int futimes(int fd, struct timeval *tptr); }
+	SYS_GETPGID                = 207 // { int getpgid(pid_t pid); }
+	SYS_POLL                   = 209 // { int poll(struct pollfd *fds, u_int nfds, \
+	SYS_CLOCK_GETTIME          = 232 // { int clock_gettime(clockid_t clock_id, \
+	SYS_CLOCK_SETTIME          = 233 // { int clock_settime( \
+	SYS_CLOCK_GETRES           = 234 // { int clock_getres(clockid_t clock_id, \
+	SYS_KTIMER_CREATE          = 235 // { int ktimer_create(clockid_t clock_id, \
+	SYS_KTIMER_DELETE          = 236 // { int ktimer_delete(int timerid); }
+	SYS_KTIMER_SETTIME         = 237 // { int ktimer_settime(int timerid, int flags, \
+	SYS_KTIMER_GETTIME         = 238 // { int ktimer_gettime(int timerid, struct \
+	SYS_KTIMER_GETOVERRUN      = 239 // { int ktimer_getoverrun(int timerid); }
+	SYS_NANOSLEEP              = 240 // { int nanosleep(const struct timespec *rqtp, \
+	SYS_FFCLOCK_GETCOUNTER     = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
+	SYS_FFCLOCK_SETESTIMATE    = 242 // { int ffclock_setestimate( \
+	SYS_FFCLOCK_GETESTIMATE    = 243 // { int ffclock_getestimate( \
+	SYS_CLOCK_GETCPUCLOCKID2   = 247 // { int clock_getcpuclockid2(id_t id,\
+	SYS_NTP_GETTIME            = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
+	SYS_MINHERIT               = 250 // { int minherit(void *addr, size_t len, \
+	SYS_RFORK                  = 251 // { int rfork(int flags); }
+	SYS_OPENBSD_POLL           = 252 // { int openbsd_poll(struct pollfd *fds, \
+	SYS_ISSETUGID              = 253 // { int issetugid(void); }
+	SYS_LCHOWN                 = 254 // { int lchown(char *path, int uid, int gid); }
+	SYS_GETDENTS               = 272 // { int getdents(int fd, char *buf, \
+	SYS_LCHMOD                 = 274 // { int lchmod(char *path, mode_t mode); }
+	SYS_LUTIMES                = 276 // { int lutimes(char *path, \
+	SYS_NSTAT                  = 278 // { int nstat(char *path, struct nstat *ub); }
+	SYS_NFSTAT                 = 279 // { int nfstat(int fd, struct nstat *sb); }
+	SYS_NLSTAT                 = 280 // { int nlstat(char *path, struct nstat *ub); }
+	SYS_PREADV                 = 289 // { ssize_t preadv(int fd, struct iovec *iovp, \
+	SYS_PWRITEV                = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, \
+	SYS_FHOPEN                 = 298 // { int fhopen(const struct fhandle *u_fhp, \
+	SYS_FHSTAT                 = 299 // { int fhstat(const struct fhandle *u_fhp, \
+	SYS_MODNEXT                = 300 // { int modnext(int modid); }
+	SYS_MODSTAT                = 301 // { int modstat(int modid, \
+	SYS_MODFNEXT               = 302 // { int modfnext(int modid); }
+	SYS_MODFIND                = 303 // { int modfind(const char *name); }
+	SYS_KLDLOAD                = 304 // { int kldload(const char *file); }
+	SYS_KLDUNLOAD              = 305 // { int kldunload(int fileid); }
+	SYS_KLDFIND                = 306 // { int kldfind(const char *file); }
+	SYS_KLDNEXT                = 307 // { int kldnext(int fileid); }
+	SYS_KLDSTAT                = 308 // { int kldstat(int fileid, struct \
+	SYS_KLDFIRSTMOD            = 309 // { int kldfirstmod(int fileid); }
+	SYS_GETSID                 = 310 // { int getsid(pid_t pid); }
+	SYS_SETRESUID              = 311 // { int setresuid(uid_t ruid, uid_t euid, \
+	SYS_SETRESGID              = 312 // { int setresgid(gid_t rgid, gid_t egid, \
+	SYS_YIELD                  = 321 // { int yield(void); }
+	SYS_MLOCKALL               = 324 // { int mlockall(int how); }
+	SYS_MUNLOCKALL             = 325 // { int munlockall(void); }
+	SYS___GETCWD               = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS_SCHED_SETPARAM         = 327 // { int sched_setparam (pid_t pid, \
+	SYS_SCHED_GETPARAM         = 328 // { int sched_getparam (pid_t pid, struct \
+	SYS_SCHED_SETSCHEDULER     = 329 // { int sched_setscheduler (pid_t pid, int \
+	SYS_SCHED_GETSCHEDULER     = 330 // { int sched_getscheduler (pid_t pid); }
+	SYS_SCHED_YIELD            = 331 // { int sched_yield (void); }
+	SYS_SCHED_GET_PRIORITY_MAX = 332 // { int sched_get_priority_max (int policy); }
+	SYS_SCHED_GET_PRIORITY_MIN = 333 // { int sched_get_priority_min (int policy); }
+	SYS_SCHED_RR_GET_INTERVAL  = 334 // { int sched_rr_get_interval (pid_t pid, \
+	SYS_UTRACE                 = 335 // { int utrace(const void *addr, size_t len); }
+	SYS_KLDSYM                 = 337 // { int kldsym(int fileid, int cmd, \
+	SYS_JAIL                   = 338 // { int jail(struct jail *jail); }
+	SYS_SIGPROCMASK            = 340 // { int sigprocmask(int how, \
+	SYS_SIGSUSPEND             = 341 // { int sigsuspend(const sigset_t *sigmask); }
+	SYS_SIGPENDING             = 343 // { int sigpending(sigset_t *set); }
+	SYS_SIGTIMEDWAIT           = 345 // { int sigtimedwait(const sigset_t *set, \
+	SYS_SIGWAITINFO            = 346 // { int sigwaitinfo(const sigset_t *set, \
+	SYS___ACL_GET_FILE         = 347 // { int __acl_get_file(const char *path, \
+	SYS___ACL_SET_FILE         = 348 // { int __acl_set_file(const char *path, \
+	SYS___ACL_GET_FD           = 349 // { int __acl_get_fd(int filedes, \
+	SYS___ACL_SET_FD           = 350 // { int __acl_set_fd(int filedes, \
+	SYS___ACL_DELETE_FILE      = 351 // { int __acl_delete_file(const char *path, \
+	SYS___ACL_DELETE_FD        = 352 // { int __acl_delete_fd(int filedes, \
+	SYS___ACL_ACLCHECK_FILE    = 353 // { int __acl_aclcheck_file(const char *path, \
+	SYS___ACL_ACLCHECK_FD      = 354 // { int __acl_aclcheck_fd(int filedes, \
+	SYS_EXTATTRCTL             = 355 // { int extattrctl(const char *path, int cmd, \
+	SYS_EXTATTR_SET_FILE       = 356 // { ssize_t extattr_set_file( \
+	SYS_EXTATTR_GET_FILE       = 357 // { ssize_t extattr_get_file( \
+	SYS_EXTATTR_DELETE_FILE    = 358 // { int extattr_delete_file(const char *path, \
+	SYS_GETRESUID              = 360 // { int getresuid(uid_t *ruid, uid_t *euid, \
+	SYS_GETRESGID              = 361 // { int getresgid(gid_t *rgid, gid_t *egid, \
+	SYS_KQUEUE                 = 362 // { int kqueue(void); }
+	SYS_KEVENT                 = 363 // { int kevent(int fd, \
+	SYS_EXTATTR_SET_FD         = 371 // { ssize_t extattr_set_fd(int fd, \
+	SYS_EXTATTR_GET_FD         = 372 // { ssize_t extattr_get_fd(int fd, \
+	SYS_EXTATTR_DELETE_FD      = 373 // { int extattr_delete_fd(int fd, \
+	SYS___SETUGID              = 374 // { int __setugid(int flag); }
+	SYS_EACCESS                = 376 // { int eaccess(char *path, int amode); }
+	SYS_NMOUNT                 = 378 // { int nmount(struct iovec *iovp, \
+	SYS___MAC_GET_PROC         = 384 // { int __mac_get_proc(struct mac *mac_p); }
+	SYS___MAC_SET_PROC         = 385 // { int __mac_set_proc(struct mac *mac_p); }
+	SYS___MAC_GET_FD           = 386 // { int __mac_get_fd(int fd, \
+	SYS___MAC_GET_FILE         = 387 // { int __mac_get_file(const char *path_p, \
+	SYS___MAC_SET_FD           = 388 // { int __mac_set_fd(int fd, \
+	SYS___MAC_SET_FILE         = 389 // { int __mac_set_file(const char *path_p, \
+	SYS_KENV                   = 390 // { int kenv(int what, const char *name, \
+	SYS_LCHFLAGS               = 391 // { int lchflags(const char *path, \
+	SYS_UUIDGEN                = 392 // { int uuidgen(struct uuid *store, \
+	SYS_SENDFILE               = 393 // { int sendfile(int fd, int s, off_t offset, \
+	SYS_MAC_SYSCALL            = 394 // { int mac_syscall(const char *policy, \
+	SYS_GETFSSTAT              = 395 // { int getfsstat(struct statfs *buf, \
+	SYS_STATFS                 = 396 // { int statfs(char *path, \
+	SYS_FSTATFS                = 397 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_FHSTATFS               = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
+	SYS___MAC_GET_PID          = 409 // { int __mac_get_pid(pid_t pid, \
+	SYS___MAC_GET_LINK         = 410 // { int __mac_get_link(const char *path_p, \
+	SYS___MAC_SET_LINK         = 411 // { int __mac_set_link(const char *path_p, \
+	SYS_EXTATTR_SET_LINK       = 412 // { ssize_t extattr_set_link( \
+	SYS_EXTATTR_GET_LINK       = 413 // { ssize_t extattr_get_link( \
+	SYS_EXTATTR_DELETE_LINK    = 414 // { int extattr_delete_link( \
+	SYS___MAC_EXECVE           = 415 // { int __mac_execve(char *fname, char **argv, \
+	SYS_SIGACTION              = 416 // { int sigaction(int sig, \
+	SYS_SIGRETURN              = 417 // { int sigreturn( \
+	SYS_GETCONTEXT             = 421 // { int getcontext(struct __ucontext *ucp); }
+	SYS_SETCONTEXT             = 422 // { int setcontext( \
+	SYS_SWAPCONTEXT            = 423 // { int swapcontext(struct __ucontext *oucp, \
+	SYS_SWAPOFF                = 424 // { int swapoff(const char *name); }
+	SYS___ACL_GET_LINK         = 425 // { int __acl_get_link(const char *path, \
+	SYS___ACL_SET_LINK         = 426 // { int __acl_set_link(const char *path, \
+	SYS___ACL_DELETE_LINK      = 427 // { int __acl_delete_link(const char *path, \
+	SYS___ACL_ACLCHECK_LINK    = 428 // { int __acl_aclcheck_link(const char *path, \
+	SYS_SIGWAIT                = 429 // { int sigwait(const sigset_t *set, \
+	SYS_THR_CREATE             = 430 // { int thr_create(ucontext_t *ctx, long *id, \
+	SYS_THR_EXIT               = 431 // { void thr_exit(long *state); }
+	SYS_THR_SELF               = 432 // { int thr_self(long *id); }
+	SYS_THR_KILL               = 433 // { int thr_kill(long id, int sig); }
+	SYS__UMTX_LOCK             = 434 // { int _umtx_lock(struct umtx *umtx); }
+	SYS__UMTX_UNLOCK           = 435 // { int _umtx_unlock(struct umtx *umtx); }
+	SYS_JAIL_ATTACH            = 436 // { int jail_attach(int jid); }
+	SYS_EXTATTR_LIST_FD        = 437 // { ssize_t extattr_list_fd(int fd, \
+	SYS_EXTATTR_LIST_FILE      = 438 // { ssize_t extattr_list_file( \
+	SYS_EXTATTR_LIST_LINK      = 439 // { ssize_t extattr_list_link( \
+	SYS_THR_SUSPEND            = 442 // { int thr_suspend( \
+	SYS_THR_WAKE               = 443 // { int thr_wake(long id); }
+	SYS_KLDUNLOADF             = 444 // { int kldunloadf(int fileid, int flags); }
+	SYS_AUDIT                  = 445 // { int audit(const void *record, \
+	SYS_AUDITON                = 446 // { int auditon(int cmd, void *data, \
+	SYS_GETAUID                = 447 // { int getauid(uid_t *auid); }
+	SYS_SETAUID                = 448 // { int setauid(uid_t *auid); }
+	SYS_GETAUDIT               = 449 // { int getaudit(struct auditinfo *auditinfo); }
+	SYS_SETAUDIT               = 450 // { int setaudit(struct auditinfo *auditinfo); }
+	SYS_GETAUDIT_ADDR          = 451 // { int getaudit_addr( \
+	SYS_SETAUDIT_ADDR          = 452 // { int setaudit_addr( \
+	SYS_AUDITCTL               = 453 // { int auditctl(char *path); }
+	SYS__UMTX_OP               = 454 // { int _umtx_op(void *obj, int op, \
+	SYS_THR_NEW                = 455 // { int thr_new(struct thr_param *param, \
+	SYS_SIGQUEUE               = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
+	SYS_ABORT2                 = 463 // { int abort2(const char *why, int nargs, void **args); }
+	SYS_THR_SET_NAME           = 464 // { int thr_set_name(long id, const char *name); }
+	SYS_RTPRIO_THREAD          = 466 // { int rtprio_thread(int function, \
+	SYS_PREAD                  = 475 // { ssize_t pread(int fd, void *buf, \
+	SYS_PWRITE                 = 476 // { ssize_t pwrite(int fd, const void *buf, \
+	SYS_MMAP                   = 477 // { caddr_t mmap(caddr_t addr, size_t len, \
+	SYS_LSEEK                  = 478 // { off_t lseek(int fd, off_t offset, \
+	SYS_TRUNCATE               = 479 // { int truncate(char *path, off_t length); }
+	SYS_FTRUNCATE              = 480 // { int ftruncate(int fd, off_t length); }
+	SYS_THR_KILL2              = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
+	SYS_SHM_OPEN               = 482 // { int shm_open(const char *path, int flags, \
+	SYS_SHM_UNLINK             = 483 // { int shm_unlink(const char *path); }
+	SYS_CPUSET                 = 484 // { int cpuset(cpusetid_t *setid); }
+	SYS_CPUSET_SETID           = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, \
+	SYS_CPUSET_GETID           = 486 // { int cpuset_getid(cpulevel_t level, \
+	SYS_CPUSET_GETAFFINITY     = 487 // { int cpuset_getaffinity(cpulevel_t level, \
+	SYS_CPUSET_SETAFFINITY     = 488 // { int cpuset_setaffinity(cpulevel_t level, \
+	SYS_FACCESSAT              = 489 // { int faccessat(int fd, char *path, int amode, \
+	SYS_FCHMODAT               = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
+	SYS_FCHOWNAT               = 491 // { int fchownat(int fd, char *path, uid_t uid, \
+	SYS_FEXECVE                = 492 // { int fexecve(int fd, char **argv, \
+	SYS_FSTATAT                = 493 // { int fstatat(int fd, char *path, \
+	SYS_FUTIMESAT              = 494 // { int futimesat(int fd, char *path, \
+	SYS_LINKAT                 = 495 // { int linkat(int fd1, char *path1, int fd2, \
+	SYS_MKDIRAT                = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
+	SYS_MKFIFOAT               = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
+	SYS_MKNODAT                = 498 // { int mknodat(int fd, char *path, mode_t mode, \
+	SYS_OPENAT                 = 499 // { int openat(int fd, char *path, int flag, \
+	SYS_READLINKAT             = 500 // { int readlinkat(int fd, char *path, char *buf, \
+	SYS_RENAMEAT               = 501 // { int renameat(int oldfd, char *old, int newfd, \
+	SYS_SYMLINKAT              = 502 // { int symlinkat(char *path1, int fd, \
+	SYS_UNLINKAT               = 503 // { int unlinkat(int fd, char *path, int flag); }
+	SYS_POSIX_OPENPT           = 504 // { int posix_openpt(int flags); }
+	SYS_JAIL_GET               = 506 // { int jail_get(struct iovec *iovp, \
+	SYS_JAIL_SET               = 507 // { int jail_set(struct iovec *iovp, \
+	SYS_JAIL_REMOVE            = 508 // { int jail_remove(int jid); }
+	SYS_CLOSEFROM              = 509 // { int closefrom(int lowfd); }
+	SYS_LPATHCONF              = 513 // { int lpathconf(char *path, int name); }
+	SYS___CAP_RIGHTS_GET       = 515 // { int __cap_rights_get(int version, \
+	SYS_CAP_ENTER              = 516 // { int cap_enter(void); }
+	SYS_CAP_GETMODE            = 517 // { int cap_getmode(u_int *modep); }
+	SYS_PDFORK                 = 518 // { int pdfork(int *fdp, int flags); }
+	SYS_PDKILL                 = 519 // { int pdkill(int fd, int signum); }
+	SYS_PDGETPID               = 520 // { int pdgetpid(int fd, pid_t *pidp); }
+	SYS_PSELECT                = 522 // { int pselect(int nd, fd_set *in, \
+	SYS_GETLOGINCLASS          = 523 // { int getloginclass(char *namebuf, \
+	SYS_SETLOGINCLASS          = 524 // { int setloginclass(const char *namebuf); }
+	SYS_RCTL_GET_RACCT         = 525 // { int rctl_get_racct(const void *inbufp, \
+	SYS_RCTL_GET_RULES         = 526 // { int rctl_get_rules(const void *inbufp, \
+	SYS_RCTL_GET_LIMITS        = 527 // { int rctl_get_limits(const void *inbufp, \
+	SYS_RCTL_ADD_RULE          = 528 // { int rctl_add_rule(const void *inbufp, \
+	SYS_RCTL_REMOVE_RULE       = 529 // { int rctl_remove_rule(const void *inbufp, \
+	SYS_POSIX_FALLOCATE        = 530 // { int posix_fallocate(int fd, \
+	SYS_POSIX_FADVISE          = 531 // { int posix_fadvise(int fd, off_t offset, \
+	SYS_WAIT6                  = 532 // { int wait6(idtype_t idtype, id_t id, \
+	SYS_CAP_RIGHTS_LIMIT       = 533 // { int cap_rights_limit(int fd, \
+	SYS_CAP_IOCTLS_LIMIT       = 534 // { int cap_ioctls_limit(int fd, \
+	SYS_CAP_IOCTLS_GET         = 535 // { ssize_t cap_ioctls_get(int fd, \
+	SYS_CAP_FCNTLS_LIMIT       = 536 // { int cap_fcntls_limit(int fd, \
+	SYS_CAP_FCNTLS_GET         = 537 // { int cap_fcntls_get(int fd, \
+	SYS_BINDAT                 = 538 // { int bindat(int fd, int s, caddr_t name, \
+	SYS_CONNECTAT              = 539 // { int connectat(int fd, int s, caddr_t name, \
+	SYS_CHFLAGSAT              = 540 // { int chflagsat(int fd, const char *path, \
+	SYS_ACCEPT4                = 541 // { int accept4(int s, \
+	SYS_PIPE2                  = 542 // { int pipe2(int *fildes, int flags); }
+	SYS_PROCCTL                = 544 // { int procctl(idtype_t idtype, id_t id, \
+	SYS_PPOLL                  = 545 // { int ppoll(struct pollfd *fds, u_int nfds, \
+	SYS_FUTIMENS               = 546 // { int futimens(int fd, \
+	SYS_UTIMENSAT              = 547 // { int utimensat(int fd, \
 )
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go
index f60d8f9..8afda9c 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_386.go
@@ -134,6 +134,7 @@
 	SYS_MINHERIT             = 273 // { int|sys||minherit(void *addr, size_t len, int inherit); }
 	SYS_LCHMOD               = 274 // { int|sys||lchmod(const char *path, mode_t mode); }
 	SYS_LCHOWN               = 275 // { int|sys||lchown(const char *path, uid_t uid, gid_t gid); }
+	SYS_MSYNC                = 277 // { int|sys|13|msync(void *addr, size_t len, int flags); }
 	SYS___POSIX_CHOWN        = 283 // { int|sys||__posix_chown(const char *path, uid_t uid, gid_t gid); }
 	SYS___POSIX_FCHOWN       = 284 // { int|sys||__posix_fchown(int fd, uid_t uid, gid_t gid); }
 	SYS___POSIX_LCHOWN       = 285 // { int|sys||__posix_lchown(const char *path, uid_t uid, gid_t gid); }
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go
index 48a91d4..aea8dbe 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_amd64.go
@@ -134,6 +134,7 @@
 	SYS_MINHERIT             = 273 // { int|sys||minherit(void *addr, size_t len, int inherit); }
 	SYS_LCHMOD               = 274 // { int|sys||lchmod(const char *path, mode_t mode); }
 	SYS_LCHOWN               = 275 // { int|sys||lchown(const char *path, uid_t uid, gid_t gid); }
+	SYS_MSYNC                = 277 // { int|sys|13|msync(void *addr, size_t len, int flags); }
 	SYS___POSIX_CHOWN        = 283 // { int|sys||__posix_chown(const char *path, uid_t uid, gid_t gid); }
 	SYS___POSIX_FCHOWN       = 284 // { int|sys||__posix_fchown(int fd, uid_t uid, gid_t gid); }
 	SYS___POSIX_LCHOWN       = 285 // { int|sys||__posix_lchown(const char *path, uid_t uid, gid_t gid); }
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go
index 612ba66..c6158a7 100644
--- a/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsysnum_netbsd_arm.go
@@ -134,6 +134,7 @@
 	SYS_MINHERIT             = 273 // { int|sys||minherit(void *addr, size_t len, int inherit); }
 	SYS_LCHMOD               = 274 // { int|sys||lchmod(const char *path, mode_t mode); }
 	SYS_LCHOWN               = 275 // { int|sys||lchown(const char *path, uid_t uid, gid_t gid); }
+	SYS_MSYNC                = 277 // { int|sys|13|msync(void *addr, size_t len, int flags); }
 	SYS___POSIX_CHOWN        = 283 // { int|sys||__posix_chown(const char *path, uid_t uid, gid_t gid); }
 	SYS___POSIX_FCHOWN       = 284 // { int|sys||__posix_fchown(int fd, uid_t uid, gid_t gid); }
 	SYS___POSIX_LCHOWN       = 285 // { int|sys||__posix_lchown(const char *path, uid_t uid, gid_t gid); }
diff --git a/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
new file mode 100644
index 0000000..32653e5
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
@@ -0,0 +1,213 @@
+// mksysnum_openbsd.pl
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+// +build arm,openbsd
+
+package unix
+
+const (
+	SYS_EXIT           = 1   // { void sys_exit(int rval); }
+	SYS_FORK           = 2   // { int sys_fork(void); }
+	SYS_READ           = 3   // { ssize_t sys_read(int fd, void *buf, size_t nbyte); }
+	SYS_WRITE          = 4   // { ssize_t sys_write(int fd, const void *buf, \
+	SYS_OPEN           = 5   // { int sys_open(const char *path, \
+	SYS_CLOSE          = 6   // { int sys_close(int fd); }
+	SYS_GETENTROPY     = 7   // { int sys_getentropy(void *buf, size_t nbyte); }
+	SYS___TFORK        = 8   // { int sys___tfork(const struct __tfork *param, \
+	SYS_LINK           = 9   // { int sys_link(const char *path, const char *link); }
+	SYS_UNLINK         = 10  // { int sys_unlink(const char *path); }
+	SYS_WAIT4          = 11  // { pid_t sys_wait4(pid_t pid, int *status, \
+	SYS_CHDIR          = 12  // { int sys_chdir(const char *path); }
+	SYS_FCHDIR         = 13  // { int sys_fchdir(int fd); }
+	SYS_MKNOD          = 14  // { int sys_mknod(const char *path, mode_t mode, \
+	SYS_CHMOD          = 15  // { int sys_chmod(const char *path, mode_t mode); }
+	SYS_CHOWN          = 16  // { int sys_chown(const char *path, uid_t uid, \
+	SYS_OBREAK         = 17  // { int sys_obreak(char *nsize); } break
+	SYS_GETDTABLECOUNT = 18  // { int sys_getdtablecount(void); }
+	SYS_GETRUSAGE      = 19  // { int sys_getrusage(int who, \
+	SYS_GETPID         = 20  // { pid_t sys_getpid(void); }
+	SYS_MOUNT          = 21  // { int sys_mount(const char *type, const char *path, \
+	SYS_UNMOUNT        = 22  // { int sys_unmount(const char *path, int flags); }
+	SYS_SETUID         = 23  // { int sys_setuid(uid_t uid); }
+	SYS_GETUID         = 24  // { uid_t sys_getuid(void); }
+	SYS_GETEUID        = 25  // { uid_t sys_geteuid(void); }
+	SYS_PTRACE         = 26  // { int sys_ptrace(int req, pid_t pid, caddr_t addr, \
+	SYS_RECVMSG        = 27  // { ssize_t sys_recvmsg(int s, struct msghdr *msg, \
+	SYS_SENDMSG        = 28  // { ssize_t sys_sendmsg(int s, \
+	SYS_RECVFROM       = 29  // { ssize_t sys_recvfrom(int s, void *buf, size_t len, \
+	SYS_ACCEPT         = 30  // { int sys_accept(int s, struct sockaddr *name, \
+	SYS_GETPEERNAME    = 31  // { int sys_getpeername(int fdes, struct sockaddr *asa, \
+	SYS_GETSOCKNAME    = 32  // { int sys_getsockname(int fdes, struct sockaddr *asa, \
+	SYS_ACCESS         = 33  // { int sys_access(const char *path, int amode); }
+	SYS_CHFLAGS        = 34  // { int sys_chflags(const char *path, u_int flags); }
+	SYS_FCHFLAGS       = 35  // { int sys_fchflags(int fd, u_int flags); }
+	SYS_SYNC           = 36  // { void sys_sync(void); }
+	SYS_STAT           = 38  // { int sys_stat(const char *path, struct stat *ub); }
+	SYS_GETPPID        = 39  // { pid_t sys_getppid(void); }
+	SYS_LSTAT          = 40  // { int sys_lstat(const char *path, struct stat *ub); }
+	SYS_DUP            = 41  // { int sys_dup(int fd); }
+	SYS_FSTATAT        = 42  // { int sys_fstatat(int fd, const char *path, \
+	SYS_GETEGID        = 43  // { gid_t sys_getegid(void); }
+	SYS_PROFIL         = 44  // { int sys_profil(caddr_t samples, size_t size, \
+	SYS_KTRACE         = 45  // { int sys_ktrace(const char *fname, int ops, \
+	SYS_SIGACTION      = 46  // { int sys_sigaction(int signum, \
+	SYS_GETGID         = 47  // { gid_t sys_getgid(void); }
+	SYS_SIGPROCMASK    = 48  // { int sys_sigprocmask(int how, sigset_t mask); }
+	SYS_GETLOGIN       = 49  // { int sys_getlogin(char *namebuf, u_int namelen); }
+	SYS_SETLOGIN       = 50  // { int sys_setlogin(const char *namebuf); }
+	SYS_ACCT           = 51  // { int sys_acct(const char *path); }
+	SYS_SIGPENDING     = 52  // { int sys_sigpending(void); }
+	SYS_FSTAT          = 53  // { int sys_fstat(int fd, struct stat *sb); }
+	SYS_IOCTL          = 54  // { int sys_ioctl(int fd, \
+	SYS_REBOOT         = 55  // { int sys_reboot(int opt); }
+	SYS_REVOKE         = 56  // { int sys_revoke(const char *path); }
+	SYS_SYMLINK        = 57  // { int sys_symlink(const char *path, \
+	SYS_READLINK       = 58  // { ssize_t sys_readlink(const char *path, \
+	SYS_EXECVE         = 59  // { int sys_execve(const char *path, \
+	SYS_UMASK          = 60  // { mode_t sys_umask(mode_t newmask); }
+	SYS_CHROOT         = 61  // { int sys_chroot(const char *path); }
+	SYS_GETFSSTAT      = 62  // { int sys_getfsstat(struct statfs *buf, size_t bufsize, \
+	SYS_STATFS         = 63  // { int sys_statfs(const char *path, \
+	SYS_FSTATFS        = 64  // { int sys_fstatfs(int fd, struct statfs *buf); }
+	SYS_FHSTATFS       = 65  // { int sys_fhstatfs(const fhandle_t *fhp, \
+	SYS_VFORK          = 66  // { int sys_vfork(void); }
+	SYS_GETTIMEOFDAY   = 67  // { int sys_gettimeofday(struct timeval *tp, \
+	SYS_SETTIMEOFDAY   = 68  // { int sys_settimeofday(const struct timeval *tv, \
+	SYS_SETITIMER      = 69  // { int sys_setitimer(int which, \
+	SYS_GETITIMER      = 70  // { int sys_getitimer(int which, \
+	SYS_SELECT         = 71  // { int sys_select(int nd, fd_set *in, fd_set *ou, \
+	SYS_KEVENT         = 72  // { int sys_kevent(int fd, \
+	SYS_MUNMAP         = 73  // { int sys_munmap(void *addr, size_t len); }
+	SYS_MPROTECT       = 74  // { int sys_mprotect(void *addr, size_t len, \
+	SYS_MADVISE        = 75  // { int sys_madvise(void *addr, size_t len, \
+	SYS_UTIMES         = 76  // { int sys_utimes(const char *path, \
+	SYS_FUTIMES        = 77  // { int sys_futimes(int fd, \
+	SYS_MINCORE        = 78  // { int sys_mincore(void *addr, size_t len, \
+	SYS_GETGROUPS      = 79  // { int sys_getgroups(int gidsetsize, \
+	SYS_SETGROUPS      = 80  // { int sys_setgroups(int gidsetsize, \
+	SYS_GETPGRP        = 81  // { int sys_getpgrp(void); }
+	SYS_SETPGID        = 82  // { int sys_setpgid(pid_t pid, pid_t pgid); }
+	SYS_SENDSYSLOG     = 83  // { int sys_sendsyslog(const void *buf, size_t nbyte); }
+	SYS_UTIMENSAT      = 84  // { int sys_utimensat(int fd, const char *path, \
+	SYS_FUTIMENS       = 85  // { int sys_futimens(int fd, \
+	SYS_CLOCK_GETTIME  = 87  // { int sys_clock_gettime(clockid_t clock_id, \
+	SYS_CLOCK_SETTIME  = 88  // { int sys_clock_settime(clockid_t clock_id, \
+	SYS_CLOCK_GETRES   = 89  // { int sys_clock_getres(clockid_t clock_id, \
+	SYS_DUP2           = 90  // { int sys_dup2(int from, int to); }
+	SYS_NANOSLEEP      = 91  // { int sys_nanosleep(const struct timespec *rqtp, \
+	SYS_FCNTL          = 92  // { int sys_fcntl(int fd, int cmd, ... void *arg); }
+	SYS_ACCEPT4        = 93  // { int sys_accept4(int s, struct sockaddr *name, \
+	SYS___THRSLEEP     = 94  // { int sys___thrsleep(const volatile void *ident, \
+	SYS_FSYNC          = 95  // { int sys_fsync(int fd); }
+	SYS_SETPRIORITY    = 96  // { int sys_setpriority(int which, id_t who, int prio); }
+	SYS_SOCKET         = 97  // { int sys_socket(int domain, int type, int protocol); }
+	SYS_CONNECT        = 98  // { int sys_connect(int s, const struct sockaddr *name, \
+	SYS_GETDENTS       = 99  // { int sys_getdents(int fd, void *buf, size_t buflen); }
+	SYS_GETPRIORITY    = 100 // { int sys_getpriority(int which, id_t who); }
+	SYS_PIPE2          = 101 // { int sys_pipe2(int *fdp, int flags); }
+	SYS_DUP3           = 102 // { int sys_dup3(int from, int to, int flags); }
+	SYS_SIGRETURN      = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); }
+	SYS_BIND           = 104 // { int sys_bind(int s, const struct sockaddr *name, \
+	SYS_SETSOCKOPT     = 105 // { int sys_setsockopt(int s, int level, int name, \
+	SYS_LISTEN         = 106 // { int sys_listen(int s, int backlog); }
+	SYS_CHFLAGSAT      = 107 // { int sys_chflagsat(int fd, const char *path, \
+	SYS_PPOLL          = 109 // { int sys_ppoll(struct pollfd *fds, \
+	SYS_PSELECT        = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, \
+	SYS_SIGSUSPEND     = 111 // { int sys_sigsuspend(int mask); }
+	SYS_GETSOCKOPT     = 118 // { int sys_getsockopt(int s, int level, int name, \
+	SYS_READV          = 120 // { ssize_t sys_readv(int fd, \
+	SYS_WRITEV         = 121 // { ssize_t sys_writev(int fd, \
+	SYS_KILL           = 122 // { int sys_kill(int pid, int signum); }
+	SYS_FCHOWN         = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); }
+	SYS_FCHMOD         = 124 // { int sys_fchmod(int fd, mode_t mode); }
+	SYS_SETREUID       = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); }
+	SYS_SETREGID       = 127 // { int sys_setregid(gid_t rgid, gid_t egid); }
+	SYS_RENAME         = 128 // { int sys_rename(const char *from, const char *to); }
+	SYS_FLOCK          = 131 // { int sys_flock(int fd, int how); }
+	SYS_MKFIFO         = 132 // { int sys_mkfifo(const char *path, mode_t mode); }
+	SYS_SENDTO         = 133 // { ssize_t sys_sendto(int s, const void *buf, \
+	SYS_SHUTDOWN       = 134 // { int sys_shutdown(int s, int how); }
+	SYS_SOCKETPAIR     = 135 // { int sys_socketpair(int domain, int type, \
+	SYS_MKDIR          = 136 // { int sys_mkdir(const char *path, mode_t mode); }
+	SYS_RMDIR          = 137 // { int sys_rmdir(const char *path); }
+	SYS_ADJTIME        = 140 // { int sys_adjtime(const struct timeval *delta, \
+	SYS_SETSID         = 147 // { int sys_setsid(void); }
+	SYS_QUOTACTL       = 148 // { int sys_quotactl(const char *path, int cmd, \
+	SYS_NFSSVC         = 155 // { int sys_nfssvc(int flag, void *argp); }
+	SYS_GETFH          = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); }
+	SYS_SYSARCH        = 165 // { int sys_sysarch(int op, void *parms); }
+	SYS_PREAD          = 173 // { ssize_t sys_pread(int fd, void *buf, \
+	SYS_PWRITE         = 174 // { ssize_t sys_pwrite(int fd, const void *buf, \
+	SYS_SETGID         = 181 // { int sys_setgid(gid_t gid); }
+	SYS_SETEGID        = 182 // { int sys_setegid(gid_t egid); }
+	SYS_SETEUID        = 183 // { int sys_seteuid(uid_t euid); }
+	SYS_PATHCONF       = 191 // { long sys_pathconf(const char *path, int name); }
+	SYS_FPATHCONF      = 192 // { long sys_fpathconf(int fd, int name); }
+	SYS_SWAPCTL        = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); }
+	SYS_GETRLIMIT      = 194 // { int sys_getrlimit(int which, \
+	SYS_SETRLIMIT      = 195 // { int sys_setrlimit(int which, \
+	SYS_MMAP           = 197 // { void *sys_mmap(void *addr, size_t len, int prot, \
+	SYS_LSEEK          = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, \
+	SYS_TRUNCATE       = 200 // { int sys_truncate(const char *path, int pad, \
+	SYS_FTRUNCATE      = 201 // { int sys_ftruncate(int fd, int pad, off_t length); }
+	SYS___SYSCTL       = 202 // { int sys___sysctl(const int *name, u_int namelen, \
+	SYS_MLOCK          = 203 // { int sys_mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK        = 204 // { int sys_munlock(const void *addr, size_t len); }
+	SYS_GETPGID        = 207 // { pid_t sys_getpgid(pid_t pid); }
+	SYS_UTRACE         = 209 // { int sys_utrace(const char *label, const void *addr, \
+	SYS_SEMGET         = 221 // { int sys_semget(key_t key, int nsems, int semflg); }
+	SYS_MSGGET         = 225 // { int sys_msgget(key_t key, int msgflg); }
+	SYS_MSGSND         = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, \
+	SYS_MSGRCV         = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, \
+	SYS_SHMAT          = 228 // { void *sys_shmat(int shmid, const void *shmaddr, \
+	SYS_SHMDT          = 230 // { int sys_shmdt(const void *shmaddr); }
+	SYS_MINHERIT       = 250 // { int sys_minherit(void *addr, size_t len, \
+	SYS_POLL           = 252 // { int sys_poll(struct pollfd *fds, \
+	SYS_ISSETUGID      = 253 // { int sys_issetugid(void); }
+	SYS_LCHOWN         = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); }
+	SYS_GETSID         = 255 // { pid_t sys_getsid(pid_t pid); }
+	SYS_MSYNC          = 256 // { int sys_msync(void *addr, size_t len, int flags); }
+	SYS_PIPE           = 263 // { int sys_pipe(int *fdp); }
+	SYS_FHOPEN         = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); }
+	SYS_PREADV         = 267 // { ssize_t sys_preadv(int fd, \
+	SYS_PWRITEV        = 268 // { ssize_t sys_pwritev(int fd, \
+	SYS_KQUEUE         = 269 // { int sys_kqueue(void); }
+	SYS_MLOCKALL       = 271 // { int sys_mlockall(int flags); }
+	SYS_MUNLOCKALL     = 272 // { int sys_munlockall(void); }
+	SYS_GETRESUID      = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, \
+	SYS_SETRESUID      = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, \
+	SYS_GETRESGID      = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, \
+	SYS_SETRESGID      = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, \
+	SYS_MQUERY         = 286 // { void *sys_mquery(void *addr, size_t len, int prot, \
+	SYS_CLOSEFROM      = 287 // { int sys_closefrom(int fd); }
+	SYS_SIGALTSTACK    = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, \
+	SYS_SHMGET         = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); }
+	SYS_SEMOP          = 290 // { int sys_semop(int semid, struct sembuf *sops, \
+	SYS_FHSTAT         = 294 // { int sys_fhstat(const fhandle_t *fhp, \
+	SYS___SEMCTL       = 295 // { int sys___semctl(int semid, int semnum, int cmd, \
+	SYS_SHMCTL         = 296 // { int sys_shmctl(int shmid, int cmd, \
+	SYS_MSGCTL         = 297 // { int sys_msgctl(int msqid, int cmd, \
+	SYS_SCHED_YIELD    = 298 // { int sys_sched_yield(void); }
+	SYS_GETTHRID       = 299 // { pid_t sys_getthrid(void); }
+	SYS___THRWAKEUP    = 301 // { int sys___thrwakeup(const volatile void *ident, \
+	SYS___THREXIT      = 302 // { void sys___threxit(pid_t *notdead); }
+	SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, \
+	SYS___GETCWD       = 304 // { int sys___getcwd(char *buf, size_t len); }
+	SYS_ADJFREQ        = 305 // { int sys_adjfreq(const int64_t *freq, \
+	SYS_SETRTABLE      = 310 // { int sys_setrtable(int rtableid); }
+	SYS_GETRTABLE      = 311 // { int sys_getrtable(void); }
+	SYS_FACCESSAT      = 313 // { int sys_faccessat(int fd, const char *path, \
+	SYS_FCHMODAT       = 314 // { int sys_fchmodat(int fd, const char *path, \
+	SYS_FCHOWNAT       = 315 // { int sys_fchownat(int fd, const char *path, \
+	SYS_LINKAT         = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, \
+	SYS_MKDIRAT        = 318 // { int sys_mkdirat(int fd, const char *path, \
+	SYS_MKFIFOAT       = 319 // { int sys_mkfifoat(int fd, const char *path, \
+	SYS_MKNODAT        = 320 // { int sys_mknodat(int fd, const char *path, \
+	SYS_OPENAT         = 321 // { int sys_openat(int fd, const char *path, int flags, \
+	SYS_READLINKAT     = 322 // { ssize_t sys_readlinkat(int fd, const char *path, \
+	SYS_RENAMEAT       = 323 // { int sys_renameat(int fromfd, const char *from, \
+	SYS_SYMLINKAT      = 324 // { int sys_symlinkat(const char *path, int fd, \
+	SYS_UNLINKAT       = 325 // { int sys_unlinkat(int fd, const char *path, \
+	SYS___SET_TCB      = 329 // { void sys___set_tcb(void *tcb); }
+	SYS___GET_TCB      = 330 // { void *sys___get_tcb(void); }
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go
index 2de1d44..e61d78a 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_386.go
@@ -1,6 +1,7 @@
+// cgo -godefs types_darwin.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
 // +build 386,darwin
-// Created by cgo -godefs - DO NOT EDIT
-// cgo -godefs types_darwin.go
 
 package unix
 
@@ -445,3 +446,17 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x2
+	AT_REMOVEDIR        = 0x80
+	AT_SYMLINK_FOLLOW   = 0x40
+	AT_SYMLINK_NOFOLLOW = 0x20
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
index 0446578..2619155 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
@@ -1,6 +1,7 @@
+// cgo -godefs types_darwin.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
 // +build amd64,darwin
-// Created by cgo -godefs - DO NOT EDIT
-// cgo -godefs types_darwin.go
 
 package unix
 
@@ -456,7 +457,16 @@
 	Ospeed    uint64
 }
 
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
 const (
 	AT_FDCWD            = -0x2
+	AT_REMOVEDIR        = 0x80
+	AT_SYMLINK_FOLLOW   = 0x40
 	AT_SYMLINK_NOFOLLOW = 0x20
 )
diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go
index 66df363..4dca0d4 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm.go
@@ -447,3 +447,17 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x2
+	AT_REMOVEDIR        = 0x80
+	AT_SYMLINK_FOLLOW   = 0x40
+	AT_SYMLINK_NOFOLLOW = 0x20
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
index 85d56ea..f2881fd 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
@@ -455,3 +455,17 @@
 	Ispeed    uint64
 	Ospeed    uint64
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x2
+	AT_REMOVEDIR        = 0x80
+	AT_SYMLINK_FOLLOW   = 0x40
+	AT_SYMLINK_NOFOLLOW = 0x20
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go
index e585c89..67c6bf8 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_dragonfly_amd64.go
@@ -441,3 +441,8 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+const (
+	AT_FDCWD            = 0xfffafdcd
+	AT_SYMLINK_NOFOLLOW = 0x1
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
index 8cf3094..5b28bcb 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
@@ -1,6 +1,7 @@
+// cgo -godefs types_freebsd.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
 // +build 386,freebsd
-// Created by cgo -godefs - DO NOT EDIT
-// cgo -godefs types_freebsd.go
 
 package unix
 
@@ -85,7 +86,7 @@
 	Ctimespec     Timespec
 	Size          int64
 	Blocks        int64
-	Blksize       uint32
+	Blksize       int32
 	Flags         uint32
 	Gen           uint32
 	Lspare        int32
@@ -288,9 +289,9 @@
 }
 
 const (
-	sizeofIfMsghdr         = 0x64
+	sizeofIfMsghdr         = 0xa8
 	SizeofIfMsghdr         = 0x60
-	sizeofIfData           = 0x54
+	sizeofIfData           = 0x98
 	SizeofIfData           = 0x50
 	SizeofIfaMsghdr        = 0x14
 	SizeofIfmaMsghdr       = 0x10
@@ -322,31 +323,31 @@
 }
 
 type ifData struct {
-	Type        uint8
-	Physical    uint8
-	Addrlen     uint8
-	Hdrlen      uint8
-	Link_state  uint8
-	Vhid        uint8
-	Baudrate_pf uint8
-	Datalen     uint8
-	Mtu         uint32
-	Metric      uint32
-	Baudrate    uint32
-	Ipackets    uint32
-	Ierrors     uint32
-	Opackets    uint32
-	Oerrors     uint32
-	Collisions  uint32
-	Ibytes      uint32
-	Obytes      uint32
-	Imcasts     uint32
-	Omcasts     uint32
-	Iqdrops     uint32
-	Noproto     uint32
-	Hwassist    uint64
-	Epoch       int32
-	Lastchange  Timeval
+	Type              uint8
+	Physical          uint8
+	Addrlen           uint8
+	Hdrlen            uint8
+	Link_state        uint8
+	Vhid              uint8
+	Datalen           uint16
+	Mtu               uint32
+	Metric            uint32
+	Baudrate          uint64
+	Ipackets          uint64
+	Ierrors           uint64
+	Opackets          uint64
+	Oerrors           uint64
+	Collisions        uint64
+	Ibytes            uint64
+	Obytes            uint64
+	Imcasts           uint64
+	Omcasts           uint64
+	Iqdrops           uint64
+	Oqdrops           uint64
+	Noproto           uint64
+	Hwassist          uint64
+	X__ifi_epoch      [8]byte
+	X__ifi_lastchange [16]byte
 }
 
 type IfData struct {
@@ -500,3 +501,21 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x64
+	AT_REMOVEDIR        = 0x800
+	AT_SYMLINK_FOLLOW   = 0x400
+	AT_SYMLINK_NOFOLLOW = 0x200
+)
+
+type CapRights struct {
+	Rights [2]uint64
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
index e5feb20..c65d89e 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
@@ -1,6 +1,7 @@
+// cgo -godefs types_freebsd.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
 // +build amd64,freebsd
-// Created by cgo -godefs - DO NOT EDIT
-// cgo -godefs types_freebsd.go
 
 package unix
 
@@ -85,7 +86,7 @@
 	Ctimespec     Timespec
 	Size          int64
 	Blocks        int64
-	Blksize       uint32
+	Blksize       int32
 	Flags         uint32
 	Gen           uint32
 	Lspare        int32
@@ -324,31 +325,31 @@
 }
 
 type ifData struct {
-	Type        uint8
-	Physical    uint8
-	Addrlen     uint8
-	Hdrlen      uint8
-	Link_state  uint8
-	Vhid        uint8
-	Baudrate_pf uint8
-	Datalen     uint8
-	Mtu         uint64
-	Metric      uint64
-	Baudrate    uint64
-	Ipackets    uint64
-	Ierrors     uint64
-	Opackets    uint64
-	Oerrors     uint64
-	Collisions  uint64
-	Ibytes      uint64
-	Obytes      uint64
-	Imcasts     uint64
-	Omcasts     uint64
-	Iqdrops     uint64
-	Noproto     uint64
-	Hwassist    uint64
-	Epoch       int64
-	Lastchange  Timeval
+	Type              uint8
+	Physical          uint8
+	Addrlen           uint8
+	Hdrlen            uint8
+	Link_state        uint8
+	Vhid              uint8
+	Datalen           uint16
+	Mtu               uint32
+	Metric            uint32
+	Baudrate          uint64
+	Ipackets          uint64
+	Ierrors           uint64
+	Opackets          uint64
+	Oerrors           uint64
+	Collisions        uint64
+	Ibytes            uint64
+	Obytes            uint64
+	Imcasts           uint64
+	Omcasts           uint64
+	Iqdrops           uint64
+	Oqdrops           uint64
+	Noproto           uint64
+	Hwassist          uint64
+	X__ifi_epoch      [8]byte
+	X__ifi_lastchange [16]byte
 }
 
 type IfData struct {
@@ -503,3 +504,21 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x64
+	AT_REMOVEDIR        = 0x800
+	AT_SYMLINK_FOLLOW   = 0x400
+	AT_SYMLINK_NOFOLLOW = 0x200
+)
+
+type CapRights struct {
+	Rights [2]uint64
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
index 5472b54..42c0a50 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
@@ -1,5 +1,5 @@
-// Created by cgo -godefs - DO NOT EDIT
-// cgo -godefs -- -fsigned-char types_freebsd.go
+// cgo -godefs -- -fsigned-char types_freebsd.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
 
 // +build arm,freebsd
 
@@ -88,7 +88,7 @@
 	Ctimespec     Timespec
 	Size          int64
 	Blocks        int64
-	Blksize       uint32
+	Blksize       int32
 	Flags         uint32
 	Gen           uint32
 	Lspare        int32
@@ -142,6 +142,15 @@
 	Val [2]int32
 }
 
+const (
+	FADV_NORMAL     = 0x0
+	FADV_RANDOM     = 0x1
+	FADV_SEQUENTIAL = 0x2
+	FADV_WILLNEED   = 0x3
+	FADV_DONTNEED   = 0x4
+	FADV_NOREUSE    = 0x5
+)
+
 type RawSockaddrInet4 struct {
 	Len    uint8
 	Family uint8
@@ -282,9 +291,9 @@
 }
 
 const (
-	sizeofIfMsghdr         = 0x70
+	sizeofIfMsghdr         = 0xa8
 	SizeofIfMsghdr         = 0x70
-	sizeofIfData           = 0x60
+	sizeofIfData           = 0x98
 	SizeofIfData           = 0x60
 	SizeofIfaMsghdr        = 0x14
 	SizeofIfmaMsghdr       = 0x10
@@ -316,31 +325,31 @@
 }
 
 type ifData struct {
-	Type        uint8
-	Physical    uint8
-	Addrlen     uint8
-	Hdrlen      uint8
-	Link_state  uint8
-	Vhid        uint8
-	Baudrate_pf uint8
-	Datalen     uint8
-	Mtu         uint32
-	Metric      uint32
-	Baudrate    uint32
-	Ipackets    uint32
-	Ierrors     uint32
-	Opackets    uint32
-	Oerrors     uint32
-	Collisions  uint32
-	Ibytes      uint32
-	Obytes      uint32
-	Imcasts     uint32
-	Omcasts     uint32
-	Iqdrops     uint32
-	Noproto     uint32
-	Hwassist    uint64
-	Epoch       int64
-	Lastchange  Timeval
+	Type              uint8
+	Physical          uint8
+	Addrlen           uint8
+	Hdrlen            uint8
+	Link_state        uint8
+	Vhid              uint8
+	Datalen           uint16
+	Mtu               uint32
+	Metric            uint32
+	Baudrate          uint64
+	Ipackets          uint64
+	Ierrors           uint64
+	Opackets          uint64
+	Oerrors           uint64
+	Collisions        uint64
+	Ibytes            uint64
+	Obytes            uint64
+	Imcasts           uint64
+	Omcasts           uint64
+	Iqdrops           uint64
+	Oqdrops           uint64
+	Noproto           uint64
+	Hwassist          uint64
+	X__ifi_epoch      [8]byte
+	X__ifi_lastchange [16]byte
 }
 
 type IfData struct {
@@ -495,3 +504,21 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x64
+	AT_REMOVEDIR        = 0x800
+	AT_SYMLINK_FOLLOW   = 0x400
+	AT_SYMLINK_NOFOLLOW = 0x200
+)
+
+type CapRights struct {
+	Rights [2]uint64
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
index 8111206..0dcebb5 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
@@ -285,6 +285,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -373,9 +380,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x1c
 	SizeofCmsghdr           = 0xc
 	SizeofInet4Pktinfo      = 0xc
@@ -676,3 +685,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
index 075d9c5..d70e543 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
@@ -287,6 +287,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -377,9 +384,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x38
 	SizeofCmsghdr           = 0x10
 	SizeofInet4Pktinfo      = 0xc
@@ -694,3 +703,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
index a66c160..497f563 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
@@ -289,6 +289,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -377,9 +384,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x1c
 	SizeofCmsghdr           = 0xc
 	SizeofInet4Pktinfo      = 0xc
@@ -665,3 +674,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
index b3b506a..f0bdaed 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
@@ -288,6 +288,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -378,9 +385,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x38
 	SizeofCmsghdr           = 0x10
 	SizeofInet4Pktinfo      = 0xc
@@ -673,3 +682,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
index 5c654f5..850a68c 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
@@ -288,6 +288,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -376,9 +383,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x1c
 	SizeofCmsghdr           = 0xc
 	SizeofInet4Pktinfo      = 0xc
@@ -670,3 +679,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
index 3f11fb6..92aac5d 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
@@ -288,6 +288,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -378,9 +385,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x38
 	SizeofCmsghdr           = 0x10
 	SizeofInet4Pktinfo      = 0xc
@@ -675,3 +684,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
index 1a4ad57..623f581 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
@@ -288,6 +288,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -378,9 +385,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x38
 	SizeofCmsghdr           = 0x10
 	SizeofInet4Pktinfo      = 0xc
@@ -675,3 +684,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
index b3f0f30..56598a1 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
@@ -288,6 +288,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -376,9 +383,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x8
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x1c
 	SizeofCmsghdr           = 0xc
 	SizeofInet4Pktinfo      = 0xc
@@ -670,3 +679,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
index aeee27e..acc7c81 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
@@ -289,6 +289,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -379,9 +386,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x38
 	SizeofCmsghdr           = 0x10
 	SizeofInet4Pktinfo      = 0xc
@@ -683,3 +692,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
index b8cb2c3..b348885 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
@@ -289,6 +289,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -379,9 +386,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x38
 	SizeofCmsghdr           = 0x10
 	SizeofInet4Pktinfo      = 0xc
@@ -683,3 +692,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index 58883f9..a706e2f 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -288,6 +288,13 @@
 	Interface uint32
 }
 
+type PacketMreq struct {
+	Ifindex int32
+	Type    uint16
+	Alen    uint16
+	Address [8]uint8
+}
+
 type Msghdr struct {
 	Name       *byte
 	Namelen    uint32
@@ -378,9 +385,11 @@
 	SizeofSockaddrALG       = 0x58
 	SizeofSockaddrVM        = 0x10
 	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
 	SizeofIPMreq            = 0x8
 	SizeofIPMreqn           = 0xc
 	SizeofIPv6Mreq          = 0x14
+	SizeofPacketMreq        = 0x10
 	SizeofMsghdr            = 0x38
 	SizeofCmsghdr           = 0x10
 	SizeofInet4Pktinfo      = 0xc
@@ -700,3 +709,10 @@
 	Ispeed uint32
 	Ospeed uint32
 }
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
index caf755f..42f99c0 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_386.go
@@ -382,6 +382,11 @@
 	Ospeed int32
 }
 
+const (
+	AT_FDCWD            = -0x64
+	AT_SYMLINK_NOFOLLOW = 0x200
+)
+
 type Sysctlnode struct {
 	Flags           uint32
 	Num             int32
diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
index 91b4a53..ff290ba 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_amd64.go
@@ -389,6 +389,11 @@
 	Ospeed int32
 }
 
+const (
+	AT_FDCWD            = -0x64
+	AT_SYMLINK_NOFOLLOW = 0x200
+)
+
 type Sysctlnode struct {
 	Flags           uint32
 	Num             int32
diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
index c0758f9..66dbd7c 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go
@@ -387,6 +387,11 @@
 	Ospeed int32
 }
 
+const (
+	AT_FDCWD            = -0x64
+	AT_SYMLINK_NOFOLLOW = 0x200
+)
+
 type Sysctlnode struct {
 	Flags           uint32
 	Num             int32
diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
index 860a469..20fc9f4 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_386.go
@@ -439,3 +439,8 @@
 	Ispeed int32
 	Ospeed int32
 }
+
+const (
+	AT_FDCWD            = -0x64
+	AT_SYMLINK_NOFOLLOW = 0x2
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
index 23c5272..46fe949 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_amd64.go
@@ -446,3 +446,8 @@
 	Ispeed int32
 	Ospeed int32
 }
+
+const (
+	AT_FDCWD            = -0x64
+	AT_SYMLINK_NOFOLLOW = 0x2
+)
diff --git a/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
new file mode 100644
index 0000000..62e1f7c
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/ztypes_openbsd_arm.go
@@ -0,0 +1,439 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs types_openbsd.go
+
+// +build arm,openbsd
+
+package unix
+
+const (
+	sizeofPtr      = 0x4
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x4
+	sizeofLongLong = 0x8
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int32
+	_C_long_long int64
+)
+
+type Timespec struct {
+	Sec  int64
+	Nsec int32
+}
+
+type Timeval struct {
+	Sec  int64
+	Usec int32
+}
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int32
+	Ixrss    int32
+	Idrss    int32
+	Isrss    int32
+	Minflt   int32
+	Majflt   int32
+	Nswap    int32
+	Inblock  int32
+	Oublock  int32
+	Msgsnd   int32
+	Msgrcv   int32
+	Nsignals int32
+	Nvcsw    int32
+	Nivcsw   int32
+}
+
+type Rlimit struct {
+	Cur uint64
+	Max uint64
+}
+
+type _Gid_t uint32
+
+const (
+	S_IFMT   = 0xf000
+	S_IFIFO  = 0x1000
+	S_IFCHR  = 0x2000
+	S_IFDIR  = 0x4000
+	S_IFBLK  = 0x6000
+	S_IFREG  = 0x8000
+	S_IFLNK  = 0xa000
+	S_IFSOCK = 0xc000
+	S_ISUID  = 0x800
+	S_ISGID  = 0x400
+	S_ISVTX  = 0x200
+	S_IRUSR  = 0x100
+	S_IWUSR  = 0x80
+	S_IXUSR  = 0x40
+)
+
+type Stat_t struct {
+	Mode           uint32
+	Dev            int32
+	Ino            uint64
+	Nlink          uint32
+	Uid            uint32
+	Gid            uint32
+	Rdev           int32
+	Atim           Timespec
+	Mtim           Timespec
+	Ctim           Timespec
+	Size           int64
+	Blocks         int64
+	Blksize        int32
+	Flags          uint32
+	Gen            uint32
+	X__st_birthtim Timespec
+}
+
+type Statfs_t struct {
+	F_flags       uint32
+	F_bsize       uint32
+	F_iosize      uint32
+	F_blocks      uint64
+	F_bfree       uint64
+	F_bavail      int64
+	F_files       uint64
+	F_ffree       uint64
+	F_favail      int64
+	F_syncwrites  uint64
+	F_syncreads   uint64
+	F_asyncwrites uint64
+	F_asyncreads  uint64
+	F_fsid        Fsid
+	F_namemax     uint32
+	F_owner       uint32
+	F_ctime       uint64
+	F_fstypename  [16]uint8
+	F_mntonname   [90]uint8
+	F_mntfromname [90]uint8
+	F_mntfromspec [90]uint8
+	Pad_cgo_0     [2]byte
+	Mount_info    [160]byte
+}
+
+type Flock_t struct {
+	Start  int64
+	Len    int64
+	Pid    int32
+	Type   int16
+	Whence int16
+}
+
+type Dirent struct {
+	Fileno       uint64
+	Off          int64
+	Reclen       uint16
+	Type         uint8
+	Namlen       uint8
+	X__d_padding [4]uint8
+	Name         [256]uint8
+}
+
+type Fsid struct {
+	Val [2]int32
+}
+
+type RawSockaddrInet4 struct {
+	Len    uint8
+	Family uint8
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]int8
+}
+
+type RawSockaddrInet6 struct {
+	Len      uint8
+	Family   uint8
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+	Len    uint8
+	Family uint8
+	Path   [104]int8
+}
+
+type RawSockaddrDatalink struct {
+	Len    uint8
+	Family uint8
+	Index  uint16
+	Type   uint8
+	Nlen   uint8
+	Alen   uint8
+	Slen   uint8
+	Data   [24]int8
+}
+
+type RawSockaddr struct {
+	Len    uint8
+	Family uint8
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [92]int8
+}
+
+type _Socklen uint32
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type Iovec struct {
+	Base *byte
+	Len  uint32
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+type Msghdr struct {
+	Name       *byte
+	Namelen    uint32
+	Iov        *Iovec
+	Iovlen     uint32
+	Control    *byte
+	Controllen uint32
+	Flags      int32
+}
+
+type Cmsghdr struct {
+	Len   uint32
+	Level int32
+	Type  int32
+}
+
+type Inet6Pktinfo struct {
+	Addr    [16]byte /* in6_addr */
+	Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+	Addr RawSockaddrInet6
+	Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+	Filt [8]uint32
+}
+
+const (
+	SizeofSockaddrInet4    = 0x10
+	SizeofSockaddrInet6    = 0x1c
+	SizeofSockaddrAny      = 0x6c
+	SizeofSockaddrUnix     = 0x6a
+	SizeofSockaddrDatalink = 0x20
+	SizeofLinger           = 0x8
+	SizeofIPMreq           = 0x8
+	SizeofIPv6Mreq         = 0x14
+	SizeofMsghdr           = 0x1c
+	SizeofCmsghdr          = 0xc
+	SizeofInet6Pktinfo     = 0x14
+	SizeofIPv6MTUInfo      = 0x20
+	SizeofICMPv6Filter     = 0x20
+)
+
+const (
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
+)
+
+type Kevent_t struct {
+	Ident  uint32
+	Filter int16
+	Flags  uint16
+	Fflags uint32
+	Data   int64
+	Udata  *byte
+}
+
+type FdSet struct {
+	Bits [32]uint32
+}
+
+const (
+	SizeofIfMsghdr         = 0x98
+	SizeofIfData           = 0x80
+	SizeofIfaMsghdr        = 0x18
+	SizeofIfAnnounceMsghdr = 0x1a
+	SizeofRtMsghdr         = 0x60
+	SizeofRtMetrics        = 0x38
+)
+
+type IfMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	Tableid uint16
+	Pad1    uint8
+	Pad2    uint8
+	Addrs   int32
+	Flags   int32
+	Xflags  int32
+	Data    IfData
+}
+
+type IfData struct {
+	Type         uint8
+	Addrlen      uint8
+	Hdrlen       uint8
+	Link_state   uint8
+	Mtu          uint32
+	Metric       uint32
+	Pad          uint32
+	Baudrate     uint64
+	Ipackets     uint64
+	Ierrors      uint64
+	Opackets     uint64
+	Oerrors      uint64
+	Collisions   uint64
+	Ibytes       uint64
+	Obytes       uint64
+	Imcasts      uint64
+	Omcasts      uint64
+	Iqdrops      uint64
+	Noproto      uint64
+	Capabilities uint32
+	Lastchange   Timeval
+}
+
+type IfaMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	Tableid uint16
+	Pad1    uint8
+	Pad2    uint8
+	Addrs   int32
+	Flags   int32
+	Metric  int32
+}
+
+type IfAnnounceMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	What    uint16
+	Name    [16]uint8
+}
+
+type RtMsghdr struct {
+	Msglen   uint16
+	Version  uint8
+	Type     uint8
+	Hdrlen   uint16
+	Index    uint16
+	Tableid  uint16
+	Priority uint8
+	Mpls     uint8
+	Addrs    int32
+	Flags    int32
+	Fmask    int32
+	Pid      int32
+	Seq      int32
+	Errno    int32
+	Inits    uint32
+	Rmx      RtMetrics
+}
+
+type RtMetrics struct {
+	Pksent   uint64
+	Expire   int64
+	Locks    uint32
+	Mtu      uint32
+	Refcnt   uint32
+	Hopcount uint32
+	Recvpipe uint32
+	Sendpipe uint32
+	Ssthresh uint32
+	Rtt      uint32
+	Rttvar   uint32
+	Pad      uint32
+}
+
+type Mclpool struct{}
+
+const (
+	SizeofBpfVersion = 0x4
+	SizeofBpfStat    = 0x8
+	SizeofBpfProgram = 0x8
+	SizeofBpfInsn    = 0x8
+	SizeofBpfHdr     = 0x14
+)
+
+type BpfVersion struct {
+	Major uint16
+	Minor uint16
+}
+
+type BpfStat struct {
+	Recv uint32
+	Drop uint32
+}
+
+type BpfProgram struct {
+	Len   uint32
+	Insns *BpfInsn
+}
+
+type BpfInsn struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+
+type BpfHdr struct {
+	Tstamp    BpfTimeval
+	Caplen    uint32
+	Datalen   uint32
+	Hdrlen    uint16
+	Pad_cgo_0 [2]byte
+}
+
+type BpfTimeval struct {
+	Sec  uint32
+	Usec uint32
+}
+
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [20]uint8
+	Ispeed int32
+	Ospeed int32
+}
+
+const (
+	AT_FDCWD            = -0x64
+	AT_SYMLINK_NOFOLLOW = 0x2
+)
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
index 518250e..c7ff24b 100644
--- a/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -176,6 +176,8 @@
 //sys	RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
 //sys	getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
 //sys	GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
+//sys	SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
+//sys	GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
 //sys	WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
 //sys	ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
 //sys	CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
@@ -186,8 +188,12 @@
 //sys	CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
 //sys	CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
 //sys	GetCurrentThreadId() (id uint32)
-//sys	CreateEvent(eventAttrs *syscall.SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW
+//sys	CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW
+//sys	CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) = kernel32.CreateEventExW
+//sys	OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) = kernel32.OpenEventW
 //sys	SetEvent(event Handle) (err error) = kernel32.SetEvent
+//sys	ResetEvent(event Handle) (err error) = kernel32.ResetEvent
+//sys	PulseEvent(event Handle) (err error) = kernel32.PulseEvent
 
 // syscall interface implementation for other packages
 
diff --git a/vendor/golang.org/x/sys/windows/ztypes_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
similarity index 96%
rename from vendor/golang.org/x/sys/windows/ztypes_windows.go
rename to vendor/golang.org/x/sys/windows/types_windows.go
index c99a3fe..401a5f2 100644
--- a/vendor/golang.org/x/sys/windows/ztypes_windows.go
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -1233,3 +1233,50 @@
 	IfOperStatusNotPresent     = 6
 	IfOperStatusLowerLayerDown = 7
 )
+
+// Console related constants used for the mode parameter to SetConsoleMode. See
+// https://docs.microsoft.com/en-us/windows/console/setconsolemode for details.
+
+const (
+	ENABLE_PROCESSED_INPUT        = 0x1
+	ENABLE_LINE_INPUT             = 0x2
+	ENABLE_ECHO_INPUT             = 0x4
+	ENABLE_WINDOW_INPUT           = 0x8
+	ENABLE_MOUSE_INPUT            = 0x10
+	ENABLE_INSERT_MODE            = 0x20
+	ENABLE_QUICK_EDIT_MODE        = 0x40
+	ENABLE_EXTENDED_FLAGS         = 0x80
+	ENABLE_AUTO_POSITION          = 0x100
+	ENABLE_VIRTUAL_TERMINAL_INPUT = 0x200
+
+	ENABLE_PROCESSED_OUTPUT            = 0x1
+	ENABLE_WRAP_AT_EOL_OUTPUT          = 0x2
+	ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4
+	DISABLE_NEWLINE_AUTO_RETURN        = 0x8
+	ENABLE_LVB_GRID_WORLDWIDE          = 0x10
+)
+
+type Coord struct {
+	X int16
+	Y int16
+}
+
+type SmallRect struct {
+	Left   int16
+	Top    int16
+	Right  int16
+	Bottom int16
+}
+
+// Used with GetConsoleScreenBuffer to retreive information about a console
+// screen buffer. See
+// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str
+// for details.
+
+type ConsoleScreenBufferInfo struct {
+	Size              Coord
+	CursorPosition    Coord
+	Attributes        uint16
+	Window            SmallRect
+	MaximumWindowSize Coord
+}
diff --git a/vendor/golang.org/x/sys/windows/ztypes_windows_386.go b/vendor/golang.org/x/sys/windows/types_windows_386.go
similarity index 100%
rename from vendor/golang.org/x/sys/windows/ztypes_windows_386.go
rename to vendor/golang.org/x/sys/windows/types_windows_386.go
diff --git a/vendor/golang.org/x/sys/windows/ztypes_windows_amd64.go b/vendor/golang.org/x/sys/windows/types_windows_amd64.go
similarity index 100%
rename from vendor/golang.org/x/sys/windows/ztypes_windows_amd64.go
rename to vendor/golang.org/x/sys/windows/types_windows_amd64.go
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index d588e1d..2f893d2 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -161,6 +161,8 @@
 	procRegQueryValueExW                   = modadvapi32.NewProc("RegQueryValueExW")
 	procGetCurrentProcessId                = modkernel32.NewProc("GetCurrentProcessId")
 	procGetConsoleMode                     = modkernel32.NewProc("GetConsoleMode")
+	procSetConsoleMode                     = modkernel32.NewProc("SetConsoleMode")
+	procGetConsoleScreenBufferInfo         = modkernel32.NewProc("GetConsoleScreenBufferInfo")
 	procWriteConsoleW                      = modkernel32.NewProc("WriteConsoleW")
 	procReadConsoleW                       = modkernel32.NewProc("ReadConsoleW")
 	procCreateToolhelp32Snapshot           = modkernel32.NewProc("CreateToolhelp32Snapshot")
@@ -171,7 +173,11 @@
 	procCreateHardLinkW                    = modkernel32.NewProc("CreateHardLinkW")
 	procGetCurrentThreadId                 = modkernel32.NewProc("GetCurrentThreadId")
 	procCreateEventW                       = modkernel32.NewProc("CreateEventW")
+	procCreateEventExW                     = modkernel32.NewProc("CreateEventExW")
+	procOpenEventW                         = modkernel32.NewProc("OpenEventW")
 	procSetEvent                           = modkernel32.NewProc("SetEvent")
+	procResetEvent                         = modkernel32.NewProc("ResetEvent")
+	procPulseEvent                         = modkernel32.NewProc("PulseEvent")
 	procWSAStartup                         = modws2_32.NewProc("WSAStartup")
 	procWSACleanup                         = modws2_32.NewProc("WSACleanup")
 	procWSAIoctl                           = modws2_32.NewProc("WSAIoctl")
@@ -1629,6 +1635,30 @@
 	return
 }
 
+func SetConsoleMode(console Handle, mode uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(console), uintptr(mode), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
 	r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
 	if r1 == 0 {
@@ -1732,7 +1762,7 @@
 	return
 }
 
-func CreateEvent(eventAttrs *syscall.SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) {
+func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) {
 	r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0)
 	handle = Handle(r0)
 	if handle == 0 {
@@ -1745,6 +1775,38 @@
 	return
 }
 
+func CreateEventEx(eventAttrs *SecurityAttributes, name *uint16, flags uint32, desiredAccess uint32) (handle Handle, err error) {
+	r0, _, e1 := syscall.Syscall6(procCreateEventExW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(desiredAccess), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func OpenEvent(desiredAccess uint32, inheritHandle bool, name *uint16) (handle Handle, err error) {
+	var _p0 uint32
+	if inheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r0, _, e1 := syscall.Syscall(procOpenEventW.Addr(), 3, uintptr(desiredAccess), uintptr(_p0), uintptr(unsafe.Pointer(name)))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func SetEvent(event Handle) (err error) {
 	r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0)
 	if r1 == 0 {
@@ -1757,6 +1819,30 @@
 	return
 }
 
+func ResetEvent(event Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(event), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
+func PulseEvent(event Handle) (err error) {
+	r1, _, e1 := syscall.Syscall(procPulseEvent.Addr(), 1, uintptr(event), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
 	r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
 	if r0 != 0 {
diff --git a/volume/drivers/adapter.go b/volume/drivers/adapter.go
index 304c81b..54d1ff2 100644
--- a/volume/drivers/adapter.go
+++ b/volume/drivers/adapter.go
@@ -6,8 +6,8 @@
 	"strings"
 	"time"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/volume"
+	"github.com/sirupsen/logrus"
 )
 
 var (
diff --git a/volume/drivers/extpoint.go b/volume/drivers/extpoint.go
index da230dc..ee42f2f 100644
--- a/volume/drivers/extpoint.go
+++ b/volume/drivers/extpoint.go
@@ -10,6 +10,7 @@
 	"github.com/docker/docker/pkg/locker"
 	getter "github.com/docker/docker/pkg/plugingetter"
 	"github.com/docker/docker/volume"
+	"github.com/pkg/errors"
 )
 
 // currently created by hand. generation tool would generate this like:
@@ -31,6 +32,7 @@
 // volumeDriver defines the available functions that volume plugins must implement.
 // This interface is only defined to generate the proxy objects.
 // It's not intended to be public or reused.
+// nolint: deadcode
 type volumeDriver interface {
 	// Create a volume with the given name
 	Create(name string, opts map[string]string) (err error)
@@ -99,6 +101,14 @@
 	return true
 }
 
+type driverNotFoundError string
+
+func (e driverNotFoundError) Error() string {
+	return "volume driver not found: " + string(e)
+}
+
+func (driverNotFoundError) NotFound() {}
+
 // lookup returns the driver associated with the given name. If a
 // driver with the given name has not been registered it checks if
 // there is a VolumeDriver plugin available with the given name.
@@ -115,7 +125,7 @@
 	if drivers.plugingetter != nil {
 		p, err := drivers.plugingetter.Get(name, extName, mode)
 		if err != nil {
-			return nil, fmt.Errorf("Error looking up volume plugin %s: %v", name, err)
+			return nil, errors.Wrap(err, "error looking up volume plugin "+name)
 		}
 
 		d := NewVolumeDriver(p.Name(), p.BasePath(), p.Client())
@@ -130,7 +140,7 @@
 		}
 		return d, nil
 	}
-	return nil, fmt.Errorf("Error looking up volume plugin %s", name)
+	return nil, driverNotFoundError(name)
 }
 
 func validateDriver(vd volume.Driver) error {
diff --git a/volume/lcow_parser.go b/volume/lcow_parser.go
new file mode 100644
index 0000000..aeb81a4
--- /dev/null
+++ b/volume/lcow_parser.go
@@ -0,0 +1,35 @@
+package volume
+
+import (
+	"errors"
+	"fmt"
+	"path"
+
+	"github.com/docker/docker/api/types/mount"
+)
+
+var lcowSpecificValidators mountValidator = func(m *mount.Mount) error {
+	if path.Clean(m.Target) == "/" {
+		return fmt.Errorf("invalid specification: destination can't be '/'")
+	}
+	if m.Type == mount.TypeNamedPipe {
+		return errors.New("Linux containers on Windows do not support named pipe mounts")
+	}
+	return nil
+}
+
+type lcowParser struct {
+	windowsParser
+}
+
+func (p *lcowParser) validateMountConfig(mnt *mount.Mount) error {
+	return p.validateMountConfigReg(mnt, rxLCOWDestination, lcowSpecificValidators)
+}
+
+func (p *lcowParser) ParseMountRaw(raw, volumeDriver string) (*MountPoint, error) {
+	return p.parseMountRaw(raw, volumeDriver, rxLCOWDestination, false, lcowSpecificValidators)
+}
+
+func (p *lcowParser) ParseMountSpec(cfg mount.Mount) (*MountPoint, error) {
+	return p.parseMountSpec(cfg, rxLCOWDestination, false, lcowSpecificValidators)
+}
diff --git a/volume/linux_parser.go b/volume/linux_parser.go
new file mode 100644
index 0000000..1b3493a
--- /dev/null
+++ b/volume/linux_parser.go
@@ -0,0 +1,416 @@
+package volume
+
+import (
+	"errors"
+	"fmt"
+	"path"
+	"path/filepath"
+	"strings"
+
+	"github.com/docker/docker/api/types/mount"
+	"github.com/docker/docker/pkg/stringid"
+)
+
+type linuxParser struct {
+}
+
+func linuxSplitRawSpec(raw string) ([]string, error) {
+	if strings.Count(raw, ":") > 2 {
+		return nil, errInvalidSpec(raw)
+	}
+
+	arr := strings.SplitN(raw, ":", 3)
+	if arr[0] == "" {
+		return nil, errInvalidSpec(raw)
+	}
+	return arr, nil
+}
+
+func linuxValidateNotRoot(p string) error {
+	p = path.Clean(strings.Replace(p, `\`, `/`, -1))
+	if p == "/" {
+		return fmt.Errorf("invalid specification: destination can't be '/'")
+	}
+	return nil
+}
+func linuxValidateAbsolute(p string) error {
+	p = strings.Replace(p, `\`, `/`, -1)
+	if path.IsAbs(p) {
+		return nil
+	}
+	return fmt.Errorf("invalid mount path: '%s' mount path must be absolute", p)
+}
+func (p *linuxParser) validateMountConfig(mnt *mount.Mount) error {
+	// there was something looking like a bug in existing codebase:
+	// - validateMountConfig on linux was called with options skipping bind source existance when calling ParseMountRaw
+	// - but not when calling ParseMountSpec directly... nor when the unit test called it directly
+	return p.validateMountConfigImpl(mnt, true)
+}
+func (p *linuxParser) validateMountConfigImpl(mnt *mount.Mount, validateBindSourceExists bool) error {
+	if len(mnt.Target) == 0 {
+		return &errMountConfig{mnt, errMissingField("Target")}
+	}
+
+	if err := linuxValidateNotRoot(mnt.Target); err != nil {
+		return &errMountConfig{mnt, err}
+	}
+
+	if err := linuxValidateAbsolute(mnt.Target); err != nil {
+		return &errMountConfig{mnt, err}
+	}
+
+	switch mnt.Type {
+	case mount.TypeBind:
+		if len(mnt.Source) == 0 {
+			return &errMountConfig{mnt, errMissingField("Source")}
+		}
+		// Don't error out just because the propagation mode is not supported on the platform
+		if opts := mnt.BindOptions; opts != nil {
+			if len(opts.Propagation) > 0 && len(linuxPropagationModes) > 0 {
+				if _, ok := linuxPropagationModes[opts.Propagation]; !ok {
+					return &errMountConfig{mnt, fmt.Errorf("invalid propagation mode: %s", opts.Propagation)}
+				}
+			}
+		}
+		if mnt.VolumeOptions != nil {
+			return &errMountConfig{mnt, errExtraField("VolumeOptions")}
+		}
+
+		if err := linuxValidateAbsolute(mnt.Source); err != nil {
+			return &errMountConfig{mnt, err}
+		}
+
+		if validateBindSourceExists {
+			exists, _, _ := currentFileInfoProvider.fileInfo(mnt.Source)
+			if !exists {
+				return &errMountConfig{mnt, errBindNotExist}
+			}
+		}
+
+	case mount.TypeVolume:
+		if mnt.BindOptions != nil {
+			return &errMountConfig{mnt, errExtraField("BindOptions")}
+		}
+
+		if len(mnt.Source) == 0 && mnt.ReadOnly {
+			return &errMountConfig{mnt, fmt.Errorf("must not set ReadOnly mode when using anonymous volumes")}
+		}
+	case mount.TypeTmpfs:
+		if len(mnt.Source) != 0 {
+			return &errMountConfig{mnt, errExtraField("Source")}
+		}
+		if _, err := p.ConvertTmpfsOptions(mnt.TmpfsOptions, mnt.ReadOnly); err != nil {
+			return &errMountConfig{mnt, err}
+		}
+	default:
+		return &errMountConfig{mnt, errors.New("mount type unknown")}
+	}
+	return nil
+}
+
+// read-write modes
+var rwModes = map[string]bool{
+	"rw": true,
+	"ro": true,
+}
+
+// label modes
+var linuxLabelModes = map[string]bool{
+	"Z": true,
+	"z": true,
+}
+
+// consistency modes
+var linuxConsistencyModes = map[mount.Consistency]bool{
+	mount.ConsistencyFull:      true,
+	mount.ConsistencyCached:    true,
+	mount.ConsistencyDelegated: true,
+}
+var linuxPropagationModes = map[mount.Propagation]bool{
+	mount.PropagationPrivate:  true,
+	mount.PropagationRPrivate: true,
+	mount.PropagationSlave:    true,
+	mount.PropagationRSlave:   true,
+	mount.PropagationShared:   true,
+	mount.PropagationRShared:  true,
+}
+
+const linuxDefaultPropagationMode = mount.PropagationRPrivate
+
+func linuxGetPropagation(mode string) mount.Propagation {
+	for _, o := range strings.Split(mode, ",") {
+		prop := mount.Propagation(o)
+		if linuxPropagationModes[prop] {
+			return prop
+		}
+	}
+	return linuxDefaultPropagationMode
+}
+
+func linuxHasPropagation(mode string) bool {
+	for _, o := range strings.Split(mode, ",") {
+		if linuxPropagationModes[mount.Propagation(o)] {
+			return true
+		}
+	}
+	return false
+}
+
+func linuxValidMountMode(mode string) bool {
+	if mode == "" {
+		return true
+	}
+
+	rwModeCount := 0
+	labelModeCount := 0
+	propagationModeCount := 0
+	copyModeCount := 0
+	consistencyModeCount := 0
+
+	for _, o := range strings.Split(mode, ",") {
+		switch {
+		case rwModes[o]:
+			rwModeCount++
+		case linuxLabelModes[o]:
+			labelModeCount++
+		case linuxPropagationModes[mount.Propagation(o)]:
+			propagationModeCount++
+		case copyModeExists(o):
+			copyModeCount++
+		case linuxConsistencyModes[mount.Consistency(o)]:
+			consistencyModeCount++
+		default:
+			return false
+		}
+	}
+
+	// Only one string for each mode is allowed.
+	if rwModeCount > 1 || labelModeCount > 1 || propagationModeCount > 1 || copyModeCount > 1 || consistencyModeCount > 1 {
+		return false
+	}
+	return true
+}
+
+func (p *linuxParser) ReadWrite(mode string) bool {
+	if !linuxValidMountMode(mode) {
+		return false
+	}
+
+	for _, o := range strings.Split(mode, ",") {
+		if o == "ro" {
+			return false
+		}
+	}
+	return true
+}
+
+func (p *linuxParser) ParseMountRaw(raw, volumeDriver string) (*MountPoint, error) {
+	arr, err := linuxSplitRawSpec(raw)
+	if err != nil {
+		return nil, err
+	}
+
+	var spec mount.Mount
+	var mode string
+	switch len(arr) {
+	case 1:
+		// Just a destination path in the container
+		spec.Target = arr[0]
+	case 2:
+		if linuxValidMountMode(arr[1]) {
+			// Destination + Mode is not a valid volume - volumes
+			// cannot include a mode. e.g. /foo:rw
+			return nil, errInvalidSpec(raw)
+		}
+		// Host Source Path or Name + Destination
+		spec.Source = arr[0]
+		spec.Target = arr[1]
+	case 3:
+		// HostSourcePath+DestinationPath+Mode
+		spec.Source = arr[0]
+		spec.Target = arr[1]
+		mode = arr[2]
+	default:
+		return nil, errInvalidSpec(raw)
+	}
+
+	if !linuxValidMountMode(mode) {
+		return nil, errInvalidMode(mode)
+	}
+
+	if path.IsAbs(spec.Source) {
+		spec.Type = mount.TypeBind
+	} else {
+		spec.Type = mount.TypeVolume
+	}
+
+	spec.ReadOnly = !p.ReadWrite(mode)
+
+	// cannot assume that if a volume driver is passed in that we should set it
+	if volumeDriver != "" && spec.Type == mount.TypeVolume {
+		spec.VolumeOptions = &mount.VolumeOptions{
+			DriverConfig: &mount.Driver{Name: volumeDriver},
+		}
+	}
+
+	if copyData, isSet := getCopyMode(mode, p.DefaultCopyMode()); isSet {
+		if spec.VolumeOptions == nil {
+			spec.VolumeOptions = &mount.VolumeOptions{}
+		}
+		spec.VolumeOptions.NoCopy = !copyData
+	}
+	if linuxHasPropagation(mode) {
+		spec.BindOptions = &mount.BindOptions{
+			Propagation: linuxGetPropagation(mode),
+		}
+	}
+
+	mp, err := p.parseMountSpec(spec, false)
+	if mp != nil {
+		mp.Mode = mode
+	}
+	if err != nil {
+		err = fmt.Errorf("%v: %v", errInvalidSpec(raw), err)
+	}
+	return mp, err
+}
+func (p *linuxParser) ParseMountSpec(cfg mount.Mount) (*MountPoint, error) {
+	return p.parseMountSpec(cfg, true)
+}
+func (p *linuxParser) parseMountSpec(cfg mount.Mount, validateBindSourceExists bool) (*MountPoint, error) {
+	if err := p.validateMountConfigImpl(&cfg, validateBindSourceExists); err != nil {
+		return nil, err
+	}
+	mp := &MountPoint{
+		RW:          !cfg.ReadOnly,
+		Destination: path.Clean(filepath.ToSlash(cfg.Target)),
+		Type:        cfg.Type,
+		Spec:        cfg,
+	}
+
+	switch cfg.Type {
+	case mount.TypeVolume:
+		if cfg.Source == "" {
+			mp.Name = stringid.GenerateNonCryptoID()
+		} else {
+			mp.Name = cfg.Source
+		}
+		mp.CopyData = p.DefaultCopyMode()
+
+		if cfg.VolumeOptions != nil {
+			if cfg.VolumeOptions.DriverConfig != nil {
+				mp.Driver = cfg.VolumeOptions.DriverConfig.Name
+			}
+			if cfg.VolumeOptions.NoCopy {
+				mp.CopyData = false
+			}
+		}
+	case mount.TypeBind:
+		mp.Source = path.Clean(filepath.ToSlash(cfg.Source))
+		if cfg.BindOptions != nil && len(cfg.BindOptions.Propagation) > 0 {
+			mp.Propagation = cfg.BindOptions.Propagation
+		} else {
+			// If user did not specify a propagation mode, get
+			// default propagation mode.
+			mp.Propagation = linuxDefaultPropagationMode
+		}
+	case mount.TypeTmpfs:
+		// NOP
+	}
+	return mp, nil
+}
+
+func (p *linuxParser) ParseVolumesFrom(spec string) (string, string, error) {
+	if len(spec) == 0 {
+		return "", "", fmt.Errorf("volumes-from specification cannot be an empty string")
+	}
+
+	specParts := strings.SplitN(spec, ":", 2)
+	id := specParts[0]
+	mode := "rw"
+
+	if len(specParts) == 2 {
+		mode = specParts[1]
+		if !linuxValidMountMode(mode) {
+			return "", "", errInvalidMode(mode)
+		}
+		// For now don't allow propagation properties while importing
+		// volumes from data container. These volumes will inherit
+		// the same propagation property as of the original volume
+		// in data container. This probably can be relaxed in future.
+		if linuxHasPropagation(mode) {
+			return "", "", errInvalidMode(mode)
+		}
+		// Do not allow copy modes on volumes-from
+		if _, isSet := getCopyMode(mode, p.DefaultCopyMode()); isSet {
+			return "", "", errInvalidMode(mode)
+		}
+	}
+	return id, mode, nil
+}
+
+func (p *linuxParser) DefaultPropagationMode() mount.Propagation {
+	return linuxDefaultPropagationMode
+}
+
+func (p *linuxParser) ConvertTmpfsOptions(opt *mount.TmpfsOptions, readOnly bool) (string, error) {
+	var rawOpts []string
+	if readOnly {
+		rawOpts = append(rawOpts, "ro")
+	}
+
+	if opt != nil && opt.Mode != 0 {
+		rawOpts = append(rawOpts, fmt.Sprintf("mode=%o", opt.Mode))
+	}
+
+	if opt != nil && opt.SizeBytes != 0 {
+		// calculate suffix here, making this linux specific, but that is
+		// okay, since API is that way anyways.
+
+		// we do this by finding the suffix that divides evenly into the
+		// value, returning the value itself, with no suffix, if it fails.
+		//
+		// For the most part, we don't enforce any semantic to this values.
+		// The operating system will usually align this and enforce minimum
+		// and maximums.
+		var (
+			size   = opt.SizeBytes
+			suffix string
+		)
+		for _, r := range []struct {
+			suffix  string
+			divisor int64
+		}{
+			{"g", 1 << 30},
+			{"m", 1 << 20},
+			{"k", 1 << 10},
+		} {
+			if size%r.divisor == 0 {
+				size = size / r.divisor
+				suffix = r.suffix
+				break
+			}
+		}
+
+		rawOpts = append(rawOpts, fmt.Sprintf("size=%d%s", size, suffix))
+	}
+	return strings.Join(rawOpts, ","), nil
+}
+
+func (p *linuxParser) DefaultCopyMode() bool {
+	return true
+}
+func (p *linuxParser) ValidateVolumeName(name string) error {
+	return nil
+}
+
+func (p *linuxParser) IsBackwardCompatible(m *MountPoint) bool {
+	return len(m.Source) > 0 || m.Driver == DefaultDriverName
+}
+
+func (p *linuxParser) ValidateTmpfsMountDestination(dest string) error {
+	if err := linuxValidateNotRoot(dest); err != nil {
+		return err
+	}
+	return linuxValidateAbsolute(dest)
+}
diff --git a/volume/local/local.go b/volume/local/local.go
index 43ba1e1..b37c45e 100644
--- a/volume/local/local.go
+++ b/volume/local/local.go
@@ -13,13 +13,12 @@
 	"strings"
 	"sync"
 
-	"github.com/pkg/errors"
-
-	"github.com/Sirupsen/logrus"
-	"github.com/docker/docker/api"
+	"github.com/docker/docker/daemon/names"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/mount"
 	"github.com/docker/docker/volume"
+	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 // VolumeDataPathName is the name of the directory where the volume data is stored.
@@ -36,17 +35,9 @@
 	// volumeNameRegex ensures the name assigned for the volume is valid.
 	// This name is used to create the bind directory, so we need to avoid characters that
 	// would make the path to escape the root directory.
-	volumeNameRegex = api.RestrictedNamePattern
+	volumeNameRegex = names.RestrictedNamePattern
 )
 
-type validationError struct {
-	error
-}
-
-func (validationError) IsValidationError() bool {
-	return true
-}
-
 type activeMount struct {
 	count   uint64
 	mounted bool
@@ -148,6 +139,30 @@
 	return volume.DefaultDriverName
 }
 
+type alreadyExistsError struct {
+	path string
+}
+
+func (e alreadyExistsError) Error() string {
+	return "local volume already exists under " + e.path
+}
+
+func (e alreadyExistsError) Conflict() {}
+
+type systemError struct {
+	err error
+}
+
+func (e systemError) Error() string {
+	return e.err.Error()
+}
+
+func (e systemError) SystemError() {}
+
+func (e systemError) Cause() error {
+	return e.err
+}
+
 // Create creates a new volume.Volume with the provided name, creating
 // the underlying directory tree required for this volume in the
 // process.
@@ -167,9 +182,9 @@
 	path := r.DataPath(name)
 	if err := idtools.MkdirAllAndChown(path, 0755, r.rootIDs); err != nil {
 		if os.IsExist(err) {
-			return nil, fmt.Errorf("volume already exists under %s", filepath.Dir(path))
+			return nil, alreadyExistsError{filepath.Dir(path)}
 		}
-		return nil, errors.Wrapf(err, "error while creating volume path '%s'", path)
+		return nil, errors.Wrapf(systemError{err}, "error while creating volume path '%s'", path)
 	}
 
 	var err error
@@ -195,7 +210,7 @@
 			return nil, err
 		}
 		if err = ioutil.WriteFile(filepath.Join(filepath.Dir(path), "opts.json"), b, 600); err != nil {
-			return nil, errors.Wrap(err, "error while persisting volume options")
+			return nil, errors.Wrap(systemError{err}, "error while persisting volume options")
 		}
 	}
 
@@ -213,11 +228,11 @@
 
 	lv, ok := v.(*localVolume)
 	if !ok {
-		return fmt.Errorf("unknown volume type %T", v)
+		return systemError{errors.Errorf("unknown volume type %T", v)}
 	}
 
 	if lv.active.count > 0 {
-		return fmt.Errorf("volume has active mounts")
+		return systemError{errors.Errorf("volume has active mounts")}
 	}
 
 	if err := lv.unmount(); err != nil {
@@ -233,7 +248,7 @@
 	}
 
 	if !r.scopedPath(realPath) {
-		return fmt.Errorf("Unable to remove a directory of out the Docker root %s: %s", r.scope, realPath)
+		return systemError{errors.Errorf("Unable to remove a directory of out the Docker root %s: %s", r.scope, realPath)}
 	}
 
 	if err := removePath(realPath); err != nil {
@@ -249,7 +264,7 @@
 		if os.IsNotExist(err) {
 			return nil
 		}
-		return errors.Wrapf(err, "error removing volume path '%s'", path)
+		return errors.Wrapf(systemError{err}, "error removing volume path '%s'", path)
 	}
 	return nil
 }
@@ -270,12 +285,20 @@
 	return volume.LocalScope
 }
 
+type validationError string
+
+func (e validationError) Error() string {
+	return string(e)
+}
+
+func (e validationError) InvalidParameter() {}
+
 func (r *Root) validateName(name string) error {
 	if len(name) == 1 {
-		return validationError{fmt.Errorf("volume name is too short, names should be at least two alphanumeric characters")}
+		return validationError("volume name is too short, names should be at least two alphanumeric characters")
 	}
 	if !volumeNameRegex.MatchString(name) {
-		return validationError{fmt.Errorf("%q includes invalid characters for a local volume name, only %q are allowed. If you intended to pass a host directory, use absolute path", name, api.RestrictedNameChars)}
+		return validationError(fmt.Sprintf("%q includes invalid characters for a local volume name, only %q are allowed. If you intended to pass a host directory, use absolute path", name, names.RestrictedNameChars))
 	}
 	return nil
 }
@@ -311,6 +334,11 @@
 	return v.path
 }
 
+// CachedPath returns the data location
+func (v *localVolume) CachedPath() string {
+	return v.path
+}
+
 // Mount implements the localVolume interface, returning the data location.
 // If there are any provided mount options, the resources will be mounted at this point
 func (v *localVolume) Mount(id string) (string, error) {
@@ -319,7 +347,7 @@
 	if v.opts != nil {
 		if !v.active.mounted {
 			if err := v.mount(); err != nil {
-				return "", err
+				return "", systemError{err}
 			}
 			v.active.mounted = true
 		}
@@ -353,7 +381,7 @@
 	if v.opts != nil {
 		if err := mount.Unmount(v.path); err != nil {
 			if mounted, mErr := mount.Mounted(v.path); mounted || mErr != nil {
-				return errors.Wrapf(err, "error while unmounting volume path '%s'", v.path)
+				return errors.Wrapf(systemError{err}, "error while unmounting volume path '%s'", v.path)
 			}
 		}
 		v.active.mounted = false
@@ -364,7 +392,7 @@
 func validateOpts(opts map[string]string) error {
 	for opt := range opts {
 		if !validOpts[opt] {
-			return validationError{fmt.Errorf("invalid option key: %q", opt)}
+			return validationError(fmt.Sprintf("invalid option key: %q", opt))
 		}
 	}
 	return nil
diff --git a/volume/parser.go b/volume/parser.go
new file mode 100644
index 0000000..1f48b60
--- /dev/null
+++ b/volume/parser.go
@@ -0,0 +1,43 @@
+package volume
+
+import (
+	"runtime"
+
+	"github.com/docker/docker/api/types/mount"
+)
+
+const (
+	// OSLinux is the same as runtime.GOOS on linux
+	OSLinux = "linux"
+	// OSWindows is the same as runtime.GOOS on windows
+	OSWindows = "windows"
+)
+
+// Parser represents a platform specific parser for mount expressions
+type Parser interface {
+	ParseMountRaw(raw, volumeDriver string) (*MountPoint, error)
+	ParseMountSpec(cfg mount.Mount) (*MountPoint, error)
+	ParseVolumesFrom(spec string) (string, string, error)
+	DefaultPropagationMode() mount.Propagation
+	ConvertTmpfsOptions(opt *mount.TmpfsOptions, readOnly bool) (string, error)
+	DefaultCopyMode() bool
+	ValidateVolumeName(name string) error
+	ReadWrite(mode string) bool
+	IsBackwardCompatible(m *MountPoint) bool
+	HasResource(m *MountPoint, absPath string) bool
+	ValidateTmpfsMountDestination(dest string) error
+
+	validateMountConfig(mt *mount.Mount) error
+}
+
+// NewParser creates a parser for a given container OS, depending on the current host OS (linux on a windows host will resolve to an lcowParser)
+func NewParser(containerOS string) Parser {
+	switch containerOS {
+	case OSWindows:
+		return &windowsParser{}
+	}
+	if runtime.GOOS == OSWindows {
+		return &lcowParser{}
+	}
+	return &linuxParser{}
+}
diff --git a/volume/store/db.go b/volume/store/db.go
index c5fd164..01f0abb 100644
--- a/volume/store/db.go
+++ b/volume/store/db.go
@@ -3,9 +3,9 @@
 import (
 	"encoding/json"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/boltdb/bolt"
 	"github.com/pkg/errors"
+	"github.com/sirupsen/logrus"
 )
 
 var volumeBucketName = []byte("volumes")
diff --git a/volume/store/errors.go b/volume/store/errors.go
index 980175f..75e24e6 100644
--- a/volume/store/errors.go
+++ b/volume/store/errors.go
@@ -2,21 +2,32 @@
 
 import (
 	"strings"
-
-	"github.com/pkg/errors"
 )
 
-var (
+const (
 	// errVolumeInUse is a typed error returned when trying to remove a volume that is currently in use by a container
-	errVolumeInUse = errors.New("volume is in use")
+	errVolumeInUse conflictError = "volume is in use"
 	// errNoSuchVolume is a typed error returned if the requested volume doesn't exist in the volume store
-	errNoSuchVolume = errors.New("no such volume")
-	// errInvalidName is a typed error returned when creating a volume with a name that is not valid on the platform
-	errInvalidName = errors.New("volume name is not valid on this platform")
+	errNoSuchVolume notFoundError = "no such volume"
 	// errNameConflict is a typed error returned on create when a volume exists with the given name, but for a different driver
-	errNameConflict = errors.New("volume name must be unique")
+	errNameConflict conflictError = "volume name must be unique"
 )
 
+type conflictError string
+
+func (e conflictError) Error() string {
+	return string(e)
+}
+func (conflictError) Conflict() {}
+
+type notFoundError string
+
+func (e notFoundError) Error() string {
+	return string(e)
+}
+
+func (notFoundError) NotFound() {}
+
 // OpErr is the error type returned by functions in the store package. It describes
 // the operation, volume name, and error.
 type OpErr struct {
@@ -47,6 +58,11 @@
 	return s
 }
 
+// Cause returns the error the caused this error
+func (e *OpErr) Cause() error {
+	return e.Err
+}
+
 // IsInUse returns a boolean indicating whether the error indicates that a
 // volume is in use
 func IsInUse(err error) bool {
@@ -64,13 +80,16 @@
 	return isErr(err, errNameConflict)
 }
 
+type causal interface {
+	Cause() error
+}
+
 func isErr(err error, expected error) bool {
-	err = errors.Cause(err)
 	switch pe := err.(type) {
 	case nil:
 		return false
-	case *OpErr:
-		err = errors.Cause(pe.Err)
+	case causal:
+		return isErr(pe.Cause(), expected)
 	}
 	return err == expected
 }
diff --git a/volume/store/restore.go b/volume/store/restore.go
index c0c5b51..e2a72a6 100644
--- a/volume/store/restore.go
+++ b/volume/store/restore.go
@@ -3,10 +3,10 @@
 import (
 	"sync"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/boltdb/bolt"
 	"github.com/docker/docker/volume"
 	"github.com/docker/docker/volume/drivers"
+	"github.com/sirupsen/logrus"
 )
 
 // restore is called when a new volume store is created.
diff --git a/volume/store/store.go b/volume/store/store.go
index cded883..e47ec0e 100644
--- a/volume/store/store.go
+++ b/volume/store/store.go
@@ -4,16 +4,17 @@
 	"net"
 	"os"
 	"path/filepath"
+	"runtime"
 	"sync"
 	"time"
 
 	"github.com/pkg/errors"
 
-	"github.com/Sirupsen/logrus"
 	"github.com/boltdb/bolt"
 	"github.com/docker/docker/pkg/locker"
 	"github.com/docker/docker/volume"
 	"github.com/docker/docker/volume/drivers"
+	"github.com/sirupsen/logrus"
 )
 
 const (
@@ -188,7 +189,7 @@
 	var out []volume.Volume
 
 	for _, v := range vols {
-		name := normaliseVolumeName(v.Name())
+		name := normalizeVolumeName(v.Name())
 
 		s.locks.Lock(name)
 		storedV, exists := s.getNamed(name)
@@ -269,7 +270,7 @@
 // CreateWithRef creates a volume with the given name and driver and stores the ref
 // This ensures there's no race between creating a volume and then storing a reference.
 func (s *VolumeStore) CreateWithRef(name, driverName, ref string, opts, labels map[string]string) (volume.Volume, error) {
-	name = normaliseVolumeName(name)
+	name = normalizeVolumeName(name)
 	s.locks.Lock(name)
 	defer s.locks.Unlock(name)
 
@@ -369,13 +370,14 @@
 // It is expected that callers of this function hold any necessary locks.
 func (s *VolumeStore) create(name, driverName string, opts, labels map[string]string) (volume.Volume, error) {
 	// Validate the name in a platform-specific manner
-	valid, err := volume.IsVolumeNameValid(name)
+
+	// volume name validation is specific to the host os and not on container image
+	// windows/lcow should have an equivalent volumename validation logic so we create a parser for current host OS
+	parser := volume.NewParser(runtime.GOOS)
+	err := parser.ValidateVolumeName(name)
 	if err != nil {
 		return nil, err
 	}
-	if !valid {
-		return nil, &OpErr{Err: errInvalidName, Name: name, Op: "create"}
-	}
 
 	v, err := s.checkConflict(name, driverName)
 	if err != nil {
@@ -432,7 +434,7 @@
 // This is just like Get(), but we store the reference while holding the lock.
 // This makes sure there are no races between checking for the existence of a volume and adding a reference for it
 func (s *VolumeStore) GetWithRef(name, driverName, ref string) (volume.Volume, error) {
-	name = normaliseVolumeName(name)
+	name = normalizeVolumeName(name)
 	s.locks.Lock(name)
 	defer s.locks.Unlock(name)
 
@@ -455,7 +457,7 @@
 
 // Get looks if a volume with the given name exists and returns it if so
 func (s *VolumeStore) Get(name string) (volume.Volume, error) {
-	name = normaliseVolumeName(name)
+	name = normalizeVolumeName(name)
 	s.locks.Lock(name)
 	defer s.locks.Unlock(name)
 
@@ -558,7 +560,7 @@
 
 // Remove removes the requested volume. A volume is not removed if it has any refs
 func (s *VolumeStore) Remove(v volume.Volume) error {
-	name := normaliseVolumeName(v.Name())
+	name := normalizeVolumeName(v.Name())
 	s.locks.Lock(name)
 	defer s.locks.Unlock(name)
 
diff --git a/volume/store/store_unix.go b/volume/store/store_unix.go
index 8ebc1f2..c024abb 100644
--- a/volume/store/store_unix.go
+++ b/volume/store/store_unix.go
@@ -2,8 +2,8 @@
 
 package store
 
-// normaliseVolumeName is a platform specific function to normalise the name
+// normalizeVolumeName is a platform specific function to normalize the name
 // of a volume. This is a no-op on Unix-like platforms
-func normaliseVolumeName(name string) string {
+func normalizeVolumeName(name string) string {
 	return name
 }
diff --git a/volume/store/store_windows.go b/volume/store/store_windows.go
index 8601cdd..9e91a5f 100644
--- a/volume/store/store_windows.go
+++ b/volume/store/store_windows.go
@@ -2,11 +2,11 @@
 
 import "strings"
 
-// normaliseVolumeName is a platform specific function to normalise the name
+// normalizeVolumeName is a platform specific function to normalize the name
 // of a volume. On Windows, as NTFS is case insensitive, under
 // c:\ProgramData\Docker\Volumes\, the folders John and john would be synonymous.
 // Hence we can't allow the volume "John" and "john" to be created as separate
 // volumes.
-func normaliseVolumeName(name string) string {
+func normalizeVolumeName(name string) string {
 	return strings.ToLower(name)
 }
diff --git a/volume/validate.go b/volume/validate.go
index 42396a0..b3f6409 100644
--- a/volume/validate.go
+++ b/volume/validate.go
@@ -1,108 +1,14 @@
 package volume
 
 import (
-	"errors"
 	"fmt"
-	"os"
-	"path/filepath"
 
 	"github.com/docker/docker/api/types/mount"
+	"github.com/pkg/errors"
 )
 
 var errBindNotExist = errors.New("bind source path does not exist")
 
-type validateOpts struct {
-	skipBindSourceCheck   bool
-	skipAbsolutePathCheck bool
-}
-
-func validateMountConfig(mnt *mount.Mount, options ...func(*validateOpts)) error {
-	opts := validateOpts{}
-	for _, o := range options {
-		o(&opts)
-	}
-
-	if len(mnt.Target) == 0 {
-		return &errMountConfig{mnt, errMissingField("Target")}
-	}
-
-	if err := validateNotRoot(mnt.Target); err != nil {
-		return &errMountConfig{mnt, err}
-	}
-
-	if !opts.skipAbsolutePathCheck {
-		if err := validateAbsolute(mnt.Target); err != nil {
-			return &errMountConfig{mnt, err}
-		}
-	}
-
-	switch mnt.Type {
-	case mount.TypeBind:
-		if len(mnt.Source) == 0 {
-			return &errMountConfig{mnt, errMissingField("Source")}
-		}
-		// Don't error out just because the propagation mode is not supported on the platform
-		if opts := mnt.BindOptions; opts != nil {
-			if len(opts.Propagation) > 0 && len(propagationModes) > 0 {
-				if _, ok := propagationModes[opts.Propagation]; !ok {
-					return &errMountConfig{mnt, fmt.Errorf("invalid propagation mode: %s", opts.Propagation)}
-				}
-			}
-		}
-		if mnt.VolumeOptions != nil {
-			return &errMountConfig{mnt, errExtraField("VolumeOptions")}
-		}
-
-		if err := validateAbsolute(mnt.Source); err != nil {
-			return &errMountConfig{mnt, err}
-		}
-
-		// Do not allow binding to non-existent path
-		if !opts.skipBindSourceCheck {
-			fi, err := os.Stat(mnt.Source)
-			if err != nil {
-				if !os.IsNotExist(err) {
-					return &errMountConfig{mnt, err}
-				}
-				return &errMountConfig{mnt, errBindNotExist}
-			}
-			if err := validateStat(fi); err != nil {
-				return &errMountConfig{mnt, err}
-			}
-		}
-	case mount.TypeVolume:
-		if mnt.BindOptions != nil {
-			return &errMountConfig{mnt, errExtraField("BindOptions")}
-		}
-
-		if len(mnt.Source) == 0 && mnt.ReadOnly {
-			return &errMountConfig{mnt, fmt.Errorf("must not set ReadOnly mode when using anonymous volumes")}
-		}
-
-		if len(mnt.Source) != 0 {
-			if valid, err := IsVolumeNameValid(mnt.Source); !valid {
-				if err == nil {
-					err = errors.New("invalid volume name")
-				}
-				return &errMountConfig{mnt, err}
-			}
-		}
-	case mount.TypeTmpfs:
-		if len(mnt.Source) != 0 {
-			return &errMountConfig{mnt, errExtraField("Source")}
-		}
-		if err := ValidateTmpfsMountDestination(mnt.Target); err != nil {
-			return &errMountConfig{mnt, err}
-		}
-		if _, err := ConvertTmpfsOptions(mnt.TmpfsOptions, mnt.ReadOnly); err != nil {
-			return &errMountConfig{mnt, err}
-		}
-	default:
-		return &errMountConfig{mnt, errors.New("mount type unknown")}
-	}
-	return nil
-}
-
 type errMountConfig struct {
 	mount *mount.Mount
 	err   error
@@ -113,28 +19,8 @@
 }
 
 func errExtraField(name string) error {
-	return fmt.Errorf("field %s must not be specified", name)
+	return errors.Errorf("field %s must not be specified", name)
 }
 func errMissingField(name string) error {
-	return fmt.Errorf("field %s must not be empty", name)
-}
-
-func validateAbsolute(p string) error {
-	p = convertSlash(p)
-	if filepath.IsAbs(p) {
-		return nil
-	}
-	return fmt.Errorf("invalid mount path: '%s' mount path must be absolute", p)
-}
-
-// ValidateTmpfsMountDestination validates the destination of tmpfs mount.
-// Currently, we have only two obvious rule for validation:
-//  - path must not be "/"
-//  - path must be absolute
-// We should add more rules carefully (#30166)
-func ValidateTmpfsMountDestination(dest string) error {
-	if err := validateNotRoot(dest); err != nil {
-		return err
-	}
-	return validateAbsolute(dest)
+	return errors.Errorf("field %s must not be empty", name)
 }
diff --git a/volume/validate_test.go b/volume/validate_test.go
index 8732500..6a8e286 100644
--- a/volume/validate_test.go
+++ b/volume/validate_test.go
@@ -4,6 +4,7 @@
 	"errors"
 	"io/ioutil"
 	"os"
+	"runtime"
 	"strings"
 	"testing"
 
@@ -27,17 +28,50 @@
 		{mount.Mount{Type: mount.TypeBind}, errMissingField("Target")},
 		{mount.Mount{Type: mount.TypeBind, Target: testDestinationPath}, errMissingField("Source")},
 		{mount.Mount{Type: mount.TypeBind, Target: testDestinationPath, Source: testSourcePath, VolumeOptions: &mount.VolumeOptions{}}, errExtraField("VolumeOptions")},
-		{mount.Mount{Type: mount.TypeBind, Source: testSourcePath, Target: testDestinationPath}, errBindNotExist},
+
 		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, nil},
 		{mount.Mount{Type: "invalid", Target: testDestinationPath}, errors.New("mount type unknown")},
 	}
+	if runtime.GOOS == "windows" {
+		cases = append(cases, struct {
+			input    mount.Mount
+			expected error
+		}{mount.Mount{Type: mount.TypeBind, Source: testSourcePath, Target: testDestinationPath}, errBindNotExist}) // bind source existance is not checked on linux
+	}
+	lcowCases := []struct {
+		input    mount.Mount
+		expected error
+	}{
+		{mount.Mount{Type: mount.TypeVolume}, errMissingField("Target")},
+		{mount.Mount{Type: mount.TypeVolume, Target: "/foo", Source: "hello"}, nil},
+		{mount.Mount{Type: mount.TypeVolume, Target: "/foo"}, nil},
+		{mount.Mount{Type: mount.TypeBind}, errMissingField("Target")},
+		{mount.Mount{Type: mount.TypeBind, Target: "/foo"}, errMissingField("Source")},
+		{mount.Mount{Type: mount.TypeBind, Target: "/foo", Source: "c:\\foo", VolumeOptions: &mount.VolumeOptions{}}, errExtraField("VolumeOptions")},
+		{mount.Mount{Type: mount.TypeBind, Source: "c:\\foo", Target: "/foo"}, errBindNotExist},
+		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: "/foo"}, nil},
+		{mount.Mount{Type: "invalid", Target: "/foo"}, errors.New("mount type unknown")},
+	}
+	parser := NewParser(runtime.GOOS)
 	for i, x := range cases {
-		err := validateMountConfig(&x.input)
+		err := parser.validateMountConfig(&x.input)
 		if err == nil && x.expected == nil {
 			continue
 		}
 		if (err == nil && x.expected != nil) || (x.expected == nil && err != nil) || !strings.Contains(err.Error(), x.expected.Error()) {
-			t.Fatalf("expected %q, got %q, case: %d", x.expected, err, i)
+			t.Errorf("expected %q, got %q, case: %d", x.expected, err, i)
+		}
+	}
+	if runtime.GOOS == "windows" {
+		parser = &lcowParser{}
+		for i, x := range lcowCases {
+			err := parser.validateMountConfig(&x.input)
+			if err == nil && x.expected == nil {
+				continue
+			}
+			if (err == nil && x.expected != nil) || (x.expected == nil && err != nil) || !strings.Contains(err.Error(), x.expected.Error()) {
+				t.Errorf("expected %q, got %q, case: %d", x.expected, err, i)
+			}
 		}
 	}
 }
diff --git a/volume/validate_test_unix.go b/volume/validate_unix_test.go
similarity index 100%
rename from volume/validate_test_unix.go
rename to volume/validate_unix_test.go
diff --git a/volume/validate_test_windows.go b/volume/validate_windows_test.go
similarity index 100%
rename from volume/validate_test_windows.go
rename to volume/validate_windows_test.go
diff --git a/volume/volume.go b/volume/volume.go
index 8598d4c..b8ec1e5 100644
--- a/volume/volume.go
+++ b/volume/volume.go
@@ -4,7 +4,6 @@
 	"fmt"
 	"os"
 	"path/filepath"
-	"strings"
 	"syscall"
 	"time"
 
@@ -157,13 +156,20 @@
 			return
 		}
 
-		err = label.Relabel(m.Source, mountLabel, label.IsShared(m.Mode))
+		var sourcePath string
+		sourcePath, err = filepath.EvalSymlinks(m.Source)
+		if err != nil {
+			path = ""
+			err = errors.Wrapf(err, "error evaluating symlinks from mount source %q", m.Source)
+			return
+		}
+		err = label.Relabel(sourcePath, mountLabel, label.IsShared(m.Mode))
 		if err == syscall.ENOTSUP {
 			err = nil
 		}
 		if err != nil {
 			path = ""
-			err = errors.Wrapf(err, "error setting label on mount source '%s'", m.Source)
+			err = errors.Wrapf(err, "error setting label on mount source '%s'", sourcePath)
 		}
 	}()
 
@@ -217,158 +223,10 @@
 	return m.Source
 }
 
-// ParseVolumesFrom ensures that the supplied volumes-from is valid.
-func ParseVolumesFrom(spec string) (string, string, error) {
-	if len(spec) == 0 {
-		return "", "", fmt.Errorf("volumes-from specification cannot be an empty string")
-	}
-
-	specParts := strings.SplitN(spec, ":", 2)
-	id := specParts[0]
-	mode := "rw"
-
-	if len(specParts) == 2 {
-		mode = specParts[1]
-		if !ValidMountMode(mode) {
-			return "", "", errInvalidMode(mode)
-		}
-		// For now don't allow propagation properties while importing
-		// volumes from data container. These volumes will inherit
-		// the same propagation property as of the original volume
-		// in data container. This probably can be relaxed in future.
-		if HasPropagation(mode) {
-			return "", "", errInvalidMode(mode)
-		}
-		// Do not allow copy modes on volumes-from
-		if _, isSet := getCopyMode(mode); isSet {
-			return "", "", errInvalidMode(mode)
-		}
-	}
-	return id, mode, nil
-}
-
-// ParseMountRaw parses a raw volume spec (e.g. `-v /foo:/bar:shared`) into a
-// structured spec. Once the raw spec is parsed it relies on `ParseMountSpec` to
-// validate the spec and create a MountPoint
-func ParseMountRaw(raw, volumeDriver string) (*MountPoint, error) {
-	arr, err := splitRawSpec(convertSlash(raw))
-	if err != nil {
-		return nil, err
-	}
-
-	var spec mounttypes.Mount
-	var mode string
-	switch len(arr) {
-	case 1:
-		// Just a destination path in the container
-		spec.Target = arr[0]
-	case 2:
-		if ValidMountMode(arr[1]) {
-			// Destination + Mode is not a valid volume - volumes
-			// cannot include a mode. e.g. /foo:rw
-			return nil, errInvalidSpec(raw)
-		}
-		// Host Source Path or Name + Destination
-		spec.Source = arr[0]
-		spec.Target = arr[1]
-	case 3:
-		// HostSourcePath+DestinationPath+Mode
-		spec.Source = arr[0]
-		spec.Target = arr[1]
-		mode = arr[2]
-	default:
-		return nil, errInvalidSpec(raw)
-	}
-
-	if !ValidMountMode(mode) {
-		return nil, errInvalidMode(mode)
-	}
-
-	if filepath.IsAbs(spec.Source) {
-		spec.Type = mounttypes.TypeBind
-	} else {
-		spec.Type = mounttypes.TypeVolume
-	}
-
-	spec.ReadOnly = !ReadWrite(mode)
-
-	// cannot assume that if a volume driver is passed in that we should set it
-	if volumeDriver != "" && spec.Type == mounttypes.TypeVolume {
-		spec.VolumeOptions = &mounttypes.VolumeOptions{
-			DriverConfig: &mounttypes.Driver{Name: volumeDriver},
-		}
-	}
-
-	if copyData, isSet := getCopyMode(mode); isSet {
-		if spec.VolumeOptions == nil {
-			spec.VolumeOptions = &mounttypes.VolumeOptions{}
-		}
-		spec.VolumeOptions.NoCopy = !copyData
-	}
-	if HasPropagation(mode) {
-		spec.BindOptions = &mounttypes.BindOptions{
-			Propagation: GetPropagation(mode),
-		}
-	}
-
-	mp, err := ParseMountSpec(spec, platformRawValidationOpts...)
-	if mp != nil {
-		mp.Mode = mode
-	}
-	if err != nil {
-		err = fmt.Errorf("%v: %v", errInvalidSpec(raw), err)
-	}
-	return mp, err
-}
-
-// ParseMountSpec reads a mount config, validates it, and configures a mountpoint from it.
-func ParseMountSpec(cfg mounttypes.Mount, options ...func(*validateOpts)) (*MountPoint, error) {
-	if err := validateMountConfig(&cfg, options...); err != nil {
-		return nil, err
-	}
-	mp := &MountPoint{
-		RW:          !cfg.ReadOnly,
-		Destination: clean(convertSlash(cfg.Target)),
-		Type:        cfg.Type,
-		Spec:        cfg,
-	}
-
-	switch cfg.Type {
-	case mounttypes.TypeVolume:
-		if cfg.Source == "" {
-			mp.Name = stringid.GenerateNonCryptoID()
-		} else {
-			mp.Name = cfg.Source
-		}
-		mp.CopyData = DefaultCopyMode
-
-		if cfg.VolumeOptions != nil {
-			if cfg.VolumeOptions.DriverConfig != nil {
-				mp.Driver = cfg.VolumeOptions.DriverConfig.Name
-			}
-			if cfg.VolumeOptions.NoCopy {
-				mp.CopyData = false
-			}
-		}
-	case mounttypes.TypeBind:
-		mp.Source = clean(convertSlash(cfg.Source))
-		if cfg.BindOptions != nil && len(cfg.BindOptions.Propagation) > 0 {
-			mp.Propagation = cfg.BindOptions.Propagation
-		} else {
-			// If user did not specify a propagation mode, get
-			// default propagation mode.
-			mp.Propagation = DefaultPropagationMode
-		}
-	case mounttypes.TypeTmpfs:
-		// NOP
-	}
-	return mp, nil
-}
-
 func errInvalidMode(mode string) error {
-	return fmt.Errorf("invalid mode: %v", mode)
+	return errors.Errorf("invalid mode: %v", mode)
 }
 
 func errInvalidSpec(spec string) error {
-	return fmt.Errorf("invalid volume specification: '%s'", spec)
+	return errors.Errorf("invalid volume specification: '%s'", spec)
 }
diff --git a/volume/volume_copy.go b/volume/volume_copy.go
index 77f06a0..37c7fa7 100644
--- a/volume/volume_copy.go
+++ b/volume/volume_copy.go
@@ -13,11 +13,11 @@
 }
 
 // GetCopyMode gets the copy mode from the mode string for mounts
-func getCopyMode(mode string) (bool, bool) {
+func getCopyMode(mode string, def bool) (bool, bool) {
 	for _, o := range strings.Split(mode, ",") {
 		if isEnabled, exists := copyModes[o]; exists {
 			return isEnabled, true
 		}
 	}
-	return DefaultCopyMode, false
+	return def, false
 }
diff --git a/volume/volume_copy_unix.go b/volume/volume_copy_unix.go
deleted file mode 100644
index ad66e17..0000000
--- a/volume/volume_copy_unix.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// +build !windows
-
-package volume
-
-const (
-	// DefaultCopyMode is the copy mode used by default for normal/named volumes
-	DefaultCopyMode = true
-)
diff --git a/volume/volume_copy_windows.go b/volume/volume_copy_windows.go
deleted file mode 100644
index 798638c..0000000
--- a/volume/volume_copy_windows.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package volume
-
-const (
-	// DefaultCopyMode is the copy mode used by default for normal/named volumes
-	DefaultCopyMode = false
-)
diff --git a/volume/volume_linux.go b/volume/volume_linux.go
deleted file mode 100644
index fdf7b63..0000000
--- a/volume/volume_linux.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// +build linux
-
-package volume
-
-import (
-	"fmt"
-	"strings"
-
-	mounttypes "github.com/docker/docker/api/types/mount"
-)
-
-// ConvertTmpfsOptions converts *mounttypes.TmpfsOptions to the raw option string
-// for mount(2).
-func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions, readOnly bool) (string, error) {
-	var rawOpts []string
-	if readOnly {
-		rawOpts = append(rawOpts, "ro")
-	}
-
-	if opt != nil && opt.Mode != 0 {
-		rawOpts = append(rawOpts, fmt.Sprintf("mode=%o", opt.Mode))
-	}
-
-	if opt != nil && opt.SizeBytes != 0 {
-		// calculate suffix here, making this linux specific, but that is
-		// okay, since API is that way anyways.
-
-		// we do this by finding the suffix that divides evenly into the
-		// value, returning the value itself, with no suffix, if it fails.
-		//
-		// For the most part, we don't enforce any semantic to this values.
-		// The operating system will usually align this and enforce minimum
-		// and maximums.
-		var (
-			size   = opt.SizeBytes
-			suffix string
-		)
-		for _, r := range []struct {
-			suffix  string
-			divisor int64
-		}{
-			{"g", 1 << 30},
-			{"m", 1 << 20},
-			{"k", 1 << 10},
-		} {
-			if size%r.divisor == 0 {
-				size = size / r.divisor
-				suffix = r.suffix
-				break
-			}
-		}
-
-		rawOpts = append(rawOpts, fmt.Sprintf("size=%d%s", size, suffix))
-	}
-	return strings.Join(rawOpts, ","), nil
-}
diff --git a/volume/volume_linux_test.go b/volume/volume_linux_test.go
deleted file mode 100644
index 40ce552..0000000
--- a/volume/volume_linux_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// +build linux
-
-package volume
-
-import (
-	"strings"
-	"testing"
-
-	mounttypes "github.com/docker/docker/api/types/mount"
-)
-
-func TestConvertTmpfsOptions(t *testing.T) {
-	type testCase struct {
-		opt                  mounttypes.TmpfsOptions
-		readOnly             bool
-		expectedSubstrings   []string
-		unexpectedSubstrings []string
-	}
-	cases := []testCase{
-		{
-			opt:                  mounttypes.TmpfsOptions{SizeBytes: 1024 * 1024, Mode: 0700},
-			readOnly:             false,
-			expectedSubstrings:   []string{"size=1m", "mode=700"},
-			unexpectedSubstrings: []string{"ro"},
-		},
-		{
-			opt:                  mounttypes.TmpfsOptions{},
-			readOnly:             true,
-			expectedSubstrings:   []string{"ro"},
-			unexpectedSubstrings: []string{},
-		},
-	}
-	for _, c := range cases {
-		data, err := ConvertTmpfsOptions(&c.opt, c.readOnly)
-		if err != nil {
-			t.Fatalf("could not convert %+v (readOnly: %v) to string: %v",
-				c.opt, c.readOnly, err)
-		}
-		t.Logf("data=%q", data)
-		for _, s := range c.expectedSubstrings {
-			if !strings.Contains(data, s) {
-				t.Fatalf("expected substring: %s, got %v (case=%+v)", s, data, c)
-			}
-		}
-		for _, s := range c.unexpectedSubstrings {
-			if strings.Contains(data, s) {
-				t.Fatalf("unexpected substring: %s, got %v (case=%+v)", s, data, c)
-			}
-		}
-	}
-}
diff --git a/volume/volume_propagation_linux.go b/volume/volume_propagation_linux.go
deleted file mode 100644
index 1de57ab..0000000
--- a/volume/volume_propagation_linux.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// +build linux
-
-package volume
-
-import (
-	"strings"
-
-	mounttypes "github.com/docker/docker/api/types/mount"
-)
-
-// DefaultPropagationMode defines what propagation mode should be used by
-// default if user has not specified one explicitly.
-// propagation modes
-const DefaultPropagationMode = mounttypes.PropagationRPrivate
-
-var propagationModes = map[mounttypes.Propagation]bool{
-	mounttypes.PropagationPrivate:  true,
-	mounttypes.PropagationRPrivate: true,
-	mounttypes.PropagationSlave:    true,
-	mounttypes.PropagationRSlave:   true,
-	mounttypes.PropagationShared:   true,
-	mounttypes.PropagationRShared:  true,
-}
-
-// GetPropagation extracts and returns the mount propagation mode. If there
-// are no specifications, then by default it is "private".
-func GetPropagation(mode string) mounttypes.Propagation {
-	for _, o := range strings.Split(mode, ",") {
-		prop := mounttypes.Propagation(o)
-		if propagationModes[prop] {
-			return prop
-		}
-	}
-	return DefaultPropagationMode
-}
-
-// HasPropagation checks if there is a valid propagation mode present in
-// passed string. Returns true if a valid propagation mode specifier is
-// present, false otherwise.
-func HasPropagation(mode string) bool {
-	for _, o := range strings.Split(mode, ",") {
-		if propagationModes[mounttypes.Propagation(o)] {
-			return true
-		}
-	}
-	return false
-}
diff --git a/volume/volume_propagation_linux_test.go b/volume/volume_propagation_linux_test.go
deleted file mode 100644
index 46d0265..0000000
--- a/volume/volume_propagation_linux_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// +build linux
-
-package volume
-
-import (
-	"strings"
-	"testing"
-)
-
-func TestParseMountRawPropagation(t *testing.T) {
-	var (
-		valid   []string
-		invalid map[string]string
-	)
-
-	valid = []string{
-		"/hostPath:/containerPath:shared",
-		"/hostPath:/containerPath:rshared",
-		"/hostPath:/containerPath:slave",
-		"/hostPath:/containerPath:rslave",
-		"/hostPath:/containerPath:private",
-		"/hostPath:/containerPath:rprivate",
-		"/hostPath:/containerPath:ro,shared",
-		"/hostPath:/containerPath:ro,slave",
-		"/hostPath:/containerPath:ro,private",
-		"/hostPath:/containerPath:ro,z,shared",
-		"/hostPath:/containerPath:ro,Z,slave",
-		"/hostPath:/containerPath:Z,ro,slave",
-		"/hostPath:/containerPath:slave,Z,ro",
-		"/hostPath:/containerPath:Z,slave,ro",
-		"/hostPath:/containerPath:slave,ro,Z",
-		"/hostPath:/containerPath:rslave,ro,Z",
-		"/hostPath:/containerPath:ro,rshared,Z",
-		"/hostPath:/containerPath:ro,Z,rprivate",
-	}
-	invalid = map[string]string{
-		"/path:/path:ro,rshared,rslave":   `invalid mode`,
-		"/path:/path:ro,z,rshared,rslave": `invalid mode`,
-		"/path:shared":                    "invalid volume specification",
-		"/path:slave":                     "invalid volume specification",
-		"/path:private":                   "invalid volume specification",
-		"name:/absolute-path:shared":      "invalid volume specification",
-		"name:/absolute-path:rshared":     "invalid volume specification",
-		"name:/absolute-path:slave":       "invalid volume specification",
-		"name:/absolute-path:rslave":      "invalid volume specification",
-		"name:/absolute-path:private":     "invalid volume specification",
-		"name:/absolute-path:rprivate":    "invalid volume specification",
-	}
-
-	for _, path := range valid {
-		if _, err := ParseMountRaw(path, "local"); err != nil {
-			t.Fatalf("ParseMountRaw(`%q`) should succeed: error %q", path, err)
-		}
-	}
-
-	for path, expectedError := range invalid {
-		if _, err := ParseMountRaw(path, "local"); err == nil {
-			t.Fatalf("ParseMountRaw(`%q`) should have failed validation. Err %v", path, err)
-		} else {
-			if !strings.Contains(err.Error(), expectedError) {
-				t.Fatalf("ParseMountRaw(`%q`) error should contain %q, got %v", path, expectedError, err.Error())
-			}
-		}
-	}
-}
diff --git a/volume/volume_propagation_unsupported.go b/volume/volume_propagation_unsupported.go
deleted file mode 100644
index 7311ffc..0000000
--- a/volume/volume_propagation_unsupported.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// +build !linux
-
-package volume
-
-import mounttypes "github.com/docker/docker/api/types/mount"
-
-// DefaultPropagationMode is used only in linux. In other cases it returns
-// empty string.
-const DefaultPropagationMode mounttypes.Propagation = ""
-
-// propagation modes not supported on this platform.
-var propagationModes = map[mounttypes.Propagation]bool{}
-
-// GetPropagation is not supported. Return empty string.
-func GetPropagation(mode string) mounttypes.Propagation {
-	return DefaultPropagationMode
-}
-
-// HasPropagation checks if there is a valid propagation mode present in
-// passed string. Returns true if a valid propagation mode specifier is
-// present, false otherwise.
-func HasPropagation(mode string) bool {
-	return false
-}
diff --git a/volume/volume_test.go b/volume/volume_test.go
index 5c3e0e3..9f2020d 100644
--- a/volume/volume_test.go
+++ b/volume/volume_test.go
@@ -10,14 +10,84 @@
 	"github.com/docker/docker/api/types/mount"
 )
 
-func TestParseMountRaw(t *testing.T) {
-	var (
-		valid   []string
-		invalid map[string]string
-	)
+type parseMountRawTestSet struct {
+	valid   []string
+	invalid map[string]string
+}
 
-	if runtime.GOOS == "windows" {
-		valid = []string{
+func TestConvertTmpfsOptions(t *testing.T) {
+	type testCase struct {
+		opt                  mount.TmpfsOptions
+		readOnly             bool
+		expectedSubstrings   []string
+		unexpectedSubstrings []string
+	}
+	cases := []testCase{
+		{
+			opt:                  mount.TmpfsOptions{SizeBytes: 1024 * 1024, Mode: 0700},
+			readOnly:             false,
+			expectedSubstrings:   []string{"size=1m", "mode=700"},
+			unexpectedSubstrings: []string{"ro"},
+		},
+		{
+			opt:                  mount.TmpfsOptions{},
+			readOnly:             true,
+			expectedSubstrings:   []string{"ro"},
+			unexpectedSubstrings: []string{},
+		},
+	}
+	p := &linuxParser{}
+	for _, c := range cases {
+		data, err := p.ConvertTmpfsOptions(&c.opt, c.readOnly)
+		if err != nil {
+			t.Fatalf("could not convert %+v (readOnly: %v) to string: %v",
+				c.opt, c.readOnly, err)
+		}
+		t.Logf("data=%q", data)
+		for _, s := range c.expectedSubstrings {
+			if !strings.Contains(data, s) {
+				t.Fatalf("expected substring: %s, got %v (case=%+v)", s, data, c)
+			}
+		}
+		for _, s := range c.unexpectedSubstrings {
+			if strings.Contains(data, s) {
+				t.Fatalf("unexpected substring: %s, got %v (case=%+v)", s, data, c)
+			}
+		}
+	}
+}
+
+type mockFiProvider struct{}
+
+func (mockFiProvider) fileInfo(path string) (exists, isDir bool, err error) {
+	dirs := map[string]struct{}{
+		`c:\`:                    {},
+		`c:\windows\`:            {},
+		`c:\windows`:             {},
+		`c:\program files`:       {},
+		`c:\Windows`:             {},
+		`c:\Program Files (x86)`: {},
+		`\\?\c:\windows\`:        {},
+	}
+	files := map[string]struct{}{
+		`c:\windows\system32\ntdll.dll`: {},
+	}
+	if _, ok := dirs[path]; ok {
+		return true, true, nil
+	}
+	if _, ok := files[path]; ok {
+		return true, false, nil
+	}
+	return false, false, nil
+}
+
+func TestParseMountRaw(t *testing.T) {
+
+	previousProvider := currentFileInfoProvider
+	defer func() { currentFileInfoProvider = previousProvider }()
+	currentFileInfoProvider = mockFiProvider{}
+	windowsSet := parseMountRawTestSet{
+		valid: []string{
 			`d:\`,
 			`d:`,
 			`d:\path`,
@@ -35,10 +105,14 @@
 			`name:D::RO`,
 			`c:/:d:/forward/slashes/are/good/too`,
 			`c:/:d:/including with/spaces:ro`,
-			`c:\Windows`,             // With capital
-			`c:\Program Files (x86)`, // With capitals and brackets
-		}
-		invalid = map[string]string{
+			`c:\Windows`,                // With capital
+			`c:\Program Files (x86)`,    // With capitals and brackets
+			`\\?\c:\windows\:d:`,        // Long path handling (source)
+			`c:\windows\:\\?\d:\`,       // Long path handling (target)
+			`\\.\pipe\foo:\\.\pipe\foo`, // named pipe
+			`//./pipe/foo://./pipe/foo`, // named pipe forward slashes
+		},
+		invalid: map[string]string{
 			``:                                 "invalid volume specification: ",
 			`.`:                                "invalid volume specification: ",
 			`..\`:                              "invalid volume specification: ",
@@ -82,10 +156,79 @@
 			`lpt8:d:`:                          `cannot be a reserved word for Windows filenames`,
 			`lpt9:d:`:                          `cannot be a reserved word for Windows filenames`,
 			`c:\windows\system32\ntdll.dll`:    `Only directories can be mapped on this platform`,
-		}
-
-	} else {
-		valid = []string{
+			`\\.\pipe\foo:c:\pipe`:             `'c:\pipe' is not a valid pipe path`,
+		},
+	}
+	lcowSet := parseMountRawTestSet{
+		valid: []string{
+			`/foo`,
+			`/foo/`,
+			`/foo bar`,
+			`c:\:/foo`,
+			`c:\windows\:/foo`,
+			`c:\windows:/s p a c e`,
+			`c:\windows:/s p a c e:RW`,
+			`c:\program files:/s p a c e i n h o s t d i r`,
+			`0123456789name:/foo`,
+			`MiXeDcAsEnAmE:/foo`,
+			`name:/foo`,
+			`name:/foo:rW`,
+			`name:/foo:RW`,
+			`name:/foo:RO`,
+			`c:/:/forward/slashes/are/good/too`,
+			`c:/:/including with/spaces:ro`,
+			`/Program Files (x86)`, // With capitals and brackets
+		},
+		invalid: map[string]string{
+			``:                                   "invalid volume specification: ",
+			`.`:                                  "invalid volume specification: ",
+			`c:`:                                 "invalid volume specification: ",
+			`c:\`:                                "invalid volume specification: ",
+			`../`:                                "invalid volume specification: ",
+			`c:\:../`:                            "invalid volume specification: ",
+			`c:\:/foo:xyzzy`:                     "invalid volume specification: ",
+			`/`:                                  "destination can't be '/'",
+			`/..`:                                "destination can't be '/'",
+			`c:\notexist:/foo`:                   `source path does not exist`,
+			`c:\windows\system32\ntdll.dll:/foo`: `source path must be a directory`,
+			`name<:/foo`:                         `invalid volume specification`,
+			`name>:/foo`:                         `invalid volume specification`,
+			`name::/foo`:                         `invalid volume specification`,
+			`name":/foo`:                         `invalid volume specification`,
+			`name\:/foo`:                         `invalid volume specification`,
+			`name*:/foo`:                         `invalid volume specification`,
+			`name|:/foo`:                         `invalid volume specification`,
+			`name?:/foo`:                         `invalid volume specification`,
+			`name/:/foo`:                         `invalid volume specification`,
+			`/foo:rw`:                            `invalid volume specification`,
+			`/foo:ro`:                            `invalid volume specification`,
+			`con:/foo`:                           `cannot be a reserved word for Windows filenames`,
+			`PRN:/foo`:                           `cannot be a reserved word for Windows filenames`,
+			`aUx:/foo`:                           `cannot be a reserved word for Windows filenames`,
+			`nul:/foo`:                           `cannot be a reserved word for Windows filenames`,
+			`com1:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com2:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com3:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com4:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com5:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com6:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com7:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com8:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`com9:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt1:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt2:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt3:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt4:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt5:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt6:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt7:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt8:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`lpt9:/foo`:                          `cannot be a reserved word for Windows filenames`,
+			`\\.\pipe\foo:/foo`:                  `Linux containers on Windows do not support named pipe mounts`,
+		},
+	}
+	linuxSet := parseMountRawTestSet{
+		valid: []string{
 			"/home",
 			"/home:/home",
 			"/home:/something/else",
@@ -95,47 +238,87 @@
 			"hostPath:/containerPath:ro",
 			"/hostPath:/containerPath:rw",
 			"/rw:/ro",
-		}
-		invalid = map[string]string{
-			"":                "invalid volume specification",
-			"./":              "mount path must be absolute",
-			"../":             "mount path must be absolute",
-			"/:../":           "mount path must be absolute",
-			"/:path":          "mount path must be absolute",
-			":":               "invalid volume specification",
-			"/tmp:":           "invalid volume specification",
-			":test":           "invalid volume specification",
-			":/test":          "invalid volume specification",
-			"tmp:":            "invalid volume specification",
-			":test:":          "invalid volume specification",
-			"::":              "invalid volume specification",
-			":::":             "invalid volume specification",
-			"/tmp:::":         "invalid volume specification",
-			":/tmp::":         "invalid volume specification",
-			"/path:rw":        "invalid volume specification",
-			"/path:ro":        "invalid volume specification",
-			"/rw:rw":          "invalid volume specification",
-			"path:ro":         "invalid volume specification",
-			"/path:/path:sw":  `invalid mode`,
-			"/path:/path:rwz": `invalid mode`,
-		}
+			"/hostPath:/containerPath:shared",
+			"/hostPath:/containerPath:rshared",
+			"/hostPath:/containerPath:slave",
+			"/hostPath:/containerPath:rslave",
+			"/hostPath:/containerPath:private",
+			"/hostPath:/containerPath:rprivate",
+			"/hostPath:/containerPath:ro,shared",
+			"/hostPath:/containerPath:ro,slave",
+			"/hostPath:/containerPath:ro,private",
+			"/hostPath:/containerPath:ro,z,shared",
+			"/hostPath:/containerPath:ro,Z,slave",
+			"/hostPath:/containerPath:Z,ro,slave",
+			"/hostPath:/containerPath:slave,Z,ro",
+			"/hostPath:/containerPath:Z,slave,ro",
+			"/hostPath:/containerPath:slave,ro,Z",
+			"/hostPath:/containerPath:rslave,ro,Z",
+			"/hostPath:/containerPath:ro,rshared,Z",
+			"/hostPath:/containerPath:ro,Z,rprivate",
+		},
+		invalid: map[string]string{
+			"":                                "invalid volume specification",
+			"./":                              "mount path must be absolute",
+			"../":                             "mount path must be absolute",
+			"/:../":                           "mount path must be absolute",
+			"/:path":                          "mount path must be absolute",
+			":":                               "invalid volume specification",
+			"/tmp:":                           "invalid volume specification",
+			":test":                           "invalid volume specification",
+			":/test":                          "invalid volume specification",
+			"tmp:":                            "invalid volume specification",
+			":test:":                          "invalid volume specification",
+			"::":                              "invalid volume specification",
+			":::":                             "invalid volume specification",
+			"/tmp:::":                         "invalid volume specification",
+			":/tmp::":                         "invalid volume specification",
+			"/path:rw":                        "invalid volume specification",
+			"/path:ro":                        "invalid volume specification",
+			"/rw:rw":                          "invalid volume specification",
+			"path:ro":                         "invalid volume specification",
+			"/path:/path:sw":                  `invalid mode`,
+			"/path:/path:rwz":                 `invalid mode`,
+			"/path:/path:ro,rshared,rslave":   `invalid mode`,
+			"/path:/path:ro,z,rshared,rslave": `invalid mode`,
+			"/path:shared":                    "invalid volume specification",
+			"/path:slave":                     "invalid volume specification",
+			"/path:private":                   "invalid volume specification",
+			"name:/absolute-path:shared":      "invalid volume specification",
+			"name:/absolute-path:rshared":     "invalid volume specification",
+			"name:/absolute-path:slave":       "invalid volume specification",
+			"name:/absolute-path:rslave":      "invalid volume specification",
+			"name:/absolute-path:private":     "invalid volume specification",
+			"name:/absolute-path:rprivate":    "invalid volume specification",
+		},
 	}
 
-	for _, path := range valid {
-		if _, err := ParseMountRaw(path, "local"); err != nil {
-			t.Fatalf("ParseMountRaw(`%q`) should succeed: error %q", path, err)
-		}
-	}
+	linParser := &linuxParser{}
+	winParser := &windowsParser{}
+	lcowParser := &lcowParser{}
+	tester := func(parser Parser, set parseMountRawTestSet) {
 
-	for path, expectedError := range invalid {
-		if mp, err := ParseMountRaw(path, "local"); err == nil {
-			t.Fatalf("ParseMountRaw(`%q`) should have failed validation. Err '%v' - MP: %v", path, err, mp)
-		} else {
-			if !strings.Contains(err.Error(), expectedError) {
-				t.Fatalf("ParseMountRaw(`%q`) error should contain %q, got %v", path, expectedError, err.Error())
+		for _, path := range set.valid {
+
+			if _, err := parser.ParseMountRaw(path, "local"); err != nil {
+				t.Errorf("ParseMountRaw(`%q`) should succeed: error %q", path, err)
+			}
+		}
+
+		for path, expectedError := range set.invalid {
+			if mp, err := parser.ParseMountRaw(path, "local"); err == nil {
+				t.Errorf("ParseMountRaw(`%q`) should have failed validation. Err '%v' - MP: %v", path, err, mp)
+			} else {
+				if !strings.Contains(err.Error(), expectedError) {
+					t.Errorf("ParseMountRaw(`%q`) error should contain %q, got %v", path, expectedError, err.Error())
+				}
 			}
 		}
 	}
+	tester(linParser, linuxSet)
+	tester(winParser, windowsSet)
+	tester(lcowParser, lcowSet)
+
 }
 
 // testParseMountRaw is a structure used by TestParseMountRawSplit for
@@ -143,6 +326,7 @@
 type testParseMountRaw struct {
 	bind      string
 	driver    string
+	expType   mount.Type
 	expDest   string
 	expSource string
 	expName   string
@@ -152,69 +336,96 @@
 }
 
 func TestParseMountRawSplit(t *testing.T) {
-	var cases []testParseMountRaw
-	if runtime.GOOS == "windows" {
-		cases = []testParseMountRaw{
-			{`c:\:d:`, "local", `d:`, `c:\`, ``, "", true, false},
-			{`c:\:d:\`, "local", `d:\`, `c:\`, ``, "", true, false},
-			{`c:\:d:\:ro`, "local", `d:\`, `c:\`, ``, "", false, false},
-			{`c:\:d:\:rw`, "local", `d:\`, `c:\`, ``, "", true, false},
-			{`c:\:d:\:foo`, "local", `d:\`, `c:\`, ``, "", false, true},
-			{`name:d::rw`, "local", `d:`, ``, `name`, "local", true, false},
-			{`name:d:`, "local", `d:`, ``, `name`, "local", true, false},
-			{`name:d::ro`, "local", `d:`, ``, `name`, "local", false, false},
-			{`name:c:`, "", ``, ``, ``, "", true, true},
-			{`driver/name:c:`, "", ``, ``, ``, "", true, true},
-		}
-	} else {
-		cases = []testParseMountRaw{
-			{"/tmp:/tmp1", "", "/tmp1", "/tmp", "", "", true, false},
-			{"/tmp:/tmp2:ro", "", "/tmp2", "/tmp", "", "", false, false},
-			{"/tmp:/tmp3:rw", "", "/tmp3", "/tmp", "", "", true, false},
-			{"/tmp:/tmp4:foo", "", "", "", "", "", false, true},
-			{"name:/named1", "", "/named1", "", "name", "", true, false},
-			{"name:/named2", "external", "/named2", "", "name", "external", true, false},
-			{"name:/named3:ro", "local", "/named3", "", "name", "local", false, false},
-			{"local/name:/tmp:rw", "", "/tmp", "", "local/name", "", true, false},
-			{"/tmp:tmp", "", "", "", "", "", true, true},
-		}
+	previousProvider := currentFileInfoProvider
+	defer func() { currentFileInfoProvider = previousProvider }()
+	currentFileInfoProvider = mockFiProvider{}
+	windowsCases := []testParseMountRaw{
+		{`c:\:d:`, "local", mount.TypeBind, `d:`, `c:\`, ``, "", true, false},
+		{`c:\:d:\`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", true, false},
+		{`c:\:d:\:ro`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", false, false},
+		{`c:\:d:\:rw`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", true, false},
+		{`c:\:d:\:foo`, "local", mount.TypeBind, `d:\`, `c:\`, ``, "", false, true},
+		{`name:d::rw`, "local", mount.TypeVolume, `d:`, ``, `name`, "local", true, false},
+		{`name:d:`, "local", mount.TypeVolume, `d:`, ``, `name`, "local", true, false},
+		{`name:d::ro`, "local", mount.TypeVolume, `d:`, ``, `name`, "local", false, false},
+		{`name:c:`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
+		{`driver/name:c:`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
+		{`\\.\pipe\foo:\\.\pipe\bar`, "local", mount.TypeNamedPipe, `\\.\pipe\bar`, `\\.\pipe\foo`, "", "", true, false},
+		{`\\.\pipe\foo:c:\foo\bar`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
+		{`c:\foo\bar:\\.\pipe\foo`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
 	}
-
-	for i, c := range cases {
-		t.Logf("case %d", i)
-		m, err := ParseMountRaw(c.bind, c.driver)
-		if c.fail {
-			if err == nil {
-				t.Fatalf("Expected error, was nil, for spec %s\n", c.bind)
+	lcowCases := []testParseMountRaw{
+		{`c:\:/foo`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", true, false},
+		{`c:\:/foo:ro`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", false, false},
+		{`c:\:/foo:rw`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", true, false},
+		{`c:\:/foo:foo`, "local", mount.TypeBind, `/foo`, `c:\`, ``, "", false, true},
+		{`name:/foo:rw`, "local", mount.TypeVolume, `/foo`, ``, `name`, "local", true, false},
+		{`name:/foo`, "local", mount.TypeVolume, `/foo`, ``, `name`, "local", true, false},
+		{`name:/foo:ro`, "local", mount.TypeVolume, `/foo`, ``, `name`, "local", false, false},
+		{`name:/`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
+		{`driver/name:/`, "", mount.TypeVolume, ``, ``, ``, "", true, true},
+		{`\\.\pipe\foo:\\.\pipe\bar`, "local", mount.TypeNamedPipe, `\\.\pipe\bar`, `\\.\pipe\foo`, "", "", true, true},
+		{`\\.\pipe\foo:/data`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
+		{`c:\foo\bar:\\.\pipe\foo`, "local", mount.TypeNamedPipe, ``, ``, "", "", true, true},
+	}
+	linuxCases := []testParseMountRaw{
+		{"/tmp:/tmp1", "", mount.TypeBind, "/tmp1", "/tmp", "", "", true, false},
+		{"/tmp:/tmp2:ro", "", mount.TypeBind, "/tmp2", "/tmp", "", "", false, false},
+		{"/tmp:/tmp3:rw", "", mount.TypeBind, "/tmp3", "/tmp", "", "", true, false},
+		{"/tmp:/tmp4:foo", "", mount.TypeBind, "", "", "", "", false, true},
+		{"name:/named1", "", mount.TypeVolume, "/named1", "", "name", "", true, false},
+		{"name:/named2", "external", mount.TypeVolume, "/named2", "", "name", "external", true, false},
+		{"name:/named3:ro", "local", mount.TypeVolume, "/named3", "", "name", "local", false, false},
+		{"local/name:/tmp:rw", "", mount.TypeVolume, "/tmp", "", "local/name", "", true, false},
+		{"/tmp:tmp", "", mount.TypeBind, "", "", "", "", true, true},
+	}
+	linParser := &linuxParser{}
+	winParser := &windowsParser{}
+	lcowParser := &lcowParser{}
+	tester := func(parser Parser, cases []testParseMountRaw) {
+		for i, c := range cases {
+			t.Logf("case %d", i)
+			m, err := parser.ParseMountRaw(c.bind, c.driver)
+			if c.fail {
+				if err == nil {
+					t.Errorf("Expected error, was nil, for spec %s\n", c.bind)
+				}
+				continue
 			}
-			continue
-		}
 
-		if m == nil || err != nil {
-			t.Fatalf("ParseMountRaw failed for spec '%s', driver '%s', error '%v'", c.bind, c.driver, err.Error())
-			continue
-		}
+			if m == nil || err != nil {
+				t.Errorf("ParseMountRaw failed for spec '%s', driver '%s', error '%v'", c.bind, c.driver, err.Error())
+				continue
+			}
 
-		if m.Destination != c.expDest {
-			t.Fatalf("Expected destination '%s, was %s', for spec '%s'", c.expDest, m.Destination, c.bind)
-		}
+			if m.Destination != c.expDest {
+				t.Errorf("Expected destination '%s, was %s', for spec '%s'", c.expDest, m.Destination, c.bind)
+			}
 
-		if m.Source != c.expSource {
-			t.Fatalf("Expected source '%s', was '%s', for spec '%s'", c.expSource, m.Source, c.bind)
-		}
+			if m.Source != c.expSource {
+				t.Errorf("Expected source '%s', was '%s', for spec '%s'", c.expSource, m.Source, c.bind)
+			}
 
-		if m.Name != c.expName {
-			t.Fatalf("Expected name '%s', was '%s' for spec '%s'", c.expName, m.Name, c.bind)
-		}
+			if m.Name != c.expName {
+				t.Errorf("Expected name '%s', was '%s' for spec '%s'", c.expName, m.Name, c.bind)
+			}
 
-		if m.Driver != c.expDriver {
-			t.Fatalf("Expected driver '%s', was '%s', for spec '%s'", c.expDriver, m.Driver, c.bind)
-		}
+			if m.Driver != c.expDriver {
+				t.Errorf("Expected driver '%s', was '%s', for spec '%s'", c.expDriver, m.Driver, c.bind)
+			}
 
-		if m.RW != c.expRW {
-			t.Fatalf("Expected RW '%v', was '%v' for spec '%s'", c.expRW, m.RW, c.bind)
+			if m.RW != c.expRW {
+				t.Errorf("Expected RW '%v', was '%v' for spec '%s'", c.expRW, m.RW, c.bind)
+			}
+			if m.Type != c.expType {
+				t.Fatalf("Expected type '%s', was '%s', for spec '%s'", c.expType, m.Type, c.bind)
+			}
 		}
 	}
+
+	tester(linParser, linuxCases)
+	tester(winParser, windowsCases)
+	tester(lcowParser, lcowCases)
 }
 
 func TestParseMountSpec(t *testing.T) {
@@ -227,43 +438,43 @@
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(testDir)
-
+	parser := NewParser(runtime.GOOS)
 	cases := []c{
-		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: DefaultPropagationMode}},
-		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, RW: true, Propagation: DefaultPropagationMode}},
-		{mount.Mount{Type: mount.TypeBind, Source: testDir + string(os.PathSeparator), Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: DefaultPropagationMode}},
-		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath + string(os.PathSeparator), ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: DefaultPropagationMode}},
-		{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: DefaultCopyMode}},
-		{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath + string(os.PathSeparator)}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: DefaultCopyMode}},
+		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()}},
+		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, RW: true, Propagation: parser.DefaultPropagationMode()}},
+		{mount.Mount{Type: mount.TypeBind, Source: testDir + string(os.PathSeparator), Target: testDestinationPath, ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()}},
+		{mount.Mount{Type: mount.TypeBind, Source: testDir, Target: testDestinationPath + string(os.PathSeparator), ReadOnly: true}, MountPoint{Type: mount.TypeBind, Source: testDir, Destination: testDestinationPath, Propagation: parser.DefaultPropagationMode()}},
+		{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: parser.DefaultCopyMode()}},
+		{mount.Mount{Type: mount.TypeVolume, Target: testDestinationPath + string(os.PathSeparator)}, MountPoint{Type: mount.TypeVolume, Destination: testDestinationPath, RW: true, CopyData: parser.DefaultCopyMode()}},
 	}
 
 	for i, c := range cases {
 		t.Logf("case %d", i)
-		mp, err := ParseMountSpec(c.input)
+		mp, err := parser.ParseMountSpec(c.input)
 		if err != nil {
-			t.Fatal(err)
+			t.Error(err)
 		}
 
 		if c.expected.Type != mp.Type {
-			t.Fatalf("Expected mount types to match. Expected: '%s', Actual: '%s'", c.expected.Type, mp.Type)
+			t.Errorf("Expected mount types to match. Expected: '%s', Actual: '%s'", c.expected.Type, mp.Type)
 		}
 		if c.expected.Destination != mp.Destination {
-			t.Fatalf("Expected mount destination to match. Expected: '%s', Actual: '%s'", c.expected.Destination, mp.Destination)
+			t.Errorf("Expected mount destination to match. Expected: '%s', Actual: '%s'", c.expected.Destination, mp.Destination)
 		}
 		if c.expected.Source != mp.Source {
-			t.Fatalf("Expected mount source to match. Expected: '%s', Actual: '%s'", c.expected.Source, mp.Source)
+			t.Errorf("Expected mount source to match. Expected: '%s', Actual: '%s'", c.expected.Source, mp.Source)
 		}
 		if c.expected.RW != mp.RW {
-			t.Fatalf("Expected mount writable to match. Expected: '%v', Actual: '%v'", c.expected.RW, mp.RW)
+			t.Errorf("Expected mount writable to match. Expected: '%v', Actual: '%v'", c.expected.RW, mp.RW)
 		}
 		if c.expected.Propagation != mp.Propagation {
-			t.Fatalf("Expected mount propagation to match. Expected: '%v', Actual: '%s'", c.expected.Propagation, mp.Propagation)
+			t.Errorf("Expected mount propagation to match. Expected: '%v', Actual: '%s'", c.expected.Propagation, mp.Propagation)
 		}
 		if c.expected.Driver != mp.Driver {
-			t.Fatalf("Expected mount driver to match. Expected: '%v', Actual: '%s'", c.expected.Driver, mp.Driver)
+			t.Errorf("Expected mount driver to match. Expected: '%v', Actual: '%s'", c.expected.Driver, mp.Driver)
 		}
 		if c.expected.CopyData != mp.CopyData {
-			t.Fatalf("Expected mount copy data to match. Expected: '%v', Actual: '%v'", c.expected.CopyData, mp.CopyData)
+			t.Errorf("Expected mount copy data to match. Expected: '%v', Actual: '%v'", c.expected.CopyData, mp.CopyData)
 		}
 	}
 }
diff --git a/volume/volume_unix.go b/volume/volume_unix.go
index e35b70c..0968fe3 100644
--- a/volume/volume_unix.go
+++ b/volume/volume_unix.go
@@ -4,145 +4,15 @@
 
 import (
 	"fmt"
-	"os"
 	"path/filepath"
 	"strings"
-
-	mounttypes "github.com/docker/docker/api/types/mount"
 )
 
-var platformRawValidationOpts = []func(o *validateOpts){
-	// need to make sure to not error out if the bind source does not exist on unix
-	// this is supported for historical reasons, the path will be automatically
-	// created later.
-	func(o *validateOpts) { o.skipBindSourceCheck = true },
-}
-
-// read-write modes
-var rwModes = map[string]bool{
-	"rw": true,
-	"ro": true,
-}
-
-// label modes
-var labelModes = map[string]bool{
-	"Z": true,
-	"z": true,
-}
-
-// consistency modes
-var consistencyModes = map[mounttypes.Consistency]bool{
-	mounttypes.ConsistencyFull:      true,
-	mounttypes.ConsistencyCached:    true,
-	mounttypes.ConsistencyDelegated: true,
-}
-
-// BackwardsCompatible decides whether this mount point can be
-// used in old versions of Docker or not.
-// Only bind mounts and local volumes can be used in old versions of Docker.
-func (m *MountPoint) BackwardsCompatible() bool {
-	return len(m.Source) > 0 || m.Driver == DefaultDriverName
-}
-
-// HasResource checks whether the given absolute path for a container is in
-// this mount point. If the relative path starts with `../` then the resource
-// is outside of this mount point, but we can't simply check for this prefix
-// because it misses `..` which is also outside of the mount, so check both.
-func (m *MountPoint) HasResource(absolutePath string) bool {
+func (p *linuxParser) HasResource(m *MountPoint, absolutePath string) bool {
 	relPath, err := filepath.Rel(m.Destination, absolutePath)
 	return err == nil && relPath != ".." && !strings.HasPrefix(relPath, fmt.Sprintf("..%c", filepath.Separator))
 }
 
-// IsVolumeNameValid checks a volume name in a platform specific manner.
-func IsVolumeNameValid(name string) (bool, error) {
-	return true, nil
-}
-
-// ValidMountMode will make sure the mount mode is valid.
-// returns if it's a valid mount mode or not.
-func ValidMountMode(mode string) bool {
-	if mode == "" {
-		return true
-	}
-
-	rwModeCount := 0
-	labelModeCount := 0
-	propagationModeCount := 0
-	copyModeCount := 0
-	consistencyModeCount := 0
-
-	for _, o := range strings.Split(mode, ",") {
-		switch {
-		case rwModes[o]:
-			rwModeCount++
-		case labelModes[o]:
-			labelModeCount++
-		case propagationModes[mounttypes.Propagation(o)]:
-			propagationModeCount++
-		case copyModeExists(o):
-			copyModeCount++
-		case consistencyModes[mounttypes.Consistency(o)]:
-			consistencyModeCount++
-		default:
-			return false
-		}
-	}
-
-	// Only one string for each mode is allowed.
-	if rwModeCount > 1 || labelModeCount > 1 || propagationModeCount > 1 || copyModeCount > 1 || consistencyModeCount > 1 {
-		return false
-	}
-	return true
-}
-
-// ReadWrite tells you if a mode string is a valid read-write mode or not.
-// If there are no specifications w.r.t read write mode, then by default
-// it returns true.
-func ReadWrite(mode string) bool {
-	if !ValidMountMode(mode) {
-		return false
-	}
-
-	for _, o := range strings.Split(mode, ",") {
-		if o == "ro" {
-			return false
-		}
-	}
-	return true
-}
-
-func validateNotRoot(p string) error {
-	p = filepath.Clean(convertSlash(p))
-	if p == "/" {
-		return fmt.Errorf("invalid specification: destination can't be '/'")
-	}
-	return nil
-}
-
-func validateCopyMode(mode bool) error {
-	return nil
-}
-
-func convertSlash(p string) string {
-	return filepath.ToSlash(p)
-}
-
-func splitRawSpec(raw string) ([]string, error) {
-	if strings.Count(raw, ":") > 2 {
-		return nil, errInvalidSpec(raw)
-	}
-
-	arr := strings.SplitN(raw, ":", 3)
-	if arr[0] == "" {
-		return nil, errInvalidSpec(raw)
-	}
-	return arr, nil
-}
-
-func clean(p string) string {
-	return filepath.Clean(p)
-}
-
-func validateStat(fi os.FileInfo) error {
-	return nil
+func (p *windowsParser) HasResource(m *MountPoint, absolutePath string) bool {
+	return false
 }
diff --git a/volume/volume_unsupported.go b/volume/volume_unsupported.go
deleted file mode 100644
index ff9d6af..0000000
--- a/volume/volume_unsupported.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// +build !linux
-
-package volume
-
-import (
-	"fmt"
-	"runtime"
-
-	mounttypes "github.com/docker/docker/api/types/mount"
-)
-
-// ConvertTmpfsOptions converts *mounttypes.TmpfsOptions to the raw option string
-// for mount(2).
-func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions, readOnly bool) (string, error) {
-	return "", fmt.Errorf("%s does not support tmpfs", runtime.GOOS)
-}
diff --git a/volume/volume_windows.go b/volume/volume_windows.go
index 22f6fc7..8ec1d6c 100644
--- a/volume/volume_windows.go
+++ b/volume/volume_windows.go
@@ -1,201 +1,8 @@
 package volume
 
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-	"regexp"
-	"strings"
-)
-
-// read-write modes
-var rwModes = map[string]bool{
-	"rw": true,
-}
-
-// read-only modes
-var roModes = map[string]bool{
-	"ro": true,
-}
-
-var platformRawValidationOpts = []func(*validateOpts){
-	// filepath.IsAbs is weird on Windows:
-	//	`c:` is not considered an absolute path
-	//	`c:\` is considered an absolute path
-	// In any case, the regex matching below ensures absolute paths
-	// TODO: consider this a bug with filepath.IsAbs (?)
-	func(o *validateOpts) { o.skipAbsolutePathCheck = true },
-}
-
-const (
-	// Spec should be in the format [source:]destination[:mode]
-	//
-	// Examples: c:\foo bar:d:rw
-	//           c:\foo:d:\bar
-	//           myname:d:
-	//           d:\
-	//
-	// Explanation of this regex! Thanks @thaJeztah on IRC and gist for help. See
-	// https://gist.github.com/thaJeztah/6185659e4978789fb2b2. A good place to
-	// test is https://regex-golang.appspot.com/assets/html/index.html
-	//
-	// Useful link for referencing named capturing groups:
-	// http://stackoverflow.com/questions/20750843/using-named-matches-from-go-regex
-	//
-	// There are three match groups: source, destination and mode.
-	//
-
-	// RXHostDir is the first option of a source
-	RXHostDir = `[a-z]:\\(?:[^\\/:*?"<>|\r\n]+\\?)*`
-	// RXName is the second option of a source
-	RXName = `[^\\/:*?"<>|\r\n]+`
-	// RXReservedNames are reserved names not possible on Windows
-	RXReservedNames = `(con)|(prn)|(nul)|(aux)|(com[1-9])|(lpt[1-9])`
-
-	// RXSource is the combined possibilities for a source
-	RXSource = `((?P<source>((` + RXHostDir + `)|(` + RXName + `))):)?`
-
-	// Source. Can be either a host directory, a name, or omitted:
-	//  HostDir:
-	//    -  Essentially using the folder solution from
-	//       https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch08s18.html
-	//       but adding case insensitivity.
-	//    -  Must be an absolute path such as c:\path
-	//    -  Can include spaces such as `c:\program files`
-	//    -  And then followed by a colon which is not in the capture group
-	//    -  And can be optional
-	//  Name:
-	//    -  Must not contain invalid NTFS filename characters (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx)
-	//    -  And then followed by a colon which is not in the capture group
-	//    -  And can be optional
-
-	// RXDestination is the regex expression for the mount destination
-	RXDestination = `(?P<destination>([a-z]):((?:\\[^\\/:*?"<>\r\n]+)*\\?))`
-	// Destination (aka container path):
-	//    -  Variation on hostdir but can be a drive followed by colon as well
-	//    -  If a path, must be absolute. Can include spaces
-	//    -  Drive cannot be c: (explicitly checked in code, not RegEx)
-
-	// RXMode is the regex expression for the mode of the mount
-	// Mode (optional):
-	//    -  Hopefully self explanatory in comparison to above regex's.
-	//    -  Colon is not in the capture group
-	RXMode = `(:(?P<mode>(?i)ro|rw))?`
-)
-
-// BackwardsCompatible decides whether this mount point can be
-// used in old versions of Docker or not.
-// Windows volumes are never backwards compatible.
-func (m *MountPoint) BackwardsCompatible() bool {
+func (p *windowsParser) HasResource(m *MountPoint, absolutePath string) bool {
 	return false
 }
-
-func splitRawSpec(raw string) ([]string, error) {
-	specExp := regexp.MustCompile(`^` + RXSource + RXDestination + RXMode + `$`)
-	match := specExp.FindStringSubmatch(strings.ToLower(raw))
-
-	// Must have something back
-	if len(match) == 0 {
-		return nil, errInvalidSpec(raw)
-	}
-
-	var split []string
-	matchgroups := make(map[string]string)
-	// Pull out the sub expressions from the named capture groups
-	for i, name := range specExp.SubexpNames() {
-		matchgroups[name] = strings.ToLower(match[i])
-	}
-	if source, exists := matchgroups["source"]; exists {
-		if source != "" {
-			split = append(split, source)
-		}
-	}
-	if destination, exists := matchgroups["destination"]; exists {
-		if destination != "" {
-			split = append(split, destination)
-		}
-	}
-	if mode, exists := matchgroups["mode"]; exists {
-		if mode != "" {
-			split = append(split, mode)
-		}
-	}
-	// Fix #26329. If the destination appears to be a file, and the source is null,
-	// it may be because we've fallen through the possible naming regex and hit a
-	// situation where the user intention was to map a file into a container through
-	// a local volume, but this is not supported by the platform.
-	if matchgroups["source"] == "" && matchgroups["destination"] != "" {
-		validName, err := IsVolumeNameValid(matchgroups["destination"])
-		if err != nil {
-			return nil, err
-		}
-		if !validName {
-			if fi, err := os.Stat(matchgroups["destination"]); err == nil {
-				if !fi.IsDir() {
-					return nil, fmt.Errorf("file '%s' cannot be mapped. Only directories can be mapped on this platform", matchgroups["destination"])
-				}
-			}
-		}
-	}
-	return split, nil
-}
-
-// IsVolumeNameValid checks a volume name in a platform specific manner.
-func IsVolumeNameValid(name string) (bool, error) {
-	nameExp := regexp.MustCompile(`^` + RXName + `$`)
-	if !nameExp.MatchString(name) {
-		return false, nil
-	}
-	nameExp = regexp.MustCompile(`^` + RXReservedNames + `$`)
-	if nameExp.MatchString(name) {
-		return false, fmt.Errorf("volume name %q cannot be a reserved word for Windows filenames", name)
-	}
-	return true, nil
-}
-
-// ValidMountMode will make sure the mount mode is valid.
-// returns if it's a valid mount mode or not.
-func ValidMountMode(mode string) bool {
-	if mode == "" {
-		return true
-	}
-	return roModes[strings.ToLower(mode)] || rwModes[strings.ToLower(mode)]
-}
-
-// ReadWrite tells you if a mode string is a valid read-write mode or not.
-func ReadWrite(mode string) bool {
-	return rwModes[strings.ToLower(mode)] || mode == ""
-}
-
-func validateNotRoot(p string) error {
-	p = strings.ToLower(convertSlash(p))
-	if p == "c:" || p == `c:\` {
-		return fmt.Errorf("destination path cannot be `c:` or `c:\\`: %v", p)
-	}
-	return nil
-}
-
-func validateCopyMode(mode bool) error {
-	if mode {
-		return fmt.Errorf("Windows does not support copying image path content")
-	}
-	return nil
-}
-
-func convertSlash(p string) string {
-	return filepath.FromSlash(p)
-}
-
-func clean(p string) string {
-	if match, _ := regexp.MatchString("^[a-z]:$", p); match {
-		return p
-	}
-	return filepath.Clean(p)
-}
-
-func validateStat(fi os.FileInfo) error {
-	if !fi.IsDir() {
-		return fmt.Errorf("source path must be a directory")
-	}
-	return nil
+func (p *linuxParser) HasResource(m *MountPoint, absolutePath string) bool {
+	return false
 }
diff --git a/volume/windows_parser.go b/volume/windows_parser.go
new file mode 100644
index 0000000..172610d
--- /dev/null
+++ b/volume/windows_parser.go
@@ -0,0 +1,456 @@
+package volume
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"regexp"
+	"runtime"
+	"strings"
+
+	"github.com/docker/docker/api/types/mount"
+	"github.com/docker/docker/pkg/stringid"
+)
+
+type windowsParser struct {
+}
+
+const (
+	// Spec should be in the format [source:]destination[:mode]
+	//
+	// Examples: c:\foo bar:d:rw
+	//           c:\foo:d:\bar
+	//           myname:d:
+	//           d:\
+	//
+	// Explanation of this regex! Thanks @thaJeztah on IRC and gist for help. See
+	// https://gist.github.com/thaJeztah/6185659e4978789fb2b2. A good place to
+	// test is https://regex-golang.appspot.com/assets/html/index.html
+	//
+	// Useful link for referencing named capturing groups:
+	// http://stackoverflow.com/questions/20750843/using-named-matches-from-go-regex
+	//
+	// There are three match groups: source, destination and mode.
+	//
+
+	// rxHostDir is the first option of a source
+	rxHostDir = `(?:\\\\\?\\)?[a-z]:[\\/](?:[^\\/:*?"<>|\r\n]+[\\/]?)*`
+	// rxName is the second option of a source
+	rxName = `[^\\/:*?"<>|\r\n]+`
+
+	// RXReservedNames are reserved names not possible on Windows
+	rxReservedNames = `(con)|(prn)|(nul)|(aux)|(com[1-9])|(lpt[1-9])`
+
+	// rxPipe is a named path pipe (starts with `\\.\pipe\`, possibly with / instead of \)
+	rxPipe = `[/\\]{2}.[/\\]pipe[/\\][^:*?"<>|\r\n]+`
+	// rxSource is the combined possibilities for a source
+	rxSource = `((?P<source>((` + rxHostDir + `)|(` + rxName + `)|(` + rxPipe + `))):)?`
+
+	// Source. Can be either a host directory, a name, or omitted:
+	//  HostDir:
+	//    -  Essentially using the folder solution from
+	//       https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch08s18.html
+	//       but adding case insensitivity.
+	//    -  Must be an absolute path such as c:\path
+	//    -  Can include spaces such as `c:\program files`
+	//    -  And then followed by a colon which is not in the capture group
+	//    -  And can be optional
+	//  Name:
+	//    -  Must not contain invalid NTFS filename characters (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx)
+	//    -  And then followed by a colon which is not in the capture group
+	//    -  And can be optional
+
+	// rxDestination is the regex expression for the mount destination
+	rxDestination = `(?P<destination>((?:\\\\\?\\)?([a-z]):((?:[\\/][^\\/:*?"<>\r\n]+)*[\\/]?))|(` + rxPipe + `))`
+
+	rxLCOWDestination = `(?P<destination>/(?:[^\\/:*?"<>\r\n]+[/]?)*)`
+	// Destination (aka container path):
+	//    -  Variation on hostdir but can be a drive followed by colon as well
+	//    -  If a path, must be absolute. Can include spaces
+	//    -  Drive cannot be c: (explicitly checked in code, not RegEx)
+
+	// rxMode is the regex expression for the mode of the mount
+	// Mode (optional):
+	//    -  Hopefully self explanatory in comparison to above regex's.
+	//    -  Colon is not in the capture group
+	rxMode = `(:(?P<mode>(?i)ro|rw))?`
+)
+
+type mountValidator func(mnt *mount.Mount) error
+
+func windowsSplitRawSpec(raw, destRegex string) ([]string, error) {
+	specExp := regexp.MustCompile(`^` + rxSource + destRegex + rxMode + `$`)
+	match := specExp.FindStringSubmatch(strings.ToLower(raw))
+
+	// Must have something back
+	if len(match) == 0 {
+		return nil, errInvalidSpec(raw)
+	}
+
+	var split []string
+	matchgroups := make(map[string]string)
+	// Pull out the sub expressions from the named capture groups
+	for i, name := range specExp.SubexpNames() {
+		matchgroups[name] = strings.ToLower(match[i])
+	}
+	if source, exists := matchgroups["source"]; exists {
+		if source != "" {
+			split = append(split, source)
+		}
+	}
+	if destination, exists := matchgroups["destination"]; exists {
+		if destination != "" {
+			split = append(split, destination)
+		}
+	}
+	if mode, exists := matchgroups["mode"]; exists {
+		if mode != "" {
+			split = append(split, mode)
+		}
+	}
+	// Fix #26329. If the destination appears to be a file, and the source is null,
+	// it may be because we've fallen through the possible naming regex and hit a
+	// situation where the user intention was to map a file into a container through
+	// a local volume, but this is not supported by the platform.
+	if matchgroups["source"] == "" && matchgroups["destination"] != "" {
+		volExp := regexp.MustCompile(`^` + rxName + `$`)
+		reservedNameExp := regexp.MustCompile(`^` + rxReservedNames + `$`)
+
+		if volExp.MatchString(matchgroups["destination"]) {
+			if reservedNameExp.MatchString(matchgroups["destination"]) {
+				return nil, fmt.Errorf("volume name %q cannot be a reserved word for Windows filenames", matchgroups["destination"])
+			}
+		} else {
+
+			exists, isDir, _ := currentFileInfoProvider.fileInfo(matchgroups["destination"])
+			if exists && !isDir {
+				return nil, fmt.Errorf("file '%s' cannot be mapped. Only directories can be mapped on this platform", matchgroups["destination"])
+
+			}
+		}
+	}
+	return split, nil
+}
+
+func windowsValidMountMode(mode string) bool {
+	if mode == "" {
+		return true
+	}
+	return rwModes[strings.ToLower(mode)]
+}
+func windowsValidateNotRoot(p string) error {
+	p = strings.ToLower(strings.Replace(p, `/`, `\`, -1))
+	if p == "c:" || p == `c:\` {
+		return fmt.Errorf("destination path cannot be `c:` or `c:\\`: %v", p)
+	}
+	return nil
+}
+
+var windowsSpecificValidators mountValidator = func(mnt *mount.Mount) error {
+	return windowsValidateNotRoot(mnt.Target)
+}
+
+func windowsValidateRegex(p, r string) error {
+	if regexp.MustCompile(`^` + r + `$`).MatchString(strings.ToLower(p)) {
+		return nil
+	}
+	return fmt.Errorf("invalid mount path: '%s'", p)
+}
+func windowsValidateAbsolute(p string) error {
+	if err := windowsValidateRegex(p, rxDestination); err != nil {
+		return fmt.Errorf("invalid mount path: '%s' mount path must be absolute", p)
+	}
+	return nil
+}
+
+func windowsDetectMountType(p string) mount.Type {
+	if strings.HasPrefix(p, `\\.\pipe\`) {
+		return mount.TypeNamedPipe
+	} else if regexp.MustCompile(`^` + rxHostDir + `$`).MatchString(p) {
+		return mount.TypeBind
+	} else {
+		return mount.TypeVolume
+	}
+}
+
+func (p *windowsParser) ReadWrite(mode string) bool {
+	return strings.ToLower(mode) != "ro"
+}
+
+// IsVolumeNameValid checks a volume name in a platform specific manner.
+func (p *windowsParser) ValidateVolumeName(name string) error {
+	nameExp := regexp.MustCompile(`^` + rxName + `$`)
+	if !nameExp.MatchString(name) {
+		return errors.New("invalid volume name")
+	}
+	nameExp = regexp.MustCompile(`^` + rxReservedNames + `$`)
+	if nameExp.MatchString(name) {
+		return fmt.Errorf("volume name %q cannot be a reserved word for Windows filenames", name)
+	}
+	return nil
+}
+func (p *windowsParser) validateMountConfig(mnt *mount.Mount) error {
+	return p.validateMountConfigReg(mnt, rxDestination, windowsSpecificValidators)
+}
+
+type fileInfoProvider interface {
+	fileInfo(path string) (exist, isDir bool, err error)
+}
+
+type defaultFileInfoProvider struct {
+}
+
+func (defaultFileInfoProvider) fileInfo(path string) (exist, isDir bool, err error) {
+	fi, err := os.Stat(path)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return false, false, err
+		}
+		return false, false, nil
+	}
+	return true, fi.IsDir(), nil
+}
+
+var currentFileInfoProvider fileInfoProvider = defaultFileInfoProvider{}
+
+func (p *windowsParser) validateMountConfigReg(mnt *mount.Mount, destRegex string, additionalValidators ...mountValidator) error {
+
+	for _, v := range additionalValidators {
+		if err := v(mnt); err != nil {
+			return &errMountConfig{mnt, err}
+		}
+	}
+	if len(mnt.Target) == 0 {
+		return &errMountConfig{mnt, errMissingField("Target")}
+	}
+
+	if err := windowsValidateRegex(mnt.Target, destRegex); err != nil {
+		return &errMountConfig{mnt, err}
+	}
+
+	switch mnt.Type {
+	case mount.TypeBind:
+		if len(mnt.Source) == 0 {
+			return &errMountConfig{mnt, errMissingField("Source")}
+		}
+		// Don't error out just because the propagation mode is not supported on the platform
+		if opts := mnt.BindOptions; opts != nil {
+			if len(opts.Propagation) > 0 {
+				return &errMountConfig{mnt, fmt.Errorf("invalid propagation mode: %s", opts.Propagation)}
+			}
+		}
+		if mnt.VolumeOptions != nil {
+			return &errMountConfig{mnt, errExtraField("VolumeOptions")}
+		}
+
+		if err := windowsValidateAbsolute(mnt.Source); err != nil {
+			return &errMountConfig{mnt, err}
+		}
+
+		exists, isdir, err := currentFileInfoProvider.fileInfo(mnt.Source)
+		if err != nil {
+			return &errMountConfig{mnt, err}
+		}
+		if !exists {
+			return &errMountConfig{mnt, errBindNotExist}
+		}
+		if !isdir {
+			return &errMountConfig{mnt, fmt.Errorf("source path must be a directory")}
+		}
+
+	case mount.TypeVolume:
+		if mnt.BindOptions != nil {
+			return &errMountConfig{mnt, errExtraField("BindOptions")}
+		}
+
+		if len(mnt.Source) == 0 && mnt.ReadOnly {
+			return &errMountConfig{mnt, fmt.Errorf("must not set ReadOnly mode when using anonymous volumes")}
+		}
+
+		if len(mnt.Source) != 0 {
+			if err := p.ValidateVolumeName(mnt.Source); err != nil {
+				return &errMountConfig{mnt, err}
+			}
+		}
+	case mount.TypeNamedPipe:
+		if len(mnt.Source) == 0 {
+			return &errMountConfig{mnt, errMissingField("Source")}
+		}
+
+		if mnt.BindOptions != nil {
+			return &errMountConfig{mnt, errExtraField("BindOptions")}
+		}
+
+		if mnt.ReadOnly {
+			return &errMountConfig{mnt, errExtraField("ReadOnly")}
+		}
+
+		if windowsDetectMountType(mnt.Source) != mount.TypeNamedPipe {
+			return &errMountConfig{mnt, fmt.Errorf("'%s' is not a valid pipe path", mnt.Source)}
+		}
+
+		if windowsDetectMountType(mnt.Target) != mount.TypeNamedPipe {
+			return &errMountConfig{mnt, fmt.Errorf("'%s' is not a valid pipe path", mnt.Target)}
+		}
+	default:
+		return &errMountConfig{mnt, errors.New("mount type unknown")}
+	}
+	return nil
+}
+func (p *windowsParser) ParseMountRaw(raw, volumeDriver string) (*MountPoint, error) {
+	return p.parseMountRaw(raw, volumeDriver, rxDestination, true, windowsSpecificValidators)
+}
+
+func (p *windowsParser) parseMountRaw(raw, volumeDriver, destRegex string, convertTargetToBackslash bool, additionalValidators ...mountValidator) (*MountPoint, error) {
+	arr, err := windowsSplitRawSpec(raw, destRegex)
+	if err != nil {
+		return nil, err
+	}
+
+	var spec mount.Mount
+	var mode string
+	switch len(arr) {
+	case 1:
+		// Just a destination path in the container
+		spec.Target = arr[0]
+	case 2:
+		if windowsValidMountMode(arr[1]) {
+			// Destination + Mode is not a valid volume - volumes
+			// cannot include a mode. e.g. /foo:rw
+			return nil, errInvalidSpec(raw)
+		}
+		// Host Source Path or Name + Destination
+		spec.Source = strings.Replace(arr[0], `/`, `\`, -1)
+		spec.Target = arr[1]
+	case 3:
+		// HostSourcePath+DestinationPath+Mode
+		spec.Source = strings.Replace(arr[0], `/`, `\`, -1)
+		spec.Target = arr[1]
+		mode = arr[2]
+	default:
+		return nil, errInvalidSpec(raw)
+	}
+	if convertTargetToBackslash {
+		spec.Target = strings.Replace(spec.Target, `/`, `\`, -1)
+	}
+
+	if !windowsValidMountMode(mode) {
+		return nil, errInvalidMode(mode)
+	}
+
+	spec.Type = windowsDetectMountType(spec.Source)
+	spec.ReadOnly = !p.ReadWrite(mode)
+
+	// cannot assume that if a volume driver is passed in that we should set it
+	if volumeDriver != "" && spec.Type == mount.TypeVolume {
+		spec.VolumeOptions = &mount.VolumeOptions{
+			DriverConfig: &mount.Driver{Name: volumeDriver},
+		}
+	}
+
+	if copyData, isSet := getCopyMode(mode, p.DefaultCopyMode()); isSet {
+		if spec.VolumeOptions == nil {
+			spec.VolumeOptions = &mount.VolumeOptions{}
+		}
+		spec.VolumeOptions.NoCopy = !copyData
+	}
+
+	mp, err := p.parseMountSpec(spec, destRegex, convertTargetToBackslash, additionalValidators...)
+	if mp != nil {
+		mp.Mode = mode
+	}
+	if err != nil {
+		err = fmt.Errorf("%v: %v", errInvalidSpec(raw), err)
+	}
+	return mp, err
+}
+
+func (p *windowsParser) ParseMountSpec(cfg mount.Mount) (*MountPoint, error) {
+	return p.parseMountSpec(cfg, rxDestination, true, windowsSpecificValidators)
+}
+func (p *windowsParser) parseMountSpec(cfg mount.Mount, destRegex string, convertTargetToBackslash bool, additionalValidators ...mountValidator) (*MountPoint, error) {
+	if err := p.validateMountConfigReg(&cfg, destRegex, additionalValidators...); err != nil {
+		return nil, err
+	}
+	mp := &MountPoint{
+		RW:          !cfg.ReadOnly,
+		Destination: cfg.Target,
+		Type:        cfg.Type,
+		Spec:        cfg,
+	}
+	if convertTargetToBackslash {
+		mp.Destination = strings.Replace(cfg.Target, `/`, `\`, -1)
+	}
+
+	switch cfg.Type {
+	case mount.TypeVolume:
+		if cfg.Source == "" {
+			mp.Name = stringid.GenerateNonCryptoID()
+		} else {
+			mp.Name = cfg.Source
+		}
+		mp.CopyData = p.DefaultCopyMode()
+
+		if cfg.VolumeOptions != nil {
+			if cfg.VolumeOptions.DriverConfig != nil {
+				mp.Driver = cfg.VolumeOptions.DriverConfig.Name
+			}
+			if cfg.VolumeOptions.NoCopy {
+				mp.CopyData = false
+			}
+		}
+	case mount.TypeBind:
+		mp.Source = strings.Replace(cfg.Source, `/`, `\`, -1)
+	case mount.TypeNamedPipe:
+		mp.Source = strings.Replace(cfg.Source, `/`, `\`, -1)
+	}
+	// cleanup trailing `\` except for paths like `c:\`
+	if len(mp.Source) > 3 && mp.Source[len(mp.Source)-1] == '\\' {
+		mp.Source = mp.Source[:len(mp.Source)-1]
+	}
+	if len(mp.Destination) > 3 && mp.Destination[len(mp.Destination)-1] == '\\' {
+		mp.Destination = mp.Destination[:len(mp.Destination)-1]
+	}
+	return mp, nil
+}
+
+func (p *windowsParser) ParseVolumesFrom(spec string) (string, string, error) {
+	if len(spec) == 0 {
+		return "", "", fmt.Errorf("volumes-from specification cannot be an empty string")
+	}
+
+	specParts := strings.SplitN(spec, ":", 2)
+	id := specParts[0]
+	mode := "rw"
+
+	if len(specParts) == 2 {
+		mode = specParts[1]
+		if !windowsValidMountMode(mode) {
+			return "", "", errInvalidMode(mode)
+		}
+
+		// Do not allow copy modes on volumes-from
+		if _, isSet := getCopyMode(mode, p.DefaultCopyMode()); isSet {
+			return "", "", errInvalidMode(mode)
+		}
+	}
+	return id, mode, nil
+}
+
+func (p *windowsParser) DefaultPropagationMode() mount.Propagation {
+	return mount.Propagation("")
+}
+
+func (p *windowsParser) ConvertTmpfsOptions(opt *mount.TmpfsOptions, readOnly bool) (string, error) {
+	return "", fmt.Errorf("%s does not support tmpfs", runtime.GOOS)
+}
+func (p *windowsParser) DefaultCopyMode() bool {
+	return false
+}
+func (p *windowsParser) IsBackwardCompatible(m *MountPoint) bool {
+	return false
+}
+
+func (p *windowsParser) ValidateTmpfsMountDestination(dest string) error {
+	return errors.New("Platform does not support tmpfs")
+}