[dev.go2go] all: merge origin/master@5c4ab5c

Change-Id: I8d2de06cd35143ec1f28ca53a03581d95abde250
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/241617
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Ahmed W. <oneofone@gmail.com>
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index db389d5..0000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,93 +0,0 @@
-name: build
-
-on: [push, pull_request]
-
-jobs:
-  build:
-    name: ${{ matrix.os }} ${{ matrix.version }}
-    runs-on: ${{ matrix.os }}
-    
-    if: "!contains(github.event.head_commit.message, 'SKIP CI')"
-    timeout-minutes: 20
-    strategy:
-      fail-fast: false
-      matrix:
-        os: [ubuntu-latest]
-        version: ['stable']
-
-    steps:
-      - name: Clone repository
-        uses: actions/checkout@v2
-
-      - name: Setup Node
-        uses: actions/setup-node@v1
-        with:
-          node-version: '10.x'
-
-      - name: Setup Go
-        uses: actions/setup-go@v1
-        with:
-         go-version: '1.14'
-
-      - name: Install dependencies
-        run: npm ci
-      
-      - name: Compile
-        run: npm run vscode:prepublish
-
-      - name: Install Go tools (Modules mode)
-        run: |
-            go version
-            go get github.com/acroca/go-symbols \
-               github.com/davidrjenni/reftools/cmd/fillstruct \
-               github.com/haya14busa/goplay/cmd/goplay \
-               github.com/mdempsky/gocode \
-               github.com/sqs/goreturns \
-               github.com/uudashr/gopkgs/v2/cmd/gopkgs \
-               github.com/zmb3/gogetdoc \
-               golang.org/x/lint/golint \
-               golang.org/x/tools/cmd/gorename \
-               golang.org/x/tools/gopls
-        env:
-          GO111MODULE: on   
-          
-      - name: Install Go tools (GOPATH mode)
-        run: |
-          go version
-          go get github.com/cweill/gotests/... \
-            github.com/rogpeppe/godef \
-            github.com/ramya-rao-a/go-outline
-            # Because some tests depend on the source code checked in GOPATH. TODO: FIX THEM.
-        env:
-          GO111MODULE: off
-      
-      - name: Run unit tests
-        run: npm run unit-test
-        continue-on-error: true
-        
-      - name: Run tests
-        uses: GabrielBB/xvfb-action@v1.0
-        with:
-          run: npm run test
-        env:
-          CODE_VERSION: ${{ matrix.version }}
-
-  eslint:
-    runs-on: ubuntu-latest
-    if: "!contains(github.event.head_commit.message, 'SKIP CI')"
-
-    steps:
-      - name: Clone repository
-        uses: actions/checkout@v1
-
-      - name: Setup Node
-        uses: actions/setup-node@v1
-        with:
-          node-version: '10.x'
-
-      - name: Install Dependencies
-        run: 'npm ci'
-        shell: bash
-
-      - name: Lint check
-        run: npm run lint
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 79139db..0000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: "Code scanning - action"
-
-on:
-  push:
-  schedule:
-    - cron: '0 22 * * 1'
-
-jobs:
-  CodeQL-Build:
-
-    # CodeQL runs on ubuntu-latest and windows-latest
-    runs-on: ubuntu-latest
-
-    steps:
-    - name: Checkout repository
-      uses: actions/checkout@v2
-
-    # Initializes the CodeQL tools for scanning.
-    - name: Initialize CodeQL
-      uses: github/codeql-action/init@v1
-      with:
-        languages: go, javascript
-
-    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
-    # If this step fails, then you should remove it and run the build manually (see below)
-    - name: Autobuild
-      uses: github/codeql-action/autobuild@v1
-
-    # ℹī¸ Command-line programs to run using the OS shell.
-    # 📚 https://git.io/JvXDl
-
-    # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines
-    #    and modify them (or add more) to build your code if your project
-    #    uses a compiled language
-
-    #- run: |
-    #   make bootstrap
-    #   make release
-
-    - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml
new file mode 100644
index 0000000..8110c20
--- /dev/null
+++ b/.github/workflows/release-nightly.yml
@@ -0,0 +1,88 @@
+name: Release (golang.go-nightly)
+
+# Daily release on 15:00 UTC, monday-thursday.
+# Or, force to release by triggering repository_dispatch events by using
+#   curl -v -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/golang/vscode-go/dispatches -d '{ "event_type": "force-release" }'
+on:
+  schedule:
+    - cron: "0 15 * * MON-THU"  # 15 UTC, monday-thursday daily
+  repository_dispatch:
+    types: [force-release]
+
+jobs:
+  release:
+    if: github.ref == 'refs/heads/master' && github.repository == 'golang/vscode-go'
+
+    name: Release Nightly
+    runs-on: ubuntu-latest
+    timeout-minutes: 20
+
+    steps:
+      - name: Clone repository
+        uses: actions/checkout@v2
+
+      - name: Setup Node
+        uses: actions/setup-node@v1
+        with:
+          node-version: '10.x'
+
+      - name: Setup Go
+        uses: actions/setup-go@v1
+        with:
+         go-version: '1.14'
+
+      - name: Install dependencies
+        run: npm ci
+
+      - name: Prepare Release
+        run: build/all.bash prepare_nightly
+
+      - name: Compile
+        run: npm run vscode:prepublish
+
+      - name: Install Go tools (Modules mode)
+        run: |
+            go version
+            go get github.com/acroca/go-symbols \
+               github.com/davidrjenni/reftools/cmd/fillstruct \
+               github.com/haya14busa/goplay/cmd/goplay \
+               github.com/mdempsky/gocode \
+               github.com/sqs/goreturns \
+               github.com/uudashr/gopkgs/v2/cmd/gopkgs \
+               github.com/zmb3/gogetdoc \
+               golang.org/x/lint/golint \
+               golang.org/x/tools/cmd/gorename \
+               golang.org/x/tools/gopls
+
+        env:
+          GO111MODULE: on
+
+      - name: Install Go tools (GOPATH mode)
+        run: |
+          go version
+          go get github.com/cweill/gotests/... \
+            github.com/rogpeppe/godef \
+            github.com/ramya-rao-a/go-outline
+            # Because some tests depend on the source code checked in GOPATH. TODO: FIX THEM.
+        env:
+          GO111MODULE: off
+
+
+      - name: Run unit tests
+        run: npm run unit-test
+
+      - name: Run tests
+        uses: GabrielBB/xvfb-action@v1.0
+        with:
+          run: npm run test
+        env:
+          CODE_VERSION: 'insiders'
+          VSCODEGO_BEFORE_RELEASE_TESTS: true
+
+      - name: Publish
+        if: github.ref == 'refs/heads/master' && github.repository == 'golang/vscode-go'
+        uses: lannonbr/vsce-action@704da577da0f27de5cdb4ae018374c2f08b5f523
+        with:
+          args: "publish -p $VSCE_TOKEN"
+        env:
+          VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index db14834..c984375 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,86 +1,108 @@
-name: release
+name: Release (golang.go)
 
-# Daily release on 15:00 UTC, monday-thursday.
-# Or, force to release by triggering repository_dispatch events by using
-#   curl -v -H "Accept: application/vnd.github.everest-preview+json" -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/golang/vscode-go/dispatches -d '{ "event_type": "force-release" }'
+# The new release workflow is triggered when a new tag on the release
+# branch is pushed.
+#
+# Note: our canonical repository is in go.googlesource.com/vscode-go and tagging
+# will be done in the canonical repository, and mirrored to the github repository.
+# A typical workflow is:
+#
+# 1. A human operator creates a CL to merge the main dev branch to the 'release' branch.
+#    CI (GCB builder) will test the CL.
+# 2. The CL is reviewed and merged. This triggers the "Long test workflow" (test-long.yml).
+# 3. The human operator verifies the "Long test workflow" is green.
+#    Otherwise, fix (fix, cherry-pick, review, commit) on the 'release' branch.
+# 4. When the 'release' branch reaches to the state ready for the release,
+#    the human operator will tag the commig from the canonical repository.
+#    (https://go-review.googlesource.com/admin/repos/vscode-go,tags)
+#    Stable versions should be in the format of 'vX.X.X' (e.g. v0.15.0)
+#    Release candidates should be in the format of 'vX.X.X-rc.X' (e.g. v0.15.0-rc.1)
+# 5. The gopherbot will mirror the tag to the GitHub repo, and that push will trigger
+#    the 'Release (golang.go)' workflow specified in this file.
+#      - For stable version release (vX.X.X), check if the package.json has the matching version.
+#      - Packaging using 'vsce package'
+#      - Create a release in GitHub
+#      - Upload the vsix file as an asset of the release
+#      - For stable version release (vX.X.X), upload to the vscode market place
+
 on:
-  schedule:
-    - cron: "0 15 * * MON-THU"  # 15 UTC, monday-thursday daily
-  repository_dispatch:
-    types: [force-release]
+  push:
+    tags:
+      - v*
 
 jobs:
   release:
-    name: Release Nightly
+    name: create release
     runs-on: ubuntu-latest
-    timeout-minutes: 20
+    if: github.repository == 'golang/vscode-go'
 
     steps:
-      - name: Clone repository
+      - name: checkout code
         uses: actions/checkout@v2
 
-      - name: Setup Node
-        uses: actions/setup-node@v1
-        with:
-          node-version: '10.x'
-
-      - name: Setup Go
-        uses: actions/setup-go@v1
-        with:
-         go-version: '1.14'
-
-      - name: Install dependencies
-        run: npm ci
-
-      - name: Prepare Release
-        run: build/all.bash prepare_nightly
-
-      - name: Compile
-        run: npm run vscode:prepublish
-
-      - name: Install Go tools (Modules mode)
+      - name: get release version
+        id: release_version
         run: |
-            go version
-            go get github.com/acroca/go-symbols \
-               github.com/davidrjenni/reftools/cmd/fillstruct \
-               github.com/haya14busa/goplay/cmd/goplay \
-               github.com/mdempsky/gocode \
-               github.com/sqs/goreturns \
-               github.com/uudashr/gopkgs/v2/cmd/gopkgs \
-               github.com/zmb3/gogetdoc \
-               golang.org/x/lint/golint \
-               golang.org/x/tools/cmd/gorename \
-               golang.org/x/tools/gopls
+          TAGGED_VERSION="${GITHUB_REF/refs\/tags\/v/}"
 
-        env:
-          GO111MODULE: on
+          if [[ ! "${TAGGED_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
+            echo "Invalid version tag '${TAGGED_VERSION}'"
+            exit 1
+          fi
 
-      - name: Install Go tools (GOPATH mode)
+          echo ::set-env name=EXT_VERSION::"${TAGGED_VERSION}"
+          WRITTEN_VERSION="$(cat package.json | jq '.version' -r)"
+
+          if [[ ${TAGGED_VERSION} == *"-"* ]]; then
+            echo ::set-env name=EXT_ISPREVIEW::1
+          else
+            if [[ "${TAGGED_VERSION}" != "${WRITTEN_VERSION}" ]]; then
+              echo "Release Tag and Version in package.json do not match: '${TAGGED_VERSION}' vs '${WRITTEN_VERSION}'"
+              exit 1
+            fi
+            echo ::set-env name=EXT_ISPREVIEW::0
+          fi
+
+      - name: stamp version
         run: |
-          go version
-          go get github.com/cweill/gotests/... \
-            github.com/rogpeppe/godef \
-            github.com/ramya-rao-a/go-outline
-            # Because some tests depend on the source code checked in GOPATH. TODO: FIX THEM.
-        env:
-          GO111MODULE: off
+          cat package.json | jq --arg VER "${{ env.EXT_VERSION }}" '.version=$VER' > /tmp/package.json 
+          cp /tmp/package.json ./package.json
+          npm ci
+          npm run vscode:prepublish
 
-
-      - name: Run unit tests
-        run: npm run unit-test
-        continue-on-error: true
-
-      - name: Run tests
-        uses: GabrielBB/xvfb-action@v1.0
+      - name: package
+        uses: lannonbr/vsce-action@704da577da0f27de5cdb4ae018374c2f08b5f523
         with:
-          run: npm run test
-        env:
-          CODE_VERSION: 'insiders'
+          args: "package"
 
-      - name: Publish
-        if: github.ref == 'refs/heads/master' && github.repository == 'golang/vscode-go'
+      - name: create release
+        id: create_release
+        uses: actions/create-release@v1
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          tag_name: ${{ github.ref }}
+          release_name: Release ${{ env.EXT_VERSION }}
+          draft: false
+          prerelease: ${{env.EXT_ISPREVIEW == 1}}
+
+      - name: upload release asset
+        uses: actions/upload-release-asset@v1
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          upload_url: ${{ steps.create_release.outputs.upload_url }}
+          asset_path: ./go-${{ env.EXT_VERSION }}.vsix
+          asset_name: go-${{ env.EXT_VERSION }}.vsix
+          asset_content_type: application/zip
+
+      - name: publish
+        if: env.EXT_ISPREVIEW != 1 && github.repository == 'golang/vscode-go'
         uses: lannonbr/vsce-action@704da577da0f27de5cdb4ae018374c2f08b5f523
         with:
           args: "publish -p $VSCE_TOKEN"
         env:
           VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }}
+
+# TODO: check if the commit is in green state. (test-long.yml results)
+# TODO: after publishing, create a gerrit CL to update 'latest' branch if VERSION is for a stable version.
diff --git a/.github/workflows/test-long.yml b/.github/workflows/test-long.yml
new file mode 100644
index 0000000..6fcbbd7
--- /dev/null
+++ b/.github/workflows/test-long.yml
@@ -0,0 +1,82 @@
+name: Long Tests
+
+on:
+  push:
+    branches-ignore:
+      - 'latest'
+      - 'upstream'
+
+jobs:
+  build:
+    name: ${{ matrix.os }} ${{ matrix.version }}
+    runs-on: ${{ matrix.os }}
+
+    # Not containing 'SKIP CI' in the commit message AND
+    # (Either non-Windows OR triggered on 'push' (if triggered by 'pull_request', github.base_ref is not empty)
+    if: github.repository == 'golang/vscode-go' && !contains(github.event.head_commit.message, 'SKIP CI')
+    timeout-minutes: 20
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, windows-latest, macos-latest]
+        version: ['stable']
+
+    steps:
+      - name: Clone repository
+        uses: actions/checkout@v2
+
+      - name: Setup Node
+        uses: actions/setup-node@v1
+        with:
+          node-version: '10.x'
+
+      - name: Setup Go
+        uses: actions/setup-go@v1
+        with:
+         go-version: '1.14'
+
+      - name: Install dependencies
+        run: npm ci
+      
+      - name: Compile
+        run: npm run vscode:prepublish
+
+      - name: Install Go tools (Modules mode)
+        run: |
+            go version
+            go get github.com/acroca/go-symbols
+            go get github.com/davidrjenni/reftools/cmd/fillstruct
+            go get github.com/haya14busa/goplay/cmd/goplay
+            go get github.com/mdempsky/gocode
+            go get github.com/sqs/goreturns
+            go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
+            go get github.com/zmb3/gogetdoc
+            go get golang.org/x/lint/golint
+            go get golang.org/x/tools/cmd/gorename
+            go get golang.org/x/tools/gopls
+        env:
+          GO111MODULE: on   
+          
+      - name: Install Go tools (GOPATH mode)
+        run: |
+          go version
+          go get github.com/cweill/gotests/...
+          go get github.com/rogpeppe/godef
+          go get github.com/ramya-rao-a/go-outline
+            # Because some tests depend on the source code checked in GOPATH. TODO: FIX THEM.
+        env:
+          GO111MODULE: off
+      
+      - name: Run unit tests
+        run: npm run unit-test
+        
+      - name: Run tests
+        uses: GabrielBB/xvfb-action@v1.0
+        with:
+          run: npm run test
+        env:
+          CODE_VERSION: ${{ matrix.version }}
+      
+      - name: Lint check
+        run: npm run lint
+        if: ${{ matrix.os }} == 'ubuntu-latest'
diff --git a/.github/workflows/test-smoke.yml b/.github/workflows/test-smoke.yml
new file mode 100644
index 0000000..150b21a
--- /dev/null
+++ b/.github/workflows/test-smoke.yml
@@ -0,0 +1,78 @@
+name: Smoke Tests
+
+on: [pull_request]
+
+jobs:
+  build:
+    name: ${{ matrix.os }} ${{ matrix.version }}
+    runs-on: ${{ matrix.os }}
+    
+    # Not containing 'SKIP CI' in the commit message AND
+    # (Either non-Windows OR triggered on 'push' (if triggered by 'pull_request', github.base_ref is not empty)
+    if: "!contains(github.event.head_commit.message, 'SKIP CI')"
+    timeout-minutes: 20
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest]
+        version: ['stable']
+
+    steps:
+      - name: Clone repository
+        uses: actions/checkout@v2
+
+      - name: Setup Node
+        uses: actions/setup-node@v1
+        with:
+          node-version: '10.x'
+
+      - name: Setup Go
+        uses: actions/setup-go@v1
+        with:
+         go-version: '1.14'
+
+      - name: Install dependencies
+        run: npm ci
+      
+      - name: Compile
+        run: npm run vscode:prepublish
+
+      - name: Install Go tools (Modules mode)
+        run: |
+            go version
+            go get github.com/acroca/go-symbols
+            go get github.com/davidrjenni/reftools/cmd/fillstruct
+            go get github.com/haya14busa/goplay/cmd/goplay
+            go get github.com/mdempsky/gocode
+            go get github.com/sqs/goreturns
+            go get github.com/uudashr/gopkgs/v2/cmd/gopkgs
+            go get github.com/zmb3/gogetdoc
+            go get golang.org/x/lint/golint
+            go get golang.org/x/tools/cmd/gorename
+            go get golang.org/x/tools/gopls
+        env:
+          GO111MODULE: on   
+          
+      - name: Install Go tools (GOPATH mode)
+        run: |
+          go version
+          go get github.com/cweill/gotests/...
+          go get github.com/rogpeppe/godef
+          go get github.com/ramya-rao-a/go-outline
+            # Because some tests depend on the source code checked in GOPATH. TODO: FIX THEM.
+        env:
+          GO111MODULE: off
+      
+      - name: Run unit tests
+        run: npm run unit-test
+        
+      - name: Run tests
+        uses: GabrielBB/xvfb-action@v1.0
+        with:
+          run: npm run test
+        env:
+          CODE_VERSION: ${{ matrix.version }}
+
+      - name: Lint check
+        run: npm run lint
+        if: ${{ matrix.os }} == 'ubuntu-latest'
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 68d1f87..d71de02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
-out
-node_modules
-.vscode-test
+out/
+dist/
+node_modules/
+.vscode-test/
 .DS_Store
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c6761bb..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-language: go
-
-dist: bionic
-
-go:
-  - 1.13.x
-  - 1.14.x
-  - tip
-
-git:
-  depth: 1
-
-matrix:
-  allow_failures:
-    - go: tip
-
-os:
-  - osx
-  - linux
-
-before_install:
-  # Call xvfb directly on linux runs and give it time to start
-  - if [[ $TRAVIS_OS_NAME == "linux" ]]; then
-    export DISPLAY=:99.0;
-    Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
-    sleep 3;
-    sudo apt-get update && sudo apt-get install -y libsecret-1-0;
-    fi
-
-install:
-  - TRAVIS_NODE_VERSION="12";
-  # Clear out whatever version of NVM Travis has as it is old.
-  - rm -rf ~/.nvm;
-    # Grab NVM.
-  - git clone https://github.com/creationix/nvm.git ~/.nvm;
-    # Checkout the latest stable tag.
-    # Note that you can just hardcode a preferred version here.
-  - (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`);
-    # Install the desired version of Node
-  - source ~/.nvm/nvm.sh;
-  - nvm install $TRAVIS_NODE_VERSION;
-  - npm ci
-  - npm run vscode:prepublish
-  - go get -u -v github.com/acroca/go-symbols
-  - go get -u -v github.com/cweill/gotests/...
-  - go get -u -v github.com/davidrjenni/reftools/cmd/fillstruct
-  - go get -u -v github.com/haya14busa/goplay/cmd/goplay
-  - go get -u -v github.com/mdempsky/gocode
-  - go get -u -v github.com/ramya-rao-a/go-outline
-  - go get -u -v github.com/rogpeppe/godef
-  - go get -u -v github.com/sqs/goreturns
-  - go get -u -v github.com/uudashr/gopkgs/v2/cmd/gopkgs
-  - go get -u -v github.com/zmb3/gogetdoc
-  - go get -u -v golang.org/x/lint/golint
-  - go get -u -v golang.org/x/tools/cmd/gorename
-  - GO111MODULE=on go get golang.org/x/tools/gopls
-
-script:
-  - npm run lint
-  - npm run unit-test
-  - npm test --silent
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 94310ec..46902e2 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,7 +1,6 @@
 {
 	"version": "0.2.0",
 	"configurations": [
-		
 		{
 			"name": "Launch Extension",
 			"type": "extensionHost",
@@ -35,6 +34,21 @@
 			"preLaunchTask": "npm"
 		},
 		{
+			"name": "Launch as server (dlv dap)",
+			"type": "node",
+			"protocol": "inspector",
+			"request": "launch",
+			"program": "${workspaceFolder}/out/src/debugAdapter2/goDlvDebugMain.js",
+			"args": [
+				"--server=4711"
+			],
+			"sourceMaps": true,
+			"outFiles": [
+				"${workspaceFolder}/out/**/*.js"
+			],
+			"preLaunchTask": "npm"
+		},
+		{
 			"name": "Launch Extension Tests",
 			"type": "extensionHost",
 			"request": "launch",
@@ -99,4 +113,4 @@
 			]
 		}
 	]
-}
\ No newline at end of file
+}
diff --git a/.vscodeignore b/.vscodeignore
index 5de5988..b122d37 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -1,14 +1,19 @@
-src/**/*
 test/
 third_party/
-typings/**/*
-.vscode/**/*
+typings/
+.vscode/
 tsconfig.json
 .gitignore
-node_modules/fs-extra
 **/*.map
 **/tslint.json
-build/**/*
+build/
 docs/
 *.md.nightly
 .github/**/*
+.prettierrc.json
+.vscode-test/**
+SECURITY.md
+node_modules
+out/
+src/
+webpack.config.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 052c17e..d829289 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,55 @@
+## v0.15.1 - 7th July, 2020
+
+### Enhancement
+
+- Improved `gopls` error report suggestion and changed to send reports to the vscode-go issue tracker instead of the go issue tracker ([cl/240506](https://golang.org/cl/240506)). 
+
+### Fixed
+
+- Removed the `preview` note in the published extension ([Issue 273](https://github.com/golang/vscode-go/issues/273)).
+
+## v0.15.0 - 29th June, 2020
+
+### New Features
+
+- The new command `Go: Subtest At Cursor` runs an individual subtest if the subtest's name is a simple string ([cl/235447](https://golang.org/cl/235447)).
+- The new setting `go.trace.server` controls tracing between VS Code and the language server ([cl/232458](https://golang.org/cl/232458)). Unlike tracing using `gopls` [flags](https://github.com/golang/tools/blob/master/gopls/doc/troubleshooting.md#vs-code), this controls client-side tracing, and does not require to restart the server to change the value. This client-side trace is presented in the `gopls` output channel. The server-side trace has been moved to the new `gopls (server)` output channel ([cl/233598](https://golang.org/cl/233598)).
+- There is now a new Go version status bar item. Clicking it currently only pops up the current `GOROOT`. We plan to add Go version switch, and other features using this status bar item.
+
+### Enhancement
+
+- `Go: Add Tags To Struct Fields` prompts transform parameter input if the setting `go.addTags.promptForTags` is true ([Issue 2546](https://github.com/microsoft/vscode-go/issues/2546)).
+- `Go: Locate Go Tools` command output includes the `GOBIN` value. ([cl/235197](https://golang.org/cl/235197)).
+- Improved debugging experience
+    - The debug adapter automatically infers the mapping between remote and local paths for easy remote debugging ([cl/234020](https://golang.org/cl/234020), [Issue 45](https://github.com/golang/vscode-go/issue/45)).
+    - The debug adapter handles errors that can occur during remote connection setup ([cl/237550](https://golang.org/cl/237550), [Issue 215](https://github.com/golang/vscode-go/issue/215)).
+    - Failed watch expression evaluation no longer pops up error message windows. The error is visible in the watch window instead ([cl/236999](https://golang.org/cl/236999), [Issue 143](https://github.com/golang/vscode-go/issue/143)).
+- Better language server integration
+    - Restart the language server automatically when changes in its configuration or the language server version are detected ([cl/232598](https://golang.org/cl/232598), [cl/233159](https://golang.org/cl/233159)).
+    - Prompts user to file an issue if `gopls` crashes ([cl/233325](https://golang.org/cl/233325)).
+- `go.gopath`, `go.goroot`, `go.toolsGopath` are now [machine-overridable](https://code.visualstudio.com/api/references/contribution-points#Configuration-property-schema) ([cl/236539](https://golang.org/cl/236539), [Issue 2981](https://github.com/microsoft/vscode-go/issues/2981)).
+- The extension does not mutate the `GOROOT` environment variable any more. `go.goroot` is used to select the `go` command under the specified directory ([Issue 146](https://github.com/golang/vscode-go/issue/146)).
+- A redundant code action provider was removed when using the language server ([cl/239284](https://golang.org/cl/239284)).
+
+### Fixed
+
+- Fixed `gopls` version detection and upgrade logic when pre-release versions are involved ([cl/235524](https://golang.org/cl/235524)).
+- Processes started with `Run > Run Without Debugging (^F5)` are now cleaned up when the run sessions end ([cl/236879](https://golang.org/cl/236879)).
+- When `go.alternateTools.go` is set, the path to `$(go env GOROOT)/bin` is passed to underlying tools to ensure they use the same `go` version ([cl/239697](https://golang.org/cl/239697)).
+- Now the extension avoids invoking buggy `pgrep` on mac OS ([cl/236538](https://golang.org/cl/236538), [Issue 90](https://github.com/golang/vscode-go/issues/90)).
+
+### Code Health
+
+- More test coverage
+    - Added new tests for gopls update logic ([cl/233158](https://golang.org/cl/233158)), tools installation behavior ([cl/233557](https://golang.org/cl/233557)).
+    - Fixed Build Tags checking tests ([cl/233517](https://golang.org/cl/233517)).
+- Upgraded dependencies including websocket-extensions from 0.1.3 to 0.1.4 ([cl/228617](https://golang.org/cl/228617), [cl/236839](https://golang.org/cl/236839), [pr/3261](https://github.com/microsoft/vscode-go/pull/3261)).
+
+### Thanks
+
+Thank you for your contribution, Brayden Cloud, Bulent Rahim Kazanci, Eli Bendersky, Hana Kim, Polina Sokolova, Quoc Truong, Rebecca Stambler, Rohan Talip, Ryan Koski, Sean Caffery, Ted Silbernagel, Vincent Jo, and codekid!
+
+
 ## 0.14.3 - 21st May, 2020
 
 * [Hyang-Ah Hana Kim (@hyangah)](https://github.com/hyangah)
diff --git a/build/all.bash b/build/all.bash
index 080b74a..10c3110 100755
--- a/build/all.bash
+++ b/build/all.bash
@@ -9,7 +9,7 @@
 Usage: $0 [subcommand]
 Available subcommands:
   help      - display this help message.
-  test      - build and test locally. Some tests may fail if vscode is alreay in use.
+  test      - build and test locally. Some tests may fail if vscode is already in use.
   testlocal - build and test in a locally built container.
   ci        - build and test with headless vscode. Requires Xvfb.
 EOUSAGE
@@ -45,9 +45,12 @@
   echo "**** Run test ****"
   npm ci
   npm run compile
-  npm run lint
   npm run unit-test
   npm test --silent
+  npm run lint
+
+  echo "**** Run settings generator ****"
+  go run tools/generate.go -w=false
 }
 
 run_test_in_docker() {
@@ -77,10 +80,12 @@
 .bugs.url="https://github.com/golang/vscode-go/issues"
 ') > /tmp/package.json && mv /tmp/package.json package.json
 
-  # Replace CHANGELOG.md with CHANGELOG.md.nightly + Release commit info.
-  printf "**Release ${VER} @ ${COMMIT}** \n\n" | cat - docs/nightly/CHANGELOG.md > /tmp/CHANGELOG.md.new && mv /tmp/CHANGELOG.md.new CHANGELOG.md
+  # Replace CHANGELOG.md with CHANGELOG.md + Release commit info.
+  printf "**Release ${VER} @ ${COMMIT}** \n\n" | cat - CHANGELOG.md > /tmp/CHANGELOG.md.new && mv /tmp/CHANGELOG.md.new CHANGELOG.md
   # Replace the heading of README.md with the heading for Go Nightly.
-  sed '/^# Go for Visual Studio Code$/d' README.md | cat docs/nightly/README.md - > /tmp/README.md.new && mv /tmp/README.md.new README.md
+  sed '/^# Go for Visual Studio Code$/d' README.md | cat build/nightly/README.md - > /tmp/README.md.new && mv /tmp/README.md.new README.md
+  # Replace src/const.ts with build/nightly/const.ts.
+  cp build/nightly/const.ts src/const.ts
 }
 
 main() {
diff --git a/docs/nightly/README.md b/build/nightly/README.md
similarity index 100%
rename from docs/nightly/README.md
rename to build/nightly/README.md
diff --git a/src/telemetry.ts b/build/nightly/const.ts
similarity index 65%
rename from src/telemetry.ts
rename to build/nightly/const.ts
index b13b039..2005a46 100644
--- a/src/telemetry.ts
+++ b/build/nightly/const.ts
@@ -1,8 +1,9 @@
 /*---------------------------------------------------------
  * Copyright (C) Microsoft Corporation. All rights reserved.
+ * Modification copyright 2020 The Go Authors. All rights reserved.
  * Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------*/
 
-// TODO(hyangah): move this somewhere else (where easily modifiable during release process)
+// This file contains constants that replace constants defined in src/const.ts when building Nightly
 
 export const extensionId: string = 'golang.go2go';
diff --git a/docs/commands.md b/docs/commands.md
index 251fefe..11f0984 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -182,3 +182,7 @@
 ### `Go: Restart Language Server`
 
 Restart the running instance of the language server
+
+### `Go: Choose Go Environment`
+
+Choose a different Go version or binary for this project. (WIP)
diff --git a/docs/debugging.md b/docs/debugging.md
index e71bfe5..e5b3f47 100644
--- a/docs/debugging.md
+++ b/docs/debugging.md
@@ -345,15 +345,15 @@
 
 #### OSX
 
-This usually happens on OSX due to signing issues. See the discussions in [Microsoft/vscode-go#717](https://github.com/Microsoft/vscode-go/issues/717), [Microsoft/vscode-go#269](https://github.com/Microsoft/vscode-go/issues/269) and [derekparker/delve#357](https://github.com/derekparker/delve/issues/357).
+This usually happens on OSX due to signing issues. See the discussions in [Microsoft/vscode-go#717](https://github.com/Microsoft/vscode-go/issues/717), [Microsoft/vscode-go#269](https://github.com/Microsoft/vscode-go/issues/269) and [go-delve/delve#357](https://github.com/go-delve/delve/issues/357).
 
-**_Solution_**: You may have to uninstall dlv and install it manually as described in the [Delve instructions](https://github.com/derekparker/delve/blob/master/Documentation/installation/osx/install.md#manual-install).
+**_Solution_**: You may have to uninstall dlv and install it manually as described in the [Delve instructions](https://github.com/go-delve/delve/blob/master/Documentation/installation/osx/install.md#manual-install).
 
 #### Linux/Docker
 
 Docker has security settings preventing `ptrace(2)` operations by default within the container.
 
-**_Solution_**: To run your container insecurely, pass `--security-opt=seccomp:unconfined` to `docker run`. See [derekparker/delve#515](https://github.com/derekparker/delve/issues/515) for references.
+**_Solution_**: To run your container insecurely, pass `--security-opt=seccomp:unconfined` to `docker run`. See [go-delve/delve#515](https://github.com/go-delve/delve/issues/515) for references.
 
 #### could not launch process: exec: "lldb-server": executable file not found in $PATH
 
diff --git a/docs/nightly/CHANGELOG.md b/docs/nightly/CHANGELOG.md
deleted file mode 100644
index f93a946..0000000
--- a/docs/nightly/CHANGELOG.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## 2020.3.x
-* Set the extension name for VS Code Go Nightly(`go-nightly`).
-* Pick up the pre-release version of `gopls` if available.
-* Disabled the telemetry report for VS Code Go.
diff --git a/package-lock.json b/package-lock.json
index b74d1ae..a0e79e9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
-  "name": "go-nightly",
-  "version": "0.0.0",
+  "name": "go",
+  "version": "0.16.0-dev",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -122,15 +122,15 @@
       "dev": true
     },
     "@types/node": {
-      "version": "13.13.11",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.11.tgz",
-      "integrity": "sha512-FX7mIFKfnGCfq10DGWNhfCNxhACEeqH5uulT6wRRA1KEt7zgLe0HdrAd9/QQkObDqp2Z0KEV3OAmNgs0lTx5tQ==",
+      "version": "13.13.13",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.13.tgz",
+      "integrity": "sha512-UfvBE9oRCAJVzfR+3eWm/sdLFe/qroAPEXP3GPJ1SehQiEVgZT6NQZWYbPMiJ3UdcKM06v4j+S1lTcdWCmw+3g==",
       "dev": true
     },
     "@types/semver": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.2.0.tgz",
-      "integrity": "sha512-TbB0A8ACUWZt3Y6bQPstW9QNbhNeebdgLX4T/ZfkrswAfUzRiXrgd9seol+X379Wa589Pu4UEx9Uok0D4RjRCQ==",
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.1.tgz",
+      "integrity": "sha512-ooD/FJ8EuwlDKOI6D9HWxgIgJjMg2cuziXm/42npDC8y4NjxplBUn9loewZiBNCt44450lHAU0OSb51/UqXeag==",
       "dev": true,
       "requires": {
         "@types/node": "*"
@@ -152,15 +152,208 @@
       "dev": true
     },
     "@types/vscode": {
-      "version": "1.45.1",
-      "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.45.1.tgz",
-      "integrity": "sha512-0NO9qrrEJBO8FsqHCrFMgR2suKnwCsKBWvRSb2OzH5gs4i3QO5AhEMQYrSzDbU/wLPt7N617/rN9lPY213gmwg==",
+      "version": "1.46.0",
+      "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.46.0.tgz",
+      "integrity": "sha512-8m9wPEB2mcRqTWNKs9A9Eqs8DrQZt0qNFO8GkxBOnyW6xR//3s77SoMgb/nY1ctzACsZXwZj3YRTDsn4bAoaUw==",
+      "dev": true
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
+      "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
+      "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
+      "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
+      "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
+      "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
+      "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
+      "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
+      "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
+      "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
+      "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
+      "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
+      "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
+      "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/helper-wasm-section": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-opt": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "@webassemblyjs/wast-printer": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
+      "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
+      "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-buffer": "1.9.0",
+        "@webassemblyjs/wasm-gen": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
+      "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+        "@webassemblyjs/ieee754": "1.9.0",
+        "@webassemblyjs/leb128": "1.9.0",
+        "@webassemblyjs/utf8": "1.9.0"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
+      "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+        "@webassemblyjs/helper-api-error": "1.9.0",
+        "@webassemblyjs/helper-code-frame": "1.9.0",
+        "@webassemblyjs/helper-fsm": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
+      "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/wast-parser": "1.9.0",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
+    },
+    "acorn": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
+      "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
       "dev": true
     },
     "adm-zip": {
-      "version": "0.4.14",
-      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.14.tgz",
-      "integrity": "sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==",
+      "version": "0.4.16",
+      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
+      "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==",
       "dev": true
     },
     "agent-base": {
@@ -183,6 +376,18 @@
         "uri-js": "^4.2.2"
       }
     },
+    "ajv-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.0.tgz",
+      "integrity": "sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw==",
+      "dev": true
+    },
     "ansi-colors": {
       "version": "3.2.3",
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
@@ -214,6 +419,12 @@
         "picomatch": "^2.0.4"
       }
     },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
     "argparse": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -223,11 +434,35 @@
         "sprintf-js": "~1.0.2"
       }
     },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
     "array-filter": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz",
       "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM="
     },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
     "asn1": {
       "version": "0.2.4",
       "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
@@ -236,11 +471,70 @@
         "safer-buffer": "~2.1.0"
       }
     },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "assert": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+      "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
     "assert-plus": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
       "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
     },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "async-each": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+      "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+      "dev": true,
+      "optional": true
+    },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -252,6 +546,12 @@
       "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
       "dev": true
     },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
     "available-typed-arrays": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz",
@@ -275,6 +575,67 @@
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
       "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
     },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base64-js": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+      "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
+      "dev": true
+    },
     "bcrypt-pbkdf": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -288,12 +649,40 @@
       "resolved": "https://registry.npmjs.org/better-curry/-/better-curry-1.6.0.tgz",
       "integrity": "sha1-OPcWskyM7geiYqvEHCLDFOIOOGk="
     },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true
+    },
     "binary-extensions": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
       "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
       "dev": true
     },
+    "bindings": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "file-uri-to-path": "1.0.0"
+      }
+    },
+    "bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz",
+      "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==",
+      "dev": true
+    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -312,18 +701,195 @@
         "fill-range": "^7.0.1"
       }
     },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
     "browser-stdout": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
       "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
       "dev": true
     },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "browserify-sign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz",
+      "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.2",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "buffer": {
+      "version": "4.9.2",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+      "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        }
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
     "builtin-modules": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
       "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
       "dev": true
     },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "cacache": {
+      "version": "12.0.4",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+      "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.5",
+        "chownr": "^1.1.1",
+        "figgy-pudding": "^3.5.1",
+        "glob": "^7.1.4",
+        "graceful-fs": "^4.1.15",
+        "infer-owner": "^1.0.3",
+        "lru-cache": "^5.1.1",
+        "mississippi": "^3.0.0",
+        "mkdirp": "^0.5.1",
+        "move-concurrently": "^1.0.1",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^2.6.3",
+        "ssri": "^6.0.1",
+        "unique-filename": "^1.1.1",
+        "y18n": "^4.0.0"
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      }
+    },
     "camelcase": {
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
@@ -373,6 +939,54 @@
         "readdirp": "~3.2.0"
       }
     },
+    "chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+      "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
     "cliui": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
@@ -412,6 +1026,16 @@
         }
       }
     },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
     "color-convert": {
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -441,16 +1065,163 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "dev": true
     },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+      "dev": true
+    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
     },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "console-browserify": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+      "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+      "dev": true
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "fs-write-stream-atomic": "^1.0.8",
+        "iferr": "^0.1.5",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.0"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
     "core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
     },
+    "create-ecdh": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+      "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "requires": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        }
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
+    "cyclist": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
+      "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+      "dev": true
+    },
     "dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -463,6 +1234,7 @@
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
       "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
       "requires": {
         "ms": "2.0.0"
       }
@@ -473,6 +1245,12 @@
       "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
       "dev": true
     },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
     "deep-equal": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.3.tgz",
@@ -509,16 +1287,110 @@
         "object-keys": "^1.0.12"
       }
     },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
     "delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
       "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
     },
+    "des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "detect-file": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "dev": true
+    },
     "diff": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
       "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
     },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+      "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
     "ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -528,12 +1400,70 @@
         "safer-buffer": "^2.1.0"
       }
     },
+    "elliptic": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+      "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
     "emoji-regex": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
       "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
       "dev": true
     },
+    "emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz",
+      "integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "memory-fs": "^0.5.0",
+        "tapable": "^1.0.0"
+      }
+    },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
     "es-abstract": {
       "version": "1.17.5",
       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
@@ -612,22 +1542,188 @@
       "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
       "dev": true
     },
+    "eslint-scope": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+      "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
     "esprima": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
       "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
       "dev": true
     },
-    "eventemitter3": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
-      "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg="
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true
+    },
+    "events": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz",
+      "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==",
+      "dev": true
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "expand-tilde": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1"
+      }
     },
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
       "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
     },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "requires": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
     "extsprintf": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -651,6 +1747,19 @@
         "websocket-driver": ">=0.5.1"
       }
     },
+    "figgy-pudding": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+      "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
+      "dev": true
+    },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true,
+      "optional": true
+    },
     "fill-range": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -660,6 +1769,17 @@
         "to-regex-range": "^5.0.1"
       }
     },
+    "find-cache-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+      "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^2.0.0",
+        "pkg-dir": "^3.0.0"
+      }
+    },
     "find-up": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@@ -669,6 +1789,129 @@
         "locate-path": "^3.0.0"
       }
     },
+    "findup-sync": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+      "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+      "dev": true,
+      "requires": {
+        "detect-file": "^1.0.0",
+        "is-glob": "^4.0.0",
+        "micromatch": "^3.0.4",
+        "resolve-dir": "^1.0.1"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "^1.1.0",
+            "array-unique": "^0.3.2",
+            "extend-shallow": "^2.0.1",
+            "fill-range": "^4.0.0",
+            "isobject": "^3.0.1",
+            "repeat-element": "^1.1.2",
+            "snapdragon": "^0.8.1",
+            "snapdragon-node": "^2.0.1",
+            "split-string": "^3.0.2",
+            "to-regex": "^3.0.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "^2.0.1",
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1",
+            "to-regex-range": "^2.1.0"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "^4.0.0",
+            "array-unique": "^0.3.2",
+            "braces": "^2.3.1",
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "extglob": "^2.0.4",
+            "fragment-cache": "^0.2.1",
+            "kind-of": "^6.0.2",
+            "nanomatch": "^1.2.9",
+            "object.pick": "^1.3.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.2"
+          }
+        },
+        "to-regex-range": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+          "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+          "dev": true,
+          "requires": {
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1"
+          }
+        }
+      }
+    },
     "flat": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
@@ -678,6 +1921,22 @@
         "is-buffer": "~2.0.3"
       }
     },
+    "flush-write-stream": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+      "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.3.6"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
     "foreach": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
@@ -698,6 +1957,25 @@
         "mime-types": "^2.1.12"
       }
     },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
     "fs-extra": {
       "version": "9.0.1",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
@@ -710,6 +1988,18 @@
         "universalify": "^1.0.0"
       }
     },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "iferr": "^0.1.5",
+        "imurmurhash": "^0.1.4",
+        "readable-stream": "1 || 2"
+      }
+    },
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -733,6 +2023,12 @@
       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
       "dev": true
     },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
     "getpass": {
       "version": "0.1.7",
       "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -763,6 +2059,41 @@
         "is-glob": "^4.0.1"
       }
     },
+    "global-modules": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+      "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+      "dev": true,
+      "requires": {
+        "global-prefix": "^3.0.0"
+      },
+      "dependencies": {
+        "global-prefix": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+          "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+          "dev": true,
+          "requires": {
+            "ini": "^1.3.5",
+            "kind-of": "^6.0.2",
+            "which": "^1.3.1"
+          }
+        }
+      }
+    },
+    "global-prefix": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.2",
+        "homedir-polyfill": "^1.0.1",
+        "ini": "^1.3.4",
+        "is-windows": "^1.0.1",
+        "which": "^1.2.14"
+      }
+    },
     "graceful-fs": {
       "version": "4.2.4",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -808,16 +2139,128 @@
       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
       "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
     },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
     "he": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
       "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
       "dev": true
     },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "homedir-polyfill": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+      "dev": true,
+      "requires": {
+        "parse-passwd": "^1.0.0"
+      }
+    },
     "http-parser-js": {
-      "version": "0.4.10",
-      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz",
-      "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q="
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz",
+      "integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ=="
     },
     "http-proxy-agent": {
       "version": "2.1.0",
@@ -850,6 +2293,12 @@
         "sshpk": "^1.7.0"
       }
     },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
     "https-proxy-agent": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
@@ -877,6 +2326,40 @@
         }
       }
     },
+    "ieee754": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+      "dev": true
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "import-local": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+      "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^3.0.0",
+        "resolve-cwd": "^2.0.0"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "infer-owner": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+      "dev": true
+    },
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -891,6 +2374,44 @@
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
+    "ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "interpret": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+      "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
     "is-arguments": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
@@ -926,11 +2447,62 @@
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
       "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw=="
     },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
     "is-date-object": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
       "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
     },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
     "is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -968,6 +2540,15 @@
       "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz",
       "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw=="
     },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
     "is-regex": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz",
@@ -1020,6 +2601,18 @@
       "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.1.tgz",
       "integrity": "sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw=="
     },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "is-wsl": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+      "dev": true
+    },
     "isarray": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
@@ -1032,6 +2625,12 @@
       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
       "dev": true
     },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
     "isstream": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@@ -1058,24 +2657,37 @@
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
     },
-    "json-rpc2": {
+    "json-parse-better-errors": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/json-rpc2/-/json-rpc2-1.0.2.tgz",
-      "integrity": "sha1-63e9J7HfYGwjcCxONdSvxUdCro0=",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "json-rpc2": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/json-rpc2/-/json-rpc2-2.0.0.tgz",
+      "integrity": "sha512-0jfrGSH0ZDxrpaaHUkigg/oA6MQqsZDpKSpUzeokhP2jyy6h+cH4G+MPoAa4SVdw9sTzc+YK2hzhUgdShMzKow==",
       "requires": {
-        "debug": "2.x.x",
-        "es5class": "2.x.x",
-        "eventemitter3": "1.x.x",
-        "faye-websocket": "0.x.x",
-        "jsonparse": "1.x.x",
-        "lodash": "3.x.x",
-        "object-assign": "4.x"
+        "debug": "^4.1.1",
+        "es5class": "^2.3.1",
+        "faye-websocket": "^0.11.3",
+        "jsonparse": "^1.3.1",
+        "lodash": "^4.17.15",
+        "object-assign": "^4.1.1"
       },
       "dependencies": {
-        "lodash": {
-          "version": "3.10.1",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
-          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
         }
       }
     },
@@ -1094,6 +2706,15 @@
       "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
       "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
     },
+    "json5": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+      "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.0"
+      }
+    },
     "jsonfile": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
@@ -1126,6 +2747,29 @@
       "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==",
       "dev": true
     },
+    "kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true
+    },
+    "loader-runner": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
+      "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+      "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+      "dev": true,
+      "requires": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      }
+    },
     "locate-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
@@ -1137,10 +2781,9 @@
       }
     },
     "lodash": {
-      "version": "4.17.15",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-      "dev": true
+      "version": "4.17.19",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
+      "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
     },
     "lodash.get": {
       "version": "4.4.2",
@@ -1157,6 +2800,97 @@
         "chalk": "^2.4.2"
       }
     },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "requires": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        }
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "memory-fs": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+      "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+      "dev": true,
+      "requires": {
+        "errno": "^0.1.3",
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "micromatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+      "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+      "dev": true,
+      "requires": {
+        "braces": "^3.0.1",
+        "picomatch": "^2.0.5"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
     "mime-db": {
       "version": "1.43.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
@@ -1170,6 +2904,18 @@
         "mime-db": "1.43.0"
       }
     },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
     "minimatch": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -1183,6 +2929,45 @@
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
       "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
     },
+    "mississippi": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+      "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+      "dev": true,
+      "requires": {
+        "concat-stream": "^1.5.0",
+        "duplexify": "^3.4.2",
+        "end-of-stream": "^1.1.0",
+        "flush-write-stream": "^1.0.0",
+        "from2": "^2.1.0",
+        "parallel-transform": "^1.1.0",
+        "pump": "^3.0.0",
+        "pumpify": "^1.3.3",
+        "stream-each": "^1.1.0",
+        "through2": "^2.0.0"
+      }
+    },
+    "mixin-deep": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
     "mkdirp": {
       "version": "0.5.5",
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
@@ -1261,14 +3046,66 @@
       }
     },
     "moment": {
-      "version": "2.26.0",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
-      "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
+      "version": "2.27.0",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
+      "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
+    },
+    "move-concurrently": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+      "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "copy-concurrently": "^1.0.0",
+        "fs-write-stream-atomic": "^1.0.8",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.3"
+      }
     },
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.14.1",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+      "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
+      "dev": true
+    },
+    "nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      }
+    },
+    "neo-async": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+      "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+      "dev": true
+    },
+    "nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
     },
     "nise": {
       "version": "4.0.3",
@@ -1301,6 +3138,45 @@
         }
       }
     },
+    "node-libs-browser": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
+      "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
+      "dev": true,
+      "requires": {
+        "assert": "^1.1.1",
+        "browserify-zlib": "^0.2.0",
+        "buffer": "^4.3.0",
+        "console-browserify": "^1.1.0",
+        "constants-browserify": "^1.0.0",
+        "crypto-browserify": "^3.11.0",
+        "domain-browser": "^1.1.1",
+        "events": "^3.0.0",
+        "https-browserify": "^1.0.0",
+        "os-browserify": "^0.3.0",
+        "path-browserify": "0.0.1",
+        "process": "^0.11.10",
+        "punycode": "^1.2.4",
+        "querystring-es3": "^0.2.0",
+        "readable-stream": "^2.3.3",
+        "stream-browserify": "^2.0.1",
+        "stream-http": "^2.7.2",
+        "string_decoder": "^1.0.0",
+        "timers-browserify": "^2.0.4",
+        "tty-browserify": "0.0.0",
+        "url": "^0.11.0",
+        "util": "^0.11.0",
+        "vm-browserify": "^1.0.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
+      }
+    },
     "normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -1317,6 +3193,43 @@
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
     },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
     "object-inspect": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
@@ -1336,6 +3249,15 @@
       "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
       "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
     },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.0"
+      }
+    },
     "object.assign": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
@@ -1357,6 +3279,15 @@
         "es-abstract": "^1.17.0-next.1"
       }
     },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -1365,6 +3296,12 @@
         "wrappy": "1"
       }
     },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
     "p-limit": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
@@ -1389,6 +3326,62 @@
       "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
       "dev": true
     },
+    "pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+      "dev": true
+    },
+    "parallel-transform": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
+      "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
+      "dev": true,
+      "requires": {
+        "cyclist": "^1.0.1",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.1.5"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
+      "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
+      "dev": true,
+      "requires": {
+        "asn1.js": "^4.0.0",
+        "browserify-aes": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "parse-passwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+      "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true,
+      "optional": true
+    },
     "path-exists": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@@ -1400,6 +3393,12 @@
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
     },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
     "path-parse": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
@@ -1415,6 +3414,19 @@
         "isarray": "0.0.1"
       }
     },
+    "pbkdf2": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+      "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+      "dev": true,
+      "requires": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
     "performance-now": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -1426,17 +3438,117 @@
       "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
       "dev": true
     },
+    "pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true
+    },
+    "pkg-dir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+      "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+      "dev": true,
+      "requires": {
+        "find-up": "^3.0.0"
+      }
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
     "prettier": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz",
       "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==",
       "dev": true
     },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+      "dev": true
+    },
+    "promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "dev": true
+    },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
     "psl": {
       "version": "1.8.0",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
       "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
     },
+    "public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.9",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+          "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+          "dev": true
+        }
+      }
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "pumpify": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+      "dev": true,
+      "requires": {
+        "duplexify": "^3.6.0",
+        "inherits": "^2.0.3",
+        "pump": "^2.0.0"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+          "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        }
+      }
+    },
     "punycode": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -1447,6 +3559,66 @@
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
       "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
     },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.7",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+      "dev": true,
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        }
+      }
+    },
     "readdirp": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
@@ -1456,6 +3628,16 @@
         "picomatch": "^2.0.4"
       }
     },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
     "regexp.prototype.flags": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
@@ -1465,6 +3647,25 @@
         "es-abstract": "^1.17.0-next.1"
       }
     },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true,
+      "optional": true
+    },
+    "repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
     "request": {
       "version": "2.88.2",
       "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -1513,6 +3714,56 @@
         "path-parse": "^1.0.6"
       }
     },
+    "resolve-cwd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+      "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "resolve-dir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.0",
+        "global-modules": "^1.0.0"
+      },
+      "dependencies": {
+        "global-modules": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+          "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+          "dev": true,
+          "requires": {
+            "global-prefix": "^1.0.1",
+            "is-windows": "^1.0.1",
+            "resolve-dir": "^1.0.0"
+          }
+        }
+      }
+    },
+    "resolve-from": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
     "rimraf": {
       "version": "2.7.1",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@@ -1522,27 +3773,129 @@
         "glob": "^7.1.3"
       }
     },
+    "ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "run-queue": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+      "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1"
+      }
+    },
     "safe-buffer": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
       "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
     },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "~0.1.10"
+      }
+    },
     "safer-buffer": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
+    "schema-utils": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+      "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.1.0",
+        "ajv-errors": "^1.0.0",
+        "ajv-keywords": "^3.1.0"
+      }
+    },
     "semver": {
       "version": "7.3.2",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
       "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
     },
+    "serialize-javascript": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
+      "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.1.0"
+      }
+    },
     "set-blocking": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
       "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
       "dev": true
     },
+    "set-value": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
     "side-channel": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz",
@@ -1584,6 +3937,177 @@
         }
       }
     },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.2.0"
+      },
+      "dependencies": {
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "source-list-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "dev": true
+    },
+    "source-map-resolve": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.2",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.5.19",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.0"
+      }
+    },
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -1606,6 +4130,75 @@
         "tweetnacl": "~0.14.0"
       }
     },
+    "ssri": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+      "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+      "dev": true,
+      "requires": {
+        "figgy-pudding": "^3.5.1"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "stream-browserify": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+      "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.1",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "stream-each": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+      "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "stream-http": {
+      "version": "2.8.3",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+      "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "^3.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.6",
+        "to-arraybuffer": "^1.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "stream-shift": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+      "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+      "dev": true
+    },
     "string-width": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -1654,6 +4247,23 @@
         "es-abstract": "^1.17.5"
       }
     },
+    "string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.0"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+          "dev": true
+        }
+      }
+    },
     "strip-ansi": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -1678,6 +4288,119 @@
         "has-flag": "^3.0.0"
       }
     },
+    "tapable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+      "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+      "dev": true
+    },
+    "terser": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
+      "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.20.0",
+        "source-map": "~0.6.1",
+        "source-map-support": "~0.5.12"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "terser-webpack-plugin": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz",
+      "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==",
+      "dev": true,
+      "requires": {
+        "cacache": "^12.0.2",
+        "find-cache-dir": "^2.1.0",
+        "is-wsl": "^1.1.0",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^3.1.0",
+        "source-map": "^0.6.1",
+        "terser": "^4.1.2",
+        "webpack-sources": "^1.4.0",
+        "worker-farm": "^1.7.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "timers-browserify": {
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
+      "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==",
+      "dev": true,
+      "requires": {
+        "setimmediate": "^1.0.4"
+      }
+    },
+    "to-arraybuffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+      "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+      "dev": true
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
     "to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -1700,6 +4423,27 @@
       "version": "file:third_party/tree-kill",
       "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="
     },
+    "ts-loader": {
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz",
+      "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.3.0",
+        "enhanced-resolve": "^4.0.0",
+        "loader-utils": "^1.0.2",
+        "micromatch": "^4.0.0",
+        "semver": "^6.0.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
     "tslib": {
       "version": "1.13.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
@@ -1744,6 +4488,12 @@
         "tslib": "^1.8.1"
       }
     },
+    "tty-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+      "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+      "dev": true
+    },
     "tunnel-agent": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -1763,18 +4513,107 @@
       "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
       "dev": true
     },
-    "typescript": {
-      "version": "3.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz",
-      "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==",
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
       "dev": true
     },
+    "typescript": {
+      "version": "3.9.6",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz",
+      "integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==",
+      "dev": true
+    },
+    "union-value": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^2.0.1"
+      }
+    },
+    "unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "dev": true,
+      "requires": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
     "universalify": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
       "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
       "dev": true
     },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "^2.0.3",
+            "has-values": "^0.1.4",
+            "isobject": "^2.0.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        }
+      }
+    },
+    "upath": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+      "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+      "dev": true,
+      "optional": true
+    },
     "uri-js": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -1783,11 +4622,70 @@
         "punycode": "^2.1.0"
       }
     },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
+        }
+      }
+    },
+    "use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true
+    },
+    "util": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
+      "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
     "uuid": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
       "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
     },
+    "v8-compile-cache": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
+      "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
+      "dev": true
+    },
     "verror": {
       "version": "1.10.0",
       "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
@@ -1798,6 +4696,12 @@
         "extsprintf": "^1.2.0"
       }
     },
+    "vm-browserify": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+      "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+      "dev": true
+    },
     "vscode-debugadapter": {
       "version": "1.41.0",
       "resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.41.0.tgz",
@@ -1858,6 +4762,284 @@
         "rimraf": "^2.6.3"
       }
     },
+    "watchpack": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz",
+      "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^3.4.0",
+        "graceful-fs": "^4.1.2",
+        "neo-async": "^2.5.0",
+        "watchpack-chokidar2": "^2.0.0"
+      },
+      "dependencies": {
+        "chokidar": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+          "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "anymatch": "~3.1.1",
+            "braces": "~3.0.2",
+            "fsevents": "~2.1.2",
+            "glob-parent": "~5.1.0",
+            "is-binary-path": "~2.1.0",
+            "is-glob": "~4.0.1",
+            "normalize-path": "~3.0.0",
+            "readdirp": "~3.4.0"
+          }
+        },
+        "readdirp": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+          "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "picomatch": "^2.2.1"
+          }
+        }
+      }
+    },
+    "watchpack-chokidar2": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz",
+      "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "chokidar": "^2.1.8"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "micromatch": "^3.1.4",
+            "normalize-path": "^2.1.1"
+          },
+          "dependencies": {
+            "normalize-path": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+              "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "remove-trailing-separator": "^1.0.1"
+              }
+            }
+          }
+        },
+        "binary-extensions": {
+          "version": "1.13.1",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+          "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+          "dev": true,
+          "optional": true
+        },
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "arr-flatten": "^1.1.0",
+            "array-unique": "^0.3.2",
+            "extend-shallow": "^2.0.1",
+            "fill-range": "^4.0.0",
+            "isobject": "^3.0.1",
+            "repeat-element": "^1.1.2",
+            "snapdragon": "^0.8.1",
+            "snapdragon-node": "^2.0.1",
+            "split-string": "^3.0.2",
+            "to-regex": "^3.0.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "chokidar": {
+          "version": "2.1.8",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+          "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "anymatch": "^2.0.0",
+            "async-each": "^1.0.1",
+            "braces": "^2.3.2",
+            "fsevents": "^1.2.7",
+            "glob-parent": "^3.1.0",
+            "inherits": "^2.0.3",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^4.0.0",
+            "normalize-path": "^3.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.2.1",
+            "upath": "^1.1.1"
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "extend-shallow": "^2.0.1",
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1",
+            "to-regex-range": "^2.1.0"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "fsevents": {
+          "version": "1.2.13",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+          "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "bindings": "^1.5.0",
+            "nan": "^2.12.1"
+          }
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-glob": "^3.1.0",
+            "path-dirname": "^1.0.0"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "is-extglob": "^2.1.0"
+              }
+            }
+          }
+        },
+        "is-binary-path": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+          "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "binary-extensions": "^1.0.0"
+          }
+        },
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true,
+          "optional": true
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "optional": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "arr-diff": "^4.0.0",
+            "array-unique": "^0.3.2",
+            "braces": "^2.3.1",
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "extglob": "^2.0.4",
+            "fragment-cache": "^0.2.1",
+            "kind-of": "^6.0.2",
+            "nanomatch": "^1.2.9",
+            "object.pick": "^1.3.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.2"
+          }
+        },
+        "readdirp": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+          "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "graceful-fs": "^4.1.11",
+            "micromatch": "^3.1.10",
+            "readable-stream": "^2.0.2"
+          }
+        },
+        "to-regex-range": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+          "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1"
+          }
+        }
+      }
+    },
     "web-request": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/web-request/-/web-request-1.0.7.tgz",
@@ -1866,12 +5048,212 @@
         "request": "^2.69.0"
       }
     },
-    "websocket-driver": {
-      "version": "0.7.3",
-      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz",
-      "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==",
+    "webpack": {
+      "version": "4.43.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz",
+      "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==",
+      "dev": true,
       "requires": {
-        "http-parser-js": ">=0.4.0 <0.4.11",
+        "@webassemblyjs/ast": "1.9.0",
+        "@webassemblyjs/helper-module-context": "1.9.0",
+        "@webassemblyjs/wasm-edit": "1.9.0",
+        "@webassemblyjs/wasm-parser": "1.9.0",
+        "acorn": "^6.4.1",
+        "ajv": "^6.10.2",
+        "ajv-keywords": "^3.4.1",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^4.1.0",
+        "eslint-scope": "^4.0.3",
+        "json-parse-better-errors": "^1.0.2",
+        "loader-runner": "^2.4.0",
+        "loader-utils": "^1.2.3",
+        "memory-fs": "^0.4.1",
+        "micromatch": "^3.1.10",
+        "mkdirp": "^0.5.3",
+        "neo-async": "^2.6.1",
+        "node-libs-browser": "^2.2.1",
+        "schema-utils": "^1.0.0",
+        "tapable": "^1.1.3",
+        "terser-webpack-plugin": "^1.4.3",
+        "watchpack": "^1.6.1",
+        "webpack-sources": "^1.4.1"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "^1.1.0",
+            "array-unique": "^0.3.2",
+            "extend-shallow": "^2.0.1",
+            "fill-range": "^4.0.0",
+            "isobject": "^3.0.1",
+            "repeat-element": "^1.1.2",
+            "snapdragon": "^0.8.1",
+            "snapdragon-node": "^2.0.1",
+            "split-string": "^3.0.2",
+            "to-regex": "^3.0.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "^2.0.1",
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1",
+            "to-regex-range": "^2.1.0"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "^0.1.0"
+              }
+            }
+          }
+        },
+        "is-buffer": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+          "dev": true
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^3.0.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "^1.1.5"
+              }
+            }
+          }
+        },
+        "memory-fs": {
+          "version": "0.4.1",
+          "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+          "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+          "dev": true,
+          "requires": {
+            "errno": "^0.1.3",
+            "readable-stream": "^2.0.1"
+          }
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "^4.0.0",
+            "array-unique": "^0.3.2",
+            "braces": "^2.3.1",
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "extglob": "^2.0.4",
+            "fragment-cache": "^0.2.1",
+            "kind-of": "^6.0.2",
+            "nanomatch": "^1.2.9",
+            "object.pick": "^1.3.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.2"
+          }
+        },
+        "to-regex-range": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+          "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+          "dev": true,
+          "requires": {
+            "is-number": "^3.0.0",
+            "repeat-string": "^1.6.1"
+          }
+        }
+      }
+    },
+    "webpack-cli": {
+      "version": "3.3.12",
+      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz",
+      "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "cross-spawn": "^6.0.5",
+        "enhanced-resolve": "^4.1.1",
+        "findup-sync": "^3.0.0",
+        "global-modules": "^2.0.0",
+        "import-local": "^2.0.0",
+        "interpret": "^1.4.0",
+        "loader-utils": "^1.4.0",
+        "supports-color": "^6.1.0",
+        "v8-compile-cache": "^2.1.1",
+        "yargs": "^13.3.2"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "webpack-sources": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+      "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "^2.0.0",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "websocket-driver": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+      "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+      "requires": {
+        "http-parser-js": ">=0.5.1",
         "safe-buffer": ">=5.1.0",
         "websocket-extensions": ">=0.1.1"
       }
@@ -1941,6 +5323,15 @@
         "string-width": "^1.0.2 || 2"
       }
     },
+    "worker-farm": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+      "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+      "dev": true,
+      "requires": {
+        "errno": "~0.1.7"
+      }
+    },
     "wrap-ansi": {
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
@@ -1985,12 +5376,24 @@
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
     },
+    "xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true
+    },
     "y18n": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
       "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
       "dev": true
     },
+    "yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
     "yargs": {
       "version": "13.3.2",
       "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
@@ -2057,6 +5460,12 @@
         "lodash": "^4.17.15",
         "yargs": "^13.3.0"
       }
+    },
+    "yarn": {
+      "version": "1.22.4",
+      "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.4.tgz",
+      "integrity": "sha512-oYM7hi/lIWm9bCoDMEWgffW8aiNZXCWeZ1/tGy0DWrN6vmzjCXIKu2Y21o8DYVBUtiktwKcNoxyGl/2iKLUNGA==",
+      "dev": true
     }
   }
 }
diff --git a/package.json b/package.json
index a070e0f..fb5c6d6 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,6 @@
   "author": {
     "name": "Go Team at Google"
   },
-  "preview": true,
   "license": "MIT",
   "icon": "images/go-logo-blue.png",
   "categories": [
@@ -34,13 +33,15 @@
   ],
   "scripts": {
     "vscode:prepublish": "npm run compile",
-    "compile": "tsc -p ./",
+    "webpack": "webpack --mode development",
+    "webpack-dev": "webpack --mode development --watch",
+    "test-compile": "tsc -p ./",
+    "compile": "webpack --mode production",
     "watch": "tsc -watch -p ./",
-    "pretest": "npm run compile",
-    "test": "node ./out/test/runTest.js",
+    "test": "npm run test-compile && node ./out/test/runTest.js",
     "lint": "node ./node_modules/tslint/bin/tslint --project tsconfig.json",
     "fix-lint": "node ./node_modules/tslint/bin/tslint --fix --project tsconfig.json",
-    "unit-test": "node ./node_modules/mocha/bin/_mocha -u tdd --timeout 5000 --colors ./out/test/unit",
+    "unit-test": "npm run test-compile && node ./node_modules/mocha/bin/_mocha -u tdd --timeout 5000 --colors ./out/test/unit",
     "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\""
   },
   "extensionDependencies": [],
@@ -48,7 +49,7 @@
     "deep-equal": "^2.0.2",
     "diff": "^4.0.2",
     "glob": "^7.1.6",
-    "json-rpc2": "^1.0.2",
+    "json-rpc2": "^2.0.0",
     "moment": "^2.24.0",
     "semver": "^7.3.2",
     "tree-kill": "file:third_party/tree-kill",
@@ -70,11 +71,16 @@
     "adm-zip": "^0.4.14",
     "fs-extra": "^9.0.0",
     "mocha": "^7.1.1",
+    "nan": "^2.14.1",
     "prettier": "^2.0.4",
     "sinon": "^9.0.2",
+    "ts-loader": "^7.0.5",
     "tslint": "^6.1.1",
     "typescript": "^3.8.3",
-    "vscode-test": "^1.3.0"
+    "vscode-test": "^1.3.0",
+    "webpack": "^4.43.0",
+    "webpack-cli": "^3.3.12",
+    "yarn": "^1.22.4"
   },
   "engines": {
     "vscode": "^1.41.0"
@@ -86,7 +92,7 @@
     "onCommand:go.tools.install",
     "onDebugResolve:go"
   ],
-  "main": "./out/src/goMain",
+  "main": "./dist/goMain.js",
   "contributes": {
     "languages": [
       {
@@ -346,6 +352,11 @@
         "command": "go.languageserver.restart",
         "title": "Go: Restart Language Server",
         "description": "Restart the running instance of the language server"
+      },
+      {
+        "command": "go.environment.choose",
+        "title": "Go: Choose Go Environment",
+        "description": "Choose a different Go version or binary for this project. (WIP)"
       }
     ],
     "breakpoints": [
@@ -357,7 +368,7 @@
       {
         "type": "go",
         "label": "Go",
-        "program": "./out/src/debugAdapter/goDebug.js",
+        "program": "./dist/debugAdapter.js",
         "runtime": "node",
         "languages": [
           "go"
@@ -746,6 +757,381 @@
             }
           }
         }
+      },
+      {
+        "type": "godlvdap",
+        "label": "Go Dlv Dap (Experimental)",
+        "program": "./dist/debugAdapter2.js",
+        "runtime": "node",
+        "languages": [
+          "go"
+        ],
+        "configurationSnippets": [
+          {
+            "label": "Go: Launch package",
+            "description": "Debug the package in the program attribute",
+            "body": {
+              "name": "${2:Launch Package}",
+              "type": "godlvdap",
+              "request": "launch",
+              "mode": "debug",
+              "program": "^\"\\${workspaceFolder}${1:}\""
+            }
+          },
+          {
+            "label": "Go: Launch file",
+            "description": "Debug the file in the program attribute",
+            "body": {
+              "name": "${2:Launch file}",
+              "type": "godlvdap",
+              "request": "launch",
+              "mode": "debug",
+              "program": "^\"${1:\\${file\\}}\""
+            }
+          },
+          {
+            "label": "Go: Launch test package",
+            "description": "Debug the test package in the program attribute",
+            "body": {
+              "name": "${2:Launch test package}",
+              "type": "godlvdap",
+              "request": "launch",
+              "mode": "test",
+              "program": "^\"\\${workspaceFolder}${1:}\""
+            }
+          },
+          {
+            "label": "Go: Launch test function",
+            "description": "Debug the test function in the args, ensure program attributes points to right package",
+            "body": {
+              "name": "${3:Launch test function}",
+              "type": "godlvdap",
+              "request": "launch",
+              "mode": "test",
+              "program": "^\"\\${workspaceFolder}${1:}\"",
+              "args": [
+                "-test.run",
+                "${2:MyTestFunction}"
+              ]
+            }
+          },
+          {
+            "label": "Go: Attach to local process",
+            "description": "Attach to an existing process by process ID",
+            "body": {
+              "name": "${1:Attach to Process}",
+              "type": "godlvdap",
+              "request": "attach",
+              "mode": "local",
+              "processId": 0
+            }
+          },
+          {
+            "label": "Go: Connect to server",
+            "description": "Connect to a remote headless debug server",
+            "body": {
+              "name": "${1:Connect to server}",
+              "type": "godlvdap",
+              "request": "attach",
+              "mode": "remote",
+              "remotePath": "^\"\\${workspaceFolder}\"",
+              "port": 2345,
+              "host": "127.0.0.1"
+            }
+          }
+        ],
+        "configurationAttributes": {
+          "launch": {
+            "required": [],
+            "properties": {
+              "program": {
+                "type": "string",
+                "description": "Path to the program folder (or any file within that folder) when in 'debug' or 'test' mode, and to the pre-built binary file to debug in 'exec' mode.",
+                "default": "${workspaceFolder}"
+              },
+              "mode": {
+                "enum": [
+                  "auto",
+                  "debug",
+                  "test",
+                  "exec"
+                ],
+                "description": "One of 'auto', 'debug', 'test', 'exec'.",
+                "default": "auto"
+              },
+              "stopOnEntry": {
+                "type": "boolean",
+                "description": "Automatically stop program after launch.",
+                "default": false
+              },
+              "args": {
+                "type": "array",
+                "description": "Command line arguments passed to the program.",
+                "items": {
+                  "type": "string"
+                },
+                "default": []
+              },
+              "showLog": {
+                "type": "boolean",
+                "description": "Show log output from the delve debugger.",
+                "default": false
+              },
+              "cwd": {
+                "type": "string",
+                "description": "Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.",
+                "default": "."
+              },
+              "env": {
+                "type": "object",
+                "description": "Environment variables passed to the program.",
+                "default": {}
+              },
+              "buildFlags": {
+                "type": "string",
+                "description": "Build flags, to be passed to the Go compiler.",
+                "default": ""
+              },
+              "init": {
+                "type": "string",
+                "description": "Init file, executed by the terminal client.",
+                "default": ""
+              },
+              "remotePath": {
+                "type": "string",
+                "description": "Absolute path to the file being debugged on the remote machine in case of remote debugging.",
+                "default": ""
+              },
+              "port": {
+                "type": "number",
+                "description": "The port that the delve debugger will be listening on.",
+                "default": 2345
+              },
+              "host": {
+                "type": "string",
+                "description": "The host name of the machine the delve debugger will be listening on.",
+                "default": "127.0.0.1"
+              },
+              "trace": {
+                "type": "string",
+                "enum": [
+                  "log",
+                  "verbose",
+                  "error"
+                ],
+                "default": "error",
+                "description": "Various levels of logging shown in the debug console. When set to 'log' or 'verbose', the logs will also be written to a file."
+              },
+              "envFile": {
+                "type": [
+                  "string",
+                  "array"
+                ],
+                "items": {
+                  "type": "string"
+                },
+                "description": "Absolute path to a file containing environment variable definitions. Multiple files can be specified by provided an array of absolute paths",
+                "default": "${workspaceFolder}/.env"
+              },
+              "backend": {
+                "type": "string",
+                "enum": [
+                  "default",
+                  "native",
+                  "lldb"
+                ],
+                "description": "Backend used by delve. Only available in delve version 0.12.2 and above."
+              },
+              "output": {
+                "type": "string",
+                "description": "Output path for the binary of delve",
+                "default": "debug"
+              },
+              "logOutput": {
+                "type": "string",
+                "enum": [
+                  "debugger",
+                  "gdbwire",
+                  "lldbout",
+                  "debuglineerr",
+                  "dap"
+                ],
+                "description": "Comma separated list of components that should produce debug output.",
+                "default": "debugger"
+              },
+              "dlvLoadConfig": {
+                "type": "object",
+                "properties": {
+                  "followPointers": {
+                    "type": "boolean",
+                    "description": "FollowPointers requests pointers to be automatically dereferenced",
+                    "default": true
+                  },
+                  "maxVariableRecurse": {
+                    "type": "number",
+                    "description": "MaxVariableRecurse is how far to recurse when evaluating nested types",
+                    "default": 1
+                  },
+                  "maxStringLen": {
+                    "type": "number",
+                    "description": "MaxStringLen is the maximum number of bytes read from a string",
+                    "default": 64
+                  },
+                  "maxArrayValues": {
+                    "type": "number",
+                    "description": "MaxArrayValues is the maximum number of elements read from an array, a slice or a map",
+                    "default": 64
+                  },
+                  "maxStructFields": {
+                    "type": "number",
+                    "description": "MaxStructFields is the maximum number of fields read from a struct, -1 will read all fields",
+                    "default": -1
+                  }
+                },
+                "description": "LoadConfig describes to delve, how to load values from target's memory",
+                "default": {
+                  "followPointers": true,
+                  "maxVariableRecurse": 1,
+                  "maxStringLen": 64,
+                  "maxArrayValues": 64,
+                  "maxStructFields": -1
+                }
+              },
+              "stackTraceDepth": {
+                "type": "number",
+                "description": "Maximum depth of stack trace collected from Delve",
+                "default": 50
+              },
+              "showGlobalVariables": {
+                "type": "boolean",
+                "default": true,
+                "description": "Boolean value to indicate whether global package variables should be shown in the variables pane or not."
+              }
+            }
+          },
+          "attach": {
+            "required": [],
+            "properties": {
+              "processId": {
+                "type": "number",
+                "description": "The ID of the process to be debugged."
+              },
+              "mode": {
+                "enum": [
+                  "local",
+                  "remote"
+                ],
+                "description": "Indicates local or remote debugging.  Local maps to the dlv 'attach' command, remote maps to 'connect'.",
+                "default": "local"
+              },
+              "showLog": {
+                "type": "boolean",
+                "description": "Show log output from the delve debugger.",
+                "default": false
+              },
+              "cwd": {
+                "type": "string",
+                "description": "Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.",
+                "default": "${workspaceFolder}"
+              },
+              "remotePath": {
+                "type": "string",
+                "description": "If remote debugging, the path to the source code on the remote machine, if different from the local machine.",
+                "default": ""
+              },
+              "port": {
+                "type": "number",
+                "description": "The port that the delve debugger will be listening on.",
+                "default": 2345
+              },
+              "host": {
+                "type": "string",
+                "description": "The host name of the machine the delve debugger will be listening on.",
+                "default": "127.0.0.1"
+              },
+              "trace": {
+                "type": "string",
+                "enum": [
+                  "log",
+                  "verbose",
+                  "error"
+                ],
+                "default": "error",
+                "description": "Various levels of logging shown in the debug console. When set to 'log' or 'verbose', the logs will also be written to a file."
+              },
+              "backend": {
+                "type": "string",
+                "enum": [
+                  "default",
+                  "native",
+                  "lldb"
+                ],
+                "description": "Backend used by delve. Only available in delve version 0.12.2 and above."
+              },
+              "logOutput": {
+                "type": "string",
+                "enum": [
+                  "debugger",
+                  "gdbwire",
+                  "lldbout",
+                  "debuglineerr",
+                  "dap",
+                  "rpc"
+                ],
+                "description": "Comma separated list of components that should produce debug output.",
+                "default": "debugger"
+              },
+              "dlvLoadConfig": {
+                "type": "object",
+                "properties": {
+                  "followPointers": {
+                    "type": "boolean",
+                    "description": "FollowPointers requests pointers to be automatically dereferenced",
+                    "default": true
+                  },
+                  "maxVariableRecurse": {
+                    "type": "number",
+                    "description": "MaxVariableRecurse is how far to recurse when evaluating nested types",
+                    "default": 1
+                  },
+                  "maxStringLen": {
+                    "type": "number",
+                    "description": "MaxStringLen is the maximum number of bytes read from a string",
+                    "default": 64
+                  },
+                  "maxArrayValues": {
+                    "type": "number",
+                    "description": "MaxArrayValues is the maximum number of elements read from an array, a slice or a map",
+                    "default": 64
+                  },
+                  "maxStructFields": {
+                    "type": "number",
+                    "description": "MaxStructFields is the maximum number of fields read from a struct, -1 will read all fields",
+                    "default": -1
+                  }
+                },
+                "description": "LoadConfig describes to delve, how to load values from target's memory",
+                "default": {
+                  "followPointers": true,
+                  "maxVariableRecurse": 1,
+                  "maxStringLen": 64,
+                  "maxArrayValues": 64,
+                  "maxStructFields": -1
+                }
+              },
+              "stackTraceDepth": {
+                "type": "number",
+                "description": "Maximum depth of stack trace collected from Delve",
+                "default": 50
+              },
+              "showGlobalVariables": {
+                "type": "boolean",
+                "default": true,
+                "description": "Boolean value to indicate whether global package variables should be shown in the variables pane or not."
+              }
+            }
+          }
+        }
       }
     ],
     "configuration": {
diff --git a/src/const.ts b/src/const.ts
new file mode 100644
index 0000000..3783d8b
--- /dev/null
+++ b/src/const.ts
@@ -0,0 +1,12 @@
+/*---------------------------------------------------------
+ * Copyright (C) Microsoft Corporation. All rights reserved.
+ * Modification copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+// This file contains constants that need to change when building Nightly or Go2Go.
+//
+// For example, we replace this file with the version in the build/nightly.
+// Make sure to reflect any changes in this file to build/nightly/const.ts.
+
+export const extensionId: string = 'golang.go';
diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts
index a2b3c49..e349ed4 100644
--- a/src/debugAdapter/goDebug.ts
+++ b/src/debugAdapter/goDebug.ts
@@ -33,7 +33,7 @@
 import {
 	envPath,
 	fixDriveCasingInWindows,
-	getBinPathWithPreferredGopath,
+	getBinPathWithPreferredGopathGoroot,
 	getCurrentGoWorkspaceFromGOPATH,
 	getInferredGopath,
 	parseEnvFile
@@ -471,7 +471,7 @@
 							runArgs.push(...launchArgs.args);
 						}
 
-						const goExe = getBinPathWithPreferredGopath('go', []);
+						const goExe = getBinPathWithPreferredGopathGoroot('go', []);
 						log(`Current working directory: ${dirname}`);
 						log(`Running: ${goExe} ${runArgs.join(' ')}`);
 
@@ -514,7 +514,7 @@
 						} or ${envPath}`
 					);
 					return reject(
-						`Cannot find Delve debugger. Install from https://github.com/derekparker/delve & ensure it is in your Go tools path, "GOPATH/bin" or "PATH".`
+						`Cannot find Delve debugger. Install from https://github.com/go-delve/delve & ensure it is in your Go tools path, "GOPATH/bin" or "PATH".`
 					);
 				}
 
@@ -1934,7 +1934,7 @@
 		}
 		return new Promise((resolve) => {
 			execFile(
-				getBinPathWithPreferredGopath('go', []),
+				getBinPathWithPreferredGopathGoroot('go', []),
 				['list', '-f', '{{.Name}} {{.ImportPath}}'],
 				{ cwd: dir, env: this.delve.dlvEnv },
 				(err, stdout, stderr) => {
@@ -2335,7 +2335,7 @@
 function queryGOROOT(cwd: any, env: any): Promise<string> {
 	return new Promise<string>((resolve) => {
 		execFile(
-			getBinPathWithPreferredGopath('go', []),
+			getBinPathWithPreferredGopathGoroot('go', []),
 			['env', 'GOROOT'],
 			{ cwd, env },
 			(err, stdout, stderr) => {
diff --git a/src/debugAdapter2/README.md b/src/debugAdapter2/README.md
new file mode 100644
index 0000000..f0ca4fb
--- /dev/null
+++ b/src/debugAdapter2/README.md
@@ -0,0 +1,6 @@
+# Debug Adapter
+
+This debug adapter is experimental, in-development code. If you
+actually need to debug Go code, please use the default adapter ("type": "go").
+
+See the [contribution documentation](../../docs/contributing.md) to learn how to develop the debug adapter.
diff --git a/src/debugAdapter2/dapClient.ts b/src/debugAdapter2/dapClient.ts
new file mode 100644
index 0000000..14d38a0
--- /dev/null
+++ b/src/debugAdapter2/dapClient.ts
@@ -0,0 +1,100 @@
+/*---------------------------------------------------------
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+import { EventEmitter } from 'events';
+import stream = require('stream');
+
+import { DebugProtocol } from 'vscode-debugprotocol';
+
+// DapClient implements a simple client for the DAP protocol.
+// It's initialized with a pair of streams that the caller creats and enables
+// sending and receiving DAP messages over these streams.
+// After calling connect():
+//
+//  - For sending messages call send().
+//  - For receiving messages, subscibe to events this class emits.
+//      - 'event', 'respones', 'request' - each carrying an appropriate
+//        DebugProtocol type as an argument.
+export class DAPClient extends EventEmitter {
+	private static readonly TWO_CRLF = '\r\n\r\n';
+
+	private outputStream: stream.Writable;
+
+	private rawData = Buffer.alloc(0);
+	private contentLength: number = -1;
+
+	constructor() {
+		super();
+	}
+
+	public send(req: any): void {
+		const json = JSON.stringify(req);
+		this.outputStream.write(`Content-Length: ${Buffer.byteLength(json, 'utf8')}\r\n\r\n${json}`, 'utf8');
+	}
+
+	// Connect this client to a server, which is represented by read and write
+	// streams. Before this method is called, send() won't work and no messages
+	// from the server will be delivered.
+	protected connect(readable: stream.Readable, writable: stream.Writable): void {
+		this.outputStream = writable;
+
+		readable.on('data', (data: Buffer) => {
+			this.handleData(data);
+		});
+	}
+
+	// Implements parsing of the DAP protocol. We cannot use ProtocolClient
+	// from the vscode-debugadapter package, because it's not exported and
+	// is not meant for external usage.
+	// See https://github.com/microsoft/vscode-debugadapter-node/issues/232
+	private handleData(data: Buffer): void {
+		this.rawData = Buffer.concat([this.rawData, data]);
+
+		while (true) {
+			if (this.contentLength >= 0) {
+				if (this.rawData.length >= this.contentLength) {
+					const message = this.rawData.toString('utf8', 0, this.contentLength);
+					this.rawData = this.rawData.slice(this.contentLength);
+					this.contentLength = -1;
+					if (message.length > 0) {
+						this.dispatch(message);
+					}
+					continue;	// there may be more complete messages to process
+				}
+			} else {
+				const idx = this.rawData.indexOf(DAPClient.TWO_CRLF);
+				if (idx !== -1) {
+					const header = this.rawData.toString('utf8', 0, idx);
+					const lines = header.split('\r\n');
+					for (const line of lines) {
+						const pair = line.split(/: +/);
+						if (pair[0] === 'Content-Length') {
+							this.contentLength = +pair[1];
+						}
+					}
+					this.rawData = this.rawData.slice(idx + DAPClient.TWO_CRLF.length);
+					continue;
+				}
+			}
+			break;
+		}
+	}
+
+	private dispatch(body: string): void {
+		const rawData = JSON.parse(body);
+
+		if (rawData.type === 'event') {
+			const event = <DebugProtocol.Event>rawData;
+			this.emit('event', event);
+		} else if (rawData.type === 'response') {
+			const response = <DebugProtocol.Response>rawData;
+			this.emit('response', response);
+		} else if (rawData.type === 'request') {
+			const request = <DebugProtocol.Request>rawData;
+			this.emit('request', request);
+		} else {
+			throw new Error(`unknown message ${JSON.stringify(rawData)}`);
+		}
+	}
+}
diff --git a/src/debugAdapter2/goDlvDebug.ts b/src/debugAdapter2/goDlvDebug.ts
new file mode 100644
index 0000000..09e094e
--- /dev/null
+++ b/src/debugAdapter2/goDlvDebug.ts
@@ -0,0 +1,645 @@
+/*---------------------------------------------------------
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+// NOTE: This debug adapter is experimental, in-development code. If you
+// actually need to debug Go code, please use the default adapter.
+
+import { ChildProcess, spawn } from 'child_process';
+import * as fs from 'fs';
+import net = require('net');
+import * as os from 'os';
+import * as path from 'path';
+
+import {
+	logger,
+	Logger,
+	LoggingDebugSession,
+	TerminatedEvent
+} from 'vscode-debugadapter';
+import { DebugProtocol } from 'vscode-debugprotocol';
+
+import { envPath } from '../goPath';
+import { DAPClient } from './dapClient';
+
+interface LoadConfig {
+	// FollowPointers requests pointers to be automatically dereferenced.
+	followPointers: boolean;
+	// MaxVariableRecurse is how far to recurse when evaluating nested types.
+	maxVariableRecurse: number;
+	// MaxStringLen is the maximum number of bytes read from a string
+	maxStringLen: number;
+	// MaxArrayValues is the maximum number of elements read from an array, a slice or a map.
+	maxArrayValues: number;
+	// MaxStructFields is the maximum number of fields read from a struct, -1 will read all fields.
+	maxStructFields: number;
+}
+
+// This interface should always match the schema found in `package.json`.
+interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
+	request: 'launch';
+	[key: string]: any;
+	program: string;
+	stopOnEntry?: boolean;
+	args?: string[];
+	showLog?: boolean;
+	logOutput?: string;
+	cwd?: string;
+	env?: { [key: string]: string };
+	mode?: 'auto' | 'debug' | 'remote' | 'test' | 'exec';
+	remotePath?: string;
+	port?: number;
+	host?: string;
+	buildFlags?: string;
+	init?: string;
+	trace?: 'verbose' | 'log' | 'error';
+	/** Optional path to .env file. */
+	envFile?: string | string[];
+	backend?: string;
+	output?: string;
+	/** Delve LoadConfig parameters */
+	dlvLoadConfig?: LoadConfig;
+	dlvToolPath: string;
+	/** Delve Version */
+	apiVersion: number;
+	/** Delve maximum stack trace depth */
+	stackTraceDepth: number;
+
+	showGlobalVariables?: boolean;
+	packagePathToGoModPathMap: { [key: string]: string };
+}
+
+interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments {
+	request: 'attach';
+	processId?: number;
+	stopOnEntry?: boolean;
+	showLog?: boolean;
+	logOutput?: string;
+	cwd?: string;
+	mode?: 'local' | 'remote';
+	remotePath?: string;
+	port?: number;
+	host?: string;
+	trace?: 'verbose' | 'log' | 'error';
+	backend?: string;
+	/** Delve LoadConfig parameters */
+	dlvLoadConfig?: LoadConfig;
+	dlvToolPath: string;
+	/** Delve Version */
+	apiVersion: number;
+	/** Delve maximum stack trace depth */
+	stackTraceDepth: number;
+
+	showGlobalVariables?: boolean;
+}
+
+process.on('uncaughtException', (err: any) => {
+	const errMessage = err && (err.stack || err.message);
+	logger.error(`Unhandled error in debug adapter: ${errMessage}`);
+	throw err;
+});
+
+function logArgsToString(args: any[]): string {
+	return args
+		.map((arg) => {
+			return typeof arg === 'string' ? arg : JSON.stringify(arg);
+		})
+		.join(' ');
+}
+
+function log(...args: any[]) {
+	logger.warn(logArgsToString(args));
+}
+
+function logError(...args: any[]) {
+	logger.error(logArgsToString(args));
+}
+
+// GoDlvDapDebugSession implements a DAP debug adapter to talk to the editor.
+//
+// This adapter serves as a DAP proxy between the editor and the DAP server
+// inside Delve. It relies on functionality inherited from DebugSession to
+// implement the server side interfacing the editor, and on DapClient to
+// implement the client side interfacing Delve:
+//
+//      Editor                GoDlvDapDebugSession                 Delve
+//  +------------+        +--------------+-----------+         +------------+
+//  | DAP Client | <====> | DebugSession | DAPClient |  <====> | DAP Server |
+//  +------------+        +--------------+-----------+         +------------+
+export class GoDlvDapDebugSession extends LoggingDebugSession {
+	private readonly DEFAULT_DELVE_HOST = '127.0.0.1';
+	private readonly DEFAULT_DELVE_PORT = 42042;
+
+	private logLevel: Logger.LogLevel = Logger.LogLevel.Error;
+
+	private dlvClient: DelveClient;
+
+	public constructor() {
+		super();
+
+		// Invoke logger.init here because we want logging to work in 'inline'
+		// DA mode. It's typically called in the start() method of our parent
+		// class, but this method isn't called in 'inline' mode.
+		logger.init((e) => this.sendEvent(e));
+
+		// this debugger uses zero-based lines and columns
+		this.setDebuggerLinesStartAt1(false);
+		this.setDebuggerColumnsStartAt1(false);
+	}
+
+	protected initializeRequest(
+		response: DebugProtocol.InitializeResponse,
+		args: DebugProtocol.InitializeRequestArguments,
+		request?: DebugProtocol.Request
+	): void {
+		log('InitializeRequest');
+		response.body.supportsConfigurationDoneRequest = true;
+
+		// We respond to InitializeRequest here, because Delve hasn't been
+		// launched yet. Delve will start responding to DAP requests after
+		// LaunchRequest is received, which tell us how to start it.
+
+		// TODO: we could send an InitializeRequest to Delve when
+		// it launches, wait for its response and sanity check the capabilities
+		// it reports. Once DAP support in Delve is complete, this can be part
+		// of making sure that the "dlv" binary we find is sufficiently
+		// up-to-date to talk DAP with us.
+		this.sendResponse(response);
+		log('InitializeResponse');
+	}
+
+	protected launchRequest(
+		response: DebugProtocol.LaunchResponse,
+		args: LaunchRequestArguments,
+		request: DebugProtocol.Request
+	): void {
+		// Setup logger now that we have the 'trace' level passed in from
+		// LaunchRequestArguments.
+		this.logLevel =
+			args.trace === 'verbose'
+				? Logger.LogLevel.Verbose
+				: args.trace === 'log'
+					? Logger.LogLevel.Log
+					: Logger.LogLevel.Error;
+		const logPath =
+			this.logLevel !== Logger.LogLevel.Error ? path.join(os.tmpdir(), 'vscode-godlvdapdebug.txt') : undefined;
+		logger.setup(this.logLevel, logPath);
+
+		log('launchRequest');
+
+		if (!args.port) {
+			args.port = this.DEFAULT_DELVE_PORT;
+		}
+		if (!args.host) {
+			args.host = this.DEFAULT_DELVE_HOST;
+		}
+
+		// TODO: if this is a noDebug launch request, don't launch Delve;
+		// instead, run the program directly.
+
+		this.dlvClient = new DelveClient(args);
+
+		this.dlvClient.on('stdout', (str) => {
+			log('dlv stdout:', str);
+		});
+
+		this.dlvClient.on('stderr', (str) => {
+			log('dlv stderr:', str);
+		});
+
+		this.dlvClient.on('connected', () => {
+			this.dlvClient.send(request);
+		});
+
+		this.dlvClient.on('close', (rc) => {
+			if (rc !== 0) {
+				this.sendErrorResponse(
+					response,
+					3000,
+					'Failed to continue: Check the debug console for details.');
+			}
+			log('Sending TerminatedEvent as delve is closed');
+			this.sendEvent(new TerminatedEvent());
+		});
+
+		// Relay events and responses back to vscode. In the future we will
+		// add middleware here to intercept specific kinds of responses/events
+		// for special handling.
+		this.dlvClient.on('event', (event) => {
+			this.sendEvent(event);
+		});
+
+		this.dlvClient.on('response', (resp) => {
+			this.sendResponse(resp);
+		});
+	}
+
+	protected attachRequest(
+		response: DebugProtocol.AttachResponse,
+		args: AttachRequestArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected disconnectRequest(
+		response: DebugProtocol.DisconnectResponse,
+		args: DebugProtocol.DisconnectArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected terminateRequest(
+		response: DebugProtocol.TerminateResponse,
+		args: DebugProtocol.TerminateArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected restartRequest(
+		response: DebugProtocol.RestartResponse,
+		args: DebugProtocol.RestartArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected setBreakPointsRequest(
+		response: DebugProtocol.SetBreakpointsResponse,
+		args: DebugProtocol.SetBreakpointsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected setFunctionBreakPointsRequest(
+		response: DebugProtocol.SetFunctionBreakpointsResponse,
+		args: DebugProtocol.SetFunctionBreakpointsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected setExceptionBreakPointsRequest(
+		response: DebugProtocol.SetExceptionBreakpointsResponse,
+		args: DebugProtocol.SetExceptionBreakpointsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected configurationDoneRequest(
+		response: DebugProtocol.ConfigurationDoneResponse,
+		args: DebugProtocol.ConfigurationDoneArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected continueRequest(
+		response: DebugProtocol.ContinueResponse,
+		args: DebugProtocol.ContinueArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected nextRequest(
+		response: DebugProtocol.NextResponse,
+		args: DebugProtocol.NextArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected stepInRequest(
+		response: DebugProtocol.StepInResponse,
+		args: DebugProtocol.StepInArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected stepOutRequest(
+		response: DebugProtocol.StepOutResponse,
+		args: DebugProtocol.StepOutArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected stepBackRequest(
+		response: DebugProtocol.StepBackResponse,
+		args: DebugProtocol.StepBackArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected reverseContinueRequest(
+		response: DebugProtocol.ReverseContinueResponse,
+		args: DebugProtocol.ReverseContinueArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected restartFrameRequest(
+		response: DebugProtocol.RestartFrameResponse,
+		args: DebugProtocol.RestartFrameArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected gotoRequest(
+		response: DebugProtocol.GotoResponse,
+		args: DebugProtocol.GotoArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected pauseRequest(
+		response: DebugProtocol.PauseResponse,
+		args: DebugProtocol.PauseArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected sourceRequest(
+		response: DebugProtocol.SourceResponse,
+		args: DebugProtocol.SourceArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected threadsRequest(
+		response: DebugProtocol.ThreadsResponse,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected terminateThreadsRequest(
+		response: DebugProtocol.TerminateThreadsResponse,
+		args: DebugProtocol.TerminateThreadsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected stackTraceRequest(
+		response: DebugProtocol.StackTraceResponse,
+		args: DebugProtocol.StackTraceArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected scopesRequest(
+		response: DebugProtocol.ScopesResponse,
+		args: DebugProtocol.ScopesArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected variablesRequest(
+		response: DebugProtocol.VariablesResponse,
+		args: DebugProtocol.VariablesArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected setVariableRequest(
+		response: DebugProtocol.SetVariableResponse,
+		args: DebugProtocol.SetVariableArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected setExpressionRequest(
+		response: DebugProtocol.SetExpressionResponse,
+		args: DebugProtocol.SetExpressionArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected evaluateRequest(
+		response: DebugProtocol.EvaluateResponse,
+		args: DebugProtocol.EvaluateArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected stepInTargetsRequest(
+		response: DebugProtocol.StepInTargetsResponse,
+		args: DebugProtocol.StepInTargetsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected gotoTargetsRequest(
+		response: DebugProtocol.GotoTargetsResponse,
+		args: DebugProtocol.GotoTargetsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected completionsRequest(
+		response: DebugProtocol.CompletionsResponse,
+		args: DebugProtocol.CompletionsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected exceptionInfoRequest(
+		response: DebugProtocol.ExceptionInfoResponse,
+		args: DebugProtocol.ExceptionInfoArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected loadedSourcesRequest(
+		response: DebugProtocol.LoadedSourcesResponse,
+		args: DebugProtocol.LoadedSourcesArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected dataBreakpointInfoRequest(
+		response: DebugProtocol.DataBreakpointInfoResponse,
+		args: DebugProtocol.DataBreakpointInfoArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected setDataBreakpointsRequest(
+		response: DebugProtocol.SetDataBreakpointsResponse,
+		args: DebugProtocol.SetDataBreakpointsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected readMemoryRequest(
+		response: DebugProtocol.ReadMemoryResponse,
+		args: DebugProtocol.ReadMemoryArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected disassembleRequest(
+		response: DebugProtocol.DisassembleResponse,
+		args: DebugProtocol.DisassembleArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected cancelRequest(
+		response: DebugProtocol.CancelResponse,
+		args: DebugProtocol.CancelArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected breakpointLocationsRequest(
+		response: DebugProtocol.BreakpointLocationsResponse,
+		args: DebugProtocol.BreakpointLocationsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+
+	protected setInstructionBreakpointsRequest(
+		response: DebugProtocol.SetInstructionBreakpointsResponse,
+		args: DebugProtocol.SetInstructionBreakpointsArguments,
+		request?: DebugProtocol.Request
+	): void {
+		this.dlvClient.send(request);
+	}
+}
+
+// DelveClient provides a DAP client to talk to a DAP server in Delve.
+//
+// After creation, it emits the following events:
+//
+//    'connected':            delve is connected to delve
+//    'request (request)':    delve sent request
+//    'response (response)':  delve sent response
+//    'event (event)':        delve sent event
+//    'stdout' (str):         delve emitted str to stdout
+//    'stderr' (str):         delve emitted str to stderr
+//    'close' (rc):           delve exited with return code rc
+class DelveClient extends DAPClient {
+	private debugProcess: ChildProcess;
+	private serverStarted: boolean = false;
+
+	constructor(launchArgs: LaunchRequestArguments) {
+		super();
+
+		const launchArgsEnv = launchArgs.env || {};
+		const env = Object.assign({}, process.env, launchArgsEnv);
+
+		// Let users override direct path to delve by setting it in the env
+		// map in launch.json; if unspecified, fall back to dlvToolPath.
+		let dlvPath = launchArgsEnv['dlvPath'];
+		if (!dlvPath) {
+			dlvPath = launchArgs.dlvToolPath;
+		}
+
+		if (!fs.existsSync(dlvPath)) {
+			log(
+				`Couldn't find dlv at the Go tools path, ${process.env['GOPATH']}${
+				env['GOPATH'] ? ', ' + env['GOPATH'] : ''
+				} or ${envPath}`
+			);
+			throw new Error(
+				`Cannot find Delve debugger. Install from https://github.com/go-delve/delve/ & ensure it is in your Go tools path, "GOPATH/bin" or "PATH".`
+			);
+		}
+
+		const dlvArgs = new Array<string>();
+		dlvArgs.push('dap');
+		dlvArgs.push(`--listen=${launchArgs.host}:${launchArgs.port}`);
+		if (launchArgs.showLog) {
+			dlvArgs.push('--log=' + launchArgs.showLog.toString());
+		}
+		if (launchArgs.logOutput) {
+			dlvArgs.push('--log-output=' + launchArgs.logOutput);
+		}
+
+		log(`Running: ${dlvPath} ${dlvArgs.join(' ')}`);
+
+		this.debugProcess = spawn(dlvPath, dlvArgs, {
+			cwd: path.dirname(launchArgs.program),
+			env
+		});
+
+		this.debugProcess.stderr.on('data', (chunk) => {
+			const str = chunk.toString();
+			this.emit('stderr', str);
+		});
+
+		this.debugProcess.stdout.on('data', (chunk) => {
+			const str = chunk.toString();
+			this.emit('stdout', str);
+
+			if (!this.serverStarted) {
+				this.serverStarted = true;
+				this.connectSocketToServer(launchArgs.port, launchArgs.host);
+			}
+		});
+
+		this.debugProcess.on('close', (rc) => {
+			if (rc) {
+				logError(`Process exiting with code: ${rc} signal: ${this.debugProcess.killed}`);
+			} else {
+				log(`Process exiting normally ${this.debugProcess.killed}`);
+			}
+			this.emit('close', rc);
+		});
+
+		this.debugProcess.on('error', (err) => {
+			throw err;
+		});
+	}
+
+	// Connect this client to the server. The server is expected to be listening
+	// on host:port.
+	private connectSocketToServer(port: number, host: string) {
+		// Add a slight delay to ensure that Delve started up the server.
+		setTimeout(() => {
+			const socket = net.createConnection(
+				port,
+				host,
+				() => {
+					this.connect(socket, socket);
+					this.emit('connected');
+				});
+
+			socket.on('error', (err) => {
+				throw err;
+			});
+		}, 200);
+	}
+}
diff --git a/src/debugAdapter2/goDlvDebugMain.ts b/src/debugAdapter2/goDlvDebugMain.ts
new file mode 100644
index 0000000..2d4cdb8
--- /dev/null
+++ b/src/debugAdapter2/goDlvDebugMain.ts
@@ -0,0 +1,10 @@
+/*---------------------------------------------------------
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+// This file is for running the godlvdap debug adapter as a standalone program
+// in a separate process (e.g. when working in --server mode).
+import { GoDlvDapDebugSession } from './goDlvDebug';
+
+GoDlvDapDebugSession.run(GoDlvDapDebugSession);
diff --git a/src/goBrowsePackage.ts b/src/goBrowsePackage.ts
index c2b041a..f27b107 100644
--- a/src/goBrowsePackage.ts
+++ b/src/goBrowsePackage.ts
@@ -9,7 +9,7 @@
 import path = require('path');
 import vscode = require('vscode');
 import { getAllPackages } from './goPackages';
-import { envPath } from './goPath';
+import { envPath, getCurrentGoRoot } from './goPath';
 import { getBinPath, getCurrentGoPath, getImportPath } from './util';
 
 export function browsePackages() {
@@ -40,7 +40,7 @@
 	const goRuntimePath = getBinPath('go');
 	if (!goRuntimePath) {
 		return vscode.window.showErrorMessage(
-			`Failed to run "go list" to fetch packages as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go list" to fetch packages as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 		);
 	}
 
diff --git a/src/goCover.ts b/src/goCover.ts
index 6185838..3edc6bb 100644
--- a/src/goCover.ts
+++ b/src/goCover.ts
@@ -5,13 +5,15 @@
 
 'use strict';
 
+import cp = require('child_process');
 import fs = require('fs');
 import path = require('path');
-import rl = require('readline');
+import util = require('util');
 import vscode = require('vscode');
 import { isModSupported } from './goModules';
+import { envPath } from './goPath';
 import { getTestFlags, goTest, showTestOutput, TestConfig } from './testUtils';
-import { getGoConfig, getTempFilePath } from './util';
+import { getBinPath, getCurrentGoPath, getGoConfig, getWorkspaceFolderPath } from './util';
 
 let gutterSvgs: { [key: string]: string };
 let decorators: {
@@ -93,6 +95,8 @@
 export function updateCodeCoverageDecorators(coverageDecoratorConfig: any) {
 	// These defaults are chosen to be distinguishable in nearly any color scheme (even Red)
 	// as well as by people who have difficulties with color perception.
+	// (how do these relate the defaults in package.json?)
+	// and where do the defaults actually come from? (raised as issue #256)
 	decoratorConfig = {
 		type: 'highlight',
 		coveredHighlightColor: 'rgba(64,128,128,0.5)',
@@ -152,6 +156,8 @@
 }
 
 let coverageFiles: { [key: string]: CoverageData } = {};
+let coveragePath = new Map<string, CoverageData>();
+let pathsToDirs = new Map<string, string>();
 let isCoverageApplied: boolean = false;
 
 /**
@@ -159,6 +165,8 @@
  */
 function clearCoverage() {
 	coverageFiles = {};
+	coveragePath = new Map<string, CoverageData>();
+	pathsToDirs = new Map<string, string>();
 	disposeDecorators();
 	isCoverageApplied = false;
 }
@@ -167,48 +175,49 @@
  * Extract the coverage data from the given cover profile & apply them on the files in the open editors.
  * @param coverProfilePath Path to the file that has the cover profile data
  * @param packageDirPath Absolute path of the package for which the coverage was calculated
+ * @param testDir Directory to execute go list in, when there is no workspace, for some tests
  */
-export function applyCodeCoverageToAllEditors(coverProfilePath: string, packageDirPath: string): Promise<void> {
-	return new Promise((resolve, reject) => {
+export function applyCodeCoverageToAllEditors(coverProfilePath: string, testDir?: string): Promise<void> {
+	const v = new Promise<void>((resolve, reject) => {
 		try {
 			// Clear existing coverage files
 			clearCoverage();
 
-			const lines = rl.createInterface({
-				input: fs.createReadStream(coverProfilePath),
-				output: undefined
-			});
-
-			lines.on('line', (data: string) => {
-				// go test coverageprofile generates output:
-				//    filename:StartLine.StartColumn,EndLine.EndColumn Hits CoverCount
-				// The first line will be "mode: set" which will be ignored
-				const fileRange = data.match(/([^:]+)\:([\d]+)\.([\d]+)\,([\d]+)\.([\d]+)\s([\d]+)\s([\d]+)/);
-				if (!fileRange) {
-					return;
+			// collect the packages named in the coverage file
+			const seenPaths = new Set<string>();
+			// for now read synchronously and hope for no errors
+			const contents = fs.readFileSync(coverProfilePath).toString();
+			contents.split('\n').forEach((line) => {
+				const parse = line.match(/([^:]+)\:([\d]+)\.([\d]+)\,([\d]+)\.([\d]+)\s([\d]+)\s([\d]+)/);
+				if (!parse) { return; }
+				const lastSlash = parse[1].lastIndexOf('/'); // ok for windows?
+				if (lastSlash !== -1) {
+					seenPaths.add(parse[1].slice(0, lastSlash));
 				}
 
-				const filePath = path.join(packageDirPath, path.basename(fileRange[1]));
-				const coverage = getCoverageData(filePath);
+				// and fill in coveragePath
+				const coverage = getPathData(parse[1]);
 				const range = new vscode.Range(
 					// Start Line converted to zero based
-					parseInt(fileRange[2], 10) - 1,
+					parseInt(parse[2], 10) - 1,
 					// Start Column converted to zero based
-					parseInt(fileRange[3], 10) - 1,
+					parseInt(parse[3], 10) - 1,
 					// End Line converted to zero based
-					parseInt(fileRange[4], 10) - 1,
+					parseInt(parse[4], 10) - 1,
 					// End Column converted to zero based
-					parseInt(fileRange[5], 10) - 1
+					parseInt(parse[5], 10) - 1
 				);
 				// If is Covered (CoverCount > 0)
-				if (parseInt(fileRange[7], 10) > 0) {
+				if (parseInt(parse[7], 10) > 0) {
 					coverage.coveredRange.push(range);
 				} else {
 					coverage.uncoveredRange.push(range);
 				}
-				setCoverageData(filePath, coverage);
+				setPathData(parse[1], coverage);
 			});
-			lines.on('close', () => {
+			const pathPromise = getPathsToDirs(seenPaths, pathsToDirs, testDir);
+			pathPromise.then(() => {
+				createCoverageData();
 				setDecorators();
 				vscode.window.visibleTextEditors.forEach(applyCodeCoverage);
 				resolve();
@@ -218,6 +227,7 @@
 			reject(e);
 		}
 	});
+	return v;
 }
 
 /**
@@ -238,6 +248,33 @@
 }
 
 /**
+ * Get the CoverageData for an import path.
+ * @param importPath
+ */
+function getPathData(importPath: string): CoverageData {
+	return coveragePath.get(importPath) || { coveredRange: [], uncoveredRange: [] };
+}
+
+/**
+ * Set the CoverageData for an import path.
+ * @param importPath
+ * @param data
+ */
+function setPathData(importPath: string, data: CoverageData) {
+	coveragePath.set(importPath, data);
+}
+
+function createCoverageData() {
+	coveragePath.forEach((cd, ip) => {
+		const lastSlash = ip.lastIndexOf('/');
+		const importPath = ip.slice(0, lastSlash);
+		const fileDir = pathsToDirs.get(importPath);
+		const file = fileDir + ip.slice(lastSlash); // what about Windows?
+		setCoverageData(file, cd);
+	});
+}
+
+/**
  * Set the object that holds the coverage data for given file path.
  * @param filePath
  * @param data
@@ -334,6 +371,41 @@
 }
 
 /**
+ * Fill the map of directory paths corresponding to input package paths
+ * @param set Set<string> of import package paths
+ */
+async function getPathsToDirs(set: Set<string>, res: Map<string, string>, testDir?: string) {
+	const goRuntimePath = getBinPath('go');
+	if (!goRuntimePath) {
+		vscode.window.showErrorMessage(
+			`Failed to run, as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+		);
+	}
+	const args: string[] = ['list', '-f', '{{.ImportPath}}:{{.Dir}}'];
+	set.forEach((s) => args.push(s));
+
+	const options: { [key: string]: any } = {
+		env: Object.assign({}, process.env, { GOPATH: getCurrentGoPath() })
+	};
+	const workDir = getWorkspaceFolderPath();
+	// If there is a workDir then probably it is what we want
+	// Otherwise maybe a test suggested a directory.
+	if (workDir) {
+		options['cwd'] = workDir;
+	} else if (testDir) {
+		options['cwd'] = testDir;
+	}
+
+	const execFile = util.promisify(cp.execFile);
+	const { stdout } = await execFile(goRuntimePath, args, options);
+	stdout.split('\n').forEach((line) => {
+		const flds = line.split(':');
+		if (flds.length !== 2) { return; }
+		res.set(flds[0], flds[1]);
+	});
+}
+
+/**
  * If current editor has Code coverage applied, then remove it.
  * Else run tests to get the coverage and apply.
  */
@@ -383,3 +455,27 @@
 		return idx > -1 && idx <= change.range.start.character;
 	});
 }
+
+// These routines enable testing without starting an editing session.
+
+export function coverageFilesForTest():  { [key: string]: CoverageData; } {
+	return coverageFiles;
+}
+
+export function initForTest() {
+	if (!decoratorConfig) {
+		// this code is unnecessary except for testing, where there may be no workspace
+		// nor the normal flow of initializations
+		const x = 'rgba(0,0,0,0)';
+		if (!gutterSvgs) {
+			gutterSvgs = { x };
+		}
+		decoratorConfig = {
+			type: 'highlight',
+			coveredHighlightColor: x,
+			uncoveredHighlightColor: x,
+			coveredGutterStyle: x,
+			uncoveredGutterStyle: x
+		};
+	}
+}
diff --git a/src/goEnv.ts b/src/goEnv.ts
index aa02546..b872319 100644
--- a/src/goEnv.ts
+++ b/src/goEnv.ts
@@ -7,7 +7,7 @@
 
 import path = require('path');
 import vscode = require('vscode');
-import { getCurrentGoPath, getGoConfig, getToolsGopath, resolvePath } from './util';
+import { getCurrentGoPath, getGoConfig, getToolsGopath } from './util';
 
 // toolInstallationEnvironment returns the environment in which tools should
 // be installed. It always returns a new object.
diff --git a/src/goEnvironmentStatus.ts b/src/goEnvironmentStatus.ts
new file mode 100644
index 0000000..9175d11
--- /dev/null
+++ b/src/goEnvironmentStatus.ts
@@ -0,0 +1,350 @@
+/*---------------------------------------------------------
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+'use strict';
+
+import cp = require('child_process');
+import fs = require('fs');
+import os = require('os');
+import path = require('path');
+import { promisify } from 'util';
+import vscode = require('vscode');
+import WebRequest = require('web-request');
+import { toolInstallationEnvironment } from './goEnv';
+import { getCurrentGoRoot, pathExists } from './goPath';
+import { outputChannel } from './goStatus';
+import { getBinPath, getGoConfig, getGoVersion, timeout } from './util';
+
+export class GoEnvironmentOption {
+	public static fromQuickPickItem({ description, label }: vscode.QuickPickItem): GoEnvironmentOption {
+		return new GoEnvironmentOption(description, label);
+	}
+
+	constructor(public binpath: string, public label: string) {}
+
+	public toQuickPickItem(): vscode.QuickPickItem {
+		return {
+			label: this.label,
+			description: this.binpath,
+		};
+	}
+}
+
+// statusbar item for switching the Go environment
+let goEnvStatusbarItem: vscode.StatusBarItem;
+let terminalCreationListener: vscode.Disposable;
+
+/**
+ * Initialize the status bar item with current Go binary
+ */
+export async function initGoStatusBar() {
+	if (!goEnvStatusbarItem) {
+		goEnvStatusbarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 50);
+	}
+	// set Go version and command
+	const version = await getGoVersion();
+	const goOption = new GoEnvironmentOption(version.binaryPath, formatGoVersion(version.format()));
+
+	// ensure terminals use the correct Go version
+	if (!terminalCreationListener) {
+		updateIntegratedTerminal(vscode.window.activeTerminal);
+		terminalCreationListener = vscode.window.onDidOpenTerminal(updateIntegratedTerminal);
+	}
+
+	hideGoStatusBar();
+	goEnvStatusbarItem.text = goOption.label;
+	goEnvStatusbarItem.command = 'go.environment.choose';
+	showGoStatusBar();
+}
+
+/**
+ * disable the Go environment status bar item
+ */
+export function disposeGoStatusBar() {
+	if (!!goEnvStatusbarItem) {
+		goEnvStatusbarItem.dispose();
+	}
+	if (!!terminalCreationListener) {
+		terminalCreationListener.dispose();
+	}
+}
+
+/**
+ * Show the Go Environment statusbar item on the statusbar
+ */
+export function showGoStatusBar() {
+	if (!!goEnvStatusbarItem) {
+		goEnvStatusbarItem.show();
+	}
+}
+
+/**
+ * Hide the Go Environment statusbar item from the statusbar
+ */
+export function hideGoStatusBar() {
+	if (!!goEnvStatusbarItem) {
+		goEnvStatusbarItem.hide();
+	}
+}
+
+/**
+ * Present a command palette menu to the user to select their go binary
+ */
+export async function chooseGoEnvironment() {
+	if (!goEnvStatusbarItem) {
+		return;
+	}
+
+	// fetch default go and uninstalled go versions
+	let defaultOption: GoEnvironmentOption;
+	let uninstalledOptions: GoEnvironmentOption[];
+	let goSDKOptions: GoEnvironmentOption[];
+	try {
+		[defaultOption, uninstalledOptions, goSDKOptions] = await Promise.all([
+			getDefaultGoOption(),
+			fetchDownloadableGoVersions(),
+			getSDKGoOptions()
+		]);
+	} catch (e) {
+		vscode.window.showErrorMessage(e.message);
+		return;
+	}
+
+	// create quick pick items
+	const uninstalledQuickPicks = uninstalledOptions.map((op) => op.toQuickPickItem());
+	const defaultQuickPick = defaultOption.toQuickPickItem();
+	const goSDKQuickPicks = goSDKOptions.map((op) => op.toQuickPickItem());
+
+	// dedup options by eliminating duplicate paths (description)
+	const options = [defaultQuickPick, ...goSDKQuickPicks, ...uninstalledQuickPicks].reduce((opts, nextOption) => {
+		if (opts.find((op) => op.description === nextOption.description || op.label === nextOption.label)) {
+			return opts;
+		}
+		return [...opts, nextOption];
+	}, [] as vscode.QuickPickItem[]);
+
+	// get user's selection, return if none was made
+	const selection = await vscode.window.showQuickPick<vscode.QuickPickItem>(options);
+	if (!selection) {
+		return;
+	}
+
+	// update currently selected go
+	try {
+		await setSelectedGo(GoEnvironmentOption.fromQuickPickItem(selection), vscode.ConfigurationTarget.Workspace);
+		vscode.window.showInformationMessage(`Switched to ${selection.label}`);
+	} catch (e) {
+		vscode.window.showErrorMessage(e.message);
+	}
+}
+
+/**
+ * update the selected go path and label in the workspace state
+ */
+export async function setSelectedGo(
+	selectedGo: GoEnvironmentOption, scope: vscode.ConfigurationTarget, promptReload = true
+) {
+	const execFile = promisify(cp.execFile);
+
+	const goConfig = getGoConfig();
+	const alternateTools: any = goConfig.get('alternateTools') || {};
+	// if the selected go version is not installed, install it
+	if (selectedGo.binpath.startsWith('go get')) {
+		// start a loading indicator
+		await vscode.window.withProgress({
+			title: `Downloading ${selectedGo.label}`,
+			location: vscode.ProgressLocation.Notification,
+		}, async () => {
+			outputChannel.show();
+			outputChannel.clear();
+
+			outputChannel.appendLine('Finding Go executable for downloading');
+			const goExecutable = getBinPath('go');
+			if (!goExecutable) {
+				outputChannel.appendLine('Could not find Go executable.');
+				throw new Error('Could not find Go tool.');
+			}
+
+			// use the current go executable to download the new version
+			const env = toolInstallationEnvironment();
+			const [, ...args] = selectedGo.binpath.split(' ');
+			outputChannel.appendLine(`Running ${goExecutable} ${args.join(' ')}`);
+			try {
+				await execFile(goExecutable, args, { env });
+			} catch (getErr) {
+				outputChannel.appendLine(`Error finding Go: ${getErr}`);
+				throw new Error('Could not find Go version.');
+			}
+
+			// run `goX.X download`
+			const newExecutableName = args[1].split('/')[2];
+			const goXExecutable = getBinPath(newExecutableName);
+			outputChannel.appendLine(`Running: ${goXExecutable} download`);
+			try {
+				await execFile(goXExecutable, ['download'], { env });
+			} catch (downloadErr) {
+				outputChannel.appendLine(`Error finishing installation: ${downloadErr}`);
+				throw new Error('Could not download Go version.');
+			}
+
+			outputChannel.appendLine('Finding newly downloaded Go');
+			const sdkPath = path.join(process.env.HOME, 'sdk');
+			if (!await pathExists(sdkPath)) {
+				outputChannel.appendLine(`SDK path does not exist: ${sdkPath}`);
+				throw new Error(`SDK path does not exist: ${sdkPath}`);
+			}
+
+			const readdir = promisify(fs.readdir);
+			const subdirs = await readdir(sdkPath);
+			const dir = subdirs.find((subdir) => subdir === newExecutableName);
+			if (!dir) {
+				outputChannel.appendLine('Could not find newly downloaded Go');
+				throw new Error('Could not install Go version.');
+			}
+
+			const binpath = path.join(sdkPath, dir, 'bin', 'go');
+			const newAlternateTools = {
+				...alternateTools,
+				go: binpath,
+			};
+			await goConfig.update('alternateTools', newAlternateTools, scope);
+			goEnvStatusbarItem.text = selectedGo.label;
+
+			outputChannel.appendLine('Updating integrated terminals');
+			vscode.window.terminals.forEach(updateIntegratedTerminal);
+			outputChannel.appendLine('Success!');
+		});
+	} else {
+		const newAlternateTools = {
+			...alternateTools,
+			go: selectedGo.binpath,
+		};
+		await goConfig.update('alternateTools', newAlternateTools, scope);
+		goEnvStatusbarItem.text = selectedGo.label;
+	}
+	// prompt the user to reload the window
+	// promptReload defaults to true and should only be false for tests
+	if (promptReload) {
+		const choice = await vscode.window.showInformationMessage('Please reload the window to finish applying changes.', 'Reload Window');
+		if (choice === 'Reload Window') {
+			await vscode.commands.executeCommand('workbench.action.reloadWindow');
+		}
+	}
+}
+
+/**
+ * update the PATH variable in the given terminal to default to the currently selected Go
+ */
+export async function updateIntegratedTerminal(terminal: vscode.Terminal) {
+	if (!terminal) { return; }
+	const goroot = path.join(getCurrentGoRoot(), 'bin');
+	const isWindows = terminal.name.toLowerCase() === 'powershell' || terminal.name.toLowerCase() === 'cmd';
+
+	// append the goroot to the beginning of the PATH so it takes precedence
+	// TODO: add support for more terminal names
+	// this assumes all non-windows shells are bash-like.
+	if (isWindows) {
+		terminal.sendText(`set PATH=${goroot};%Path%`, true);
+		terminal.sendText('cls');
+	} else {
+		terminal.sendText(`export PATH=${goroot}:$PATH`, true);
+		terminal.sendText('clear');
+	}
+}
+
+/**
+ * retreive the current selected Go from the workspace state
+ */
+export async function getSelectedGo(): Promise<GoEnvironmentOption> {
+	const goVersion = await getGoVersion();
+	return new GoEnvironmentOption(goVersion.binaryPath, formatGoVersion(goVersion.format()));
+}
+
+/**
+ * return reference to the statusbar item
+ */
+export function getGoEnvironmentStatusbarItem(): vscode.StatusBarItem {
+	return goEnvStatusbarItem;
+}
+
+export function formatGoVersion(version: string): string {
+	const versionWords = version.split(' ');
+	if (versionWords[0] === 'devel') {
+		// Go devel +hash
+		return `Go ${versionWords[0]} ${versionWords[4]}`;
+	} else if (versionWords.length > 0) {
+		// some other version format
+		return `Go ${version.substr(0, 8)}`;
+	} else {
+		// default semantic version format
+		return `Go ${versionWords[0]}`;
+	}
+}
+
+async function getSDKGoOptions(): Promise<GoEnvironmentOption[]> {
+	// get list of Go versions
+	const sdkPath = path.join(os.homedir(), 'sdk');
+
+	if (!await pathExists(sdkPath)) {
+		return [];
+	}
+	const readdir = promisify(fs.readdir);
+	const subdirs = await readdir(sdkPath);
+	// the dir happens to be the version, which will be used as the label
+	// the path is assembled and used as the description
+	return subdirs.map((dir: string) =>
+		new GoEnvironmentOption(
+			path.join(sdkPath, dir, 'bin', 'go'),
+			dir.replace('go', 'Go '),
+		)
+	);
+}
+
+export async function getDefaultGoOption(): Promise<GoEnvironmentOption> {
+	// make goroot default to go.goroot
+	const goroot = getCurrentGoRoot();
+	if (!goroot) {
+		throw new Error('No Go command could be found.');
+	}
+
+	// set Go version and command
+	const version = await getGoVersion();
+	return new GoEnvironmentOption(
+		path.join(goroot, 'bin', 'go'),
+		formatGoVersion(version.format()),
+	);
+}
+
+/**
+ * make a web request to get versions of Go
+ */
+interface GoVersionWebResult {
+	version: string;
+	stable: boolean;
+	files: {
+		filename: string;
+		os: string;
+		arch: string;
+		version: string;
+		sha256: string;
+		size: number;
+		kind: string;
+	}[];
+}
+async function fetchDownloadableGoVersions(): Promise<GoEnvironmentOption[]> {
+	// fetch information about what Go versions are available to install
+	const webResults = await WebRequest.json<GoVersionWebResult[]>('https://golang.org/dl/?mode=json');
+	if (!webResults) {
+		return [];
+	}
+
+	// turn the web result into GoEnvironmentOption model
+	return webResults.reduce((opts, result: GoVersionWebResult) => {
+		// TODO: allow downloading from different sites
+		const dlPath = `go get golang.org/dl/${result.version}`;
+		const label = result.version.replace('go', 'Go ');
+		return [...opts, new GoEnvironmentOption(dlPath, label)];
+	}, []);
+}
diff --git a/src/goGetPackage.ts b/src/goGetPackage.ts
index 80dda27..272a995 100644
--- a/src/goGetPackage.ts
+++ b/src/goGetPackage.ts
@@ -8,7 +8,7 @@
 import cp = require('child_process');
 import vscode = require('vscode');
 import { buildCode } from './goBuild';
-import { envPath } from './goPath';
+import { envPath, getCurrentGoRoot } from './goPath';
 import { outputChannel } from './goStatus';
 import { getBinPath, getCurrentGoPath, getImportPath } from './util';
 
@@ -26,7 +26,7 @@
 	const goRuntimePath = getBinPath('go');
 	if (!goRuntimePath) {
 		return vscode.window.showErrorMessage(
-			`Failed to run "go get" to get package as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go get" to get package as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 		);
 	}
 
diff --git a/src/goImplementations.ts b/src/goImplementations.ts
index 4ee9e29..da39a51 100644
--- a/src/goImplementations.ts
+++ b/src/goImplementations.ts
@@ -10,14 +10,14 @@
 import vscode = require('vscode');
 import { toolExecutionEnvironment } from './goEnv';
 import { promptForMissingTool } from './goInstallTools';
-import { envPath } from './goPath';
+import { envPath, getCurrentGoRoot } from './goPath';
 import {
 	byteOffsetAt,
 	canonicalizeGOPATHPrefix,
 	getBinPath,
 	getGoConfig,
 	getWorkspaceFolderPath,
-	killTree
+	killTree,
 } from './util';
 
 interface GoListOutput {
@@ -57,7 +57,7 @@
 		const goRuntimePath = getBinPath('go');
 		if (!goRuntimePath) {
 			vscode.window.showErrorMessage(
-				`Failed to run "go list" to get the scope to find implementations as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+				`Failed to run "go list" to get the scope to find implementations as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 			);
 			return;
 		}
diff --git a/src/goImport.ts b/src/goImport.ts
index fade834..5a9df7e 100644
--- a/src/goImport.ts
+++ b/src/goImport.ts
@@ -11,7 +11,7 @@
 import { promptForMissingTool } from './goInstallTools';
 import { documentSymbols, GoOutlineImportsOptions } from './goOutline';
 import { getImportablePackages } from './goPackages';
-import { envPath } from './goPath';
+import { envPath, getCurrentGoRoot } from './goPath';
 import { getBinPath, getImportPath, parseFilePrelude } from './util';
 
 const missingToolMsg = 'Missing tool: ';
@@ -180,7 +180,7 @@
 	const goRuntimePath = getBinPath('go');
 	if (!goRuntimePath) {
 		vscode.window.showErrorMessage(
-			`Failed to run "go list" to find the package as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go list" to find the package as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 		);
 		return;
 	}
diff --git a/src/goInstall.ts b/src/goInstall.ts
index 4f351aa..859da2a 100644
--- a/src/goInstall.ts
+++ b/src/goInstall.ts
@@ -8,7 +8,7 @@
 import vscode = require('vscode');
 import { toolExecutionEnvironment } from './goEnv';
 import { isModSupported } from './goModules';
-import { envPath, getCurrentGoWorkspaceFromGOPATH } from './goPath';
+import { envPath, getCurrentGoRoot, getCurrentGoWorkspaceFromGOPATH } from './goPath';
 import { outputChannel } from './goStatus';
 import { getBinPath, getCurrentGoPath, getGoConfig, getModuleCache } from './util';
 
@@ -28,7 +28,7 @@
 	const goRuntimePath = getBinPath('go');
 	if (!goRuntimePath) {
 		vscode.window.showErrorMessage(
-			`Failed to run "go install" to install the package as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go install" to install the package as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 		);
 		return;
 	}
diff --git a/src/goInstallTools.ts b/src/goInstallTools.ts
index eb641af..62b22fc 100644
--- a/src/goInstallTools.ts
+++ b/src/goInstallTools.ts
@@ -12,9 +12,10 @@
 import util = require('util');
 import vscode = require('vscode');
 import { toolInstallationEnvironment } from './goEnv';
+import { initGoStatusBar } from './goEnvironmentStatus';
 import { getLanguageServerToolPath } from './goLanguageServer';
 import { restartLanguageServer } from './goMain';
-import { envPath, getToolFromToolPath } from './goPath';
+import { envPath, getCurrentGoRoot, getToolFromToolPath, setCurrentGoRoot } from './goPath';
 import { hideGoStatus, outputChannel, showGoStatus } from './goStatus';
 import {
 	containsTool,
@@ -33,8 +34,7 @@
 	getGoVersion,
 	getTempFilePath,
 	GoVersion,
-	resolvePath,
-	rmdirRecursive
+	rmdirRecursive,
 } from './util';
 
 // declinedUpdates tracks the tools that the user has declined to update.
@@ -326,7 +326,7 @@
 		case 'Release Notes':
 			vscode.commands.executeCommand(
 				'vscode.open',
-				vscode.Uri.parse('https://github.com/golang/go/issues/33030#issuecomment-510151934')
+				vscode.Uri.parse(`https://github.com/golang/tools/releases/tag/${tool.name}/v${newVersion}`)
 			);
 			break;
 		default:
@@ -336,44 +336,25 @@
 }
 
 export function updateGoVarsFromConfig(): Promise<void> {
-	const goroot = getGoConfig()['goroot'];
-	if (goroot) {
-		process.env['GOROOT'] = resolvePath(goroot);
-	}
-
-	if (process.env['GOPATH'] && process.env['GOROOT'] && process.env['GOPROXY'] && process.env['GOBIN']) {
+	// FIXIT: when user changes the environment variable settings or go.gopath, the following
+	// condition prevents from updating the process.env accordingly, so the extension will lie.
+	// Needs to clean up.
+	if (process.env['GOPATH'] && process.env['GOPROXY'] && process.env['GOBIN']) {
 		return Promise.resolve();
 	}
 
-	// If GOPATH is still not set, then use the one from `go env`
-	const goRuntimePath = getBinPath('go');
+	// FIXIT: if updateGoVarsFromConfig is called again after addGoRuntimeBaseToPATH sets PATH,
+	// the go chosen by getBinPath based on PATH will not change.
+	const goRuntimePath = getBinPath('go', false);
 	if (!goRuntimePath) {
 		vscode.window.showErrorMessage(
-			`Failed to run "go env" to find GOPATH as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go env" to find GOPATH as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 		);
 		return;
 	}
-	const goRuntimeBasePath = path.dirname(goRuntimePath);
-
-	// cgo and a few other Go tools expect Go binary to be in the path
-	let pathEnvVar: string;
-	if (process.env.hasOwnProperty('PATH')) {
-		pathEnvVar = 'PATH';
-	} else if (process.platform === 'win32' && process.env.hasOwnProperty('Path')) {
-		pathEnvVar = 'Path';
-	}
-	if (
-		goRuntimeBasePath &&
-		pathEnvVar &&
-		process.env[pathEnvVar] &&
-		(<string>process.env[pathEnvVar]).split(path.delimiter).indexOf(goRuntimeBasePath) === -1
-	) {
-		// Place the goRuntimeBasePath to the front so tools use the same version of go.
-		process.env[pathEnvVar] = goRuntimeBasePath + path.delimiter + process.env[pathEnvVar];
-	}
 
 	return new Promise<void>((resolve, reject) => {
-		cp.execFile(goRuntimePath, ['env', 'GOPATH', 'GOROOT', 'GOPROXY', 'GOBIN'], (err, stdout, stderr) => {
+		cp.execFile(goRuntimePath, ['env', 'GOPATH', 'GOROOT', 'GOPROXY', 'GOBIN', 'GOMODCACHE'], (err, stdout, stderr) => {
 			if (err) {
 				return reject();
 			}
@@ -381,8 +362,8 @@
 			if (!process.env['GOPATH'] && envOutput[0].trim()) {
 				process.env['GOPATH'] = envOutput[0].trim();
 			}
-			if (!process.env['GOROOT'] && envOutput[1] && envOutput[1].trim()) {
-				process.env['GOROOT'] = envOutput[1].trim();
+			if (envOutput[1] && envOutput[1].trim()) {
+				setCurrentGoRoot(envOutput[1].trim());
 			}
 			if (!process.env['GOPROXY'] && envOutput[2] && envOutput[2].trim()) {
 				process.env['GOPROXY'] = envOutput[2].trim();
@@ -390,11 +371,51 @@
 			if (!process.env['GOBIN'] && envOutput[3] && envOutput[3].trim()) {
 				process.env['GOBIN'] = envOutput[3].trim();
 			}
+			if (!process.env['GOMODCACHE']) {
+				process.env['GOMODCACHE'] = envOutput[4].trim();
+			}
+
+			// cgo, gopls, and other underlying tools will inherit the environment and attempt
+			// to locate 'go' from the PATH env var.
+			addGoRuntimeBaseToPATH(path.join(getCurrentGoRoot(), 'bin'));
+			initGoStatusBar();
+			// TODO: restart language server or synchronize with language server update.
+
 			return resolve();
 		});
 	});
 }
 
+// PATH value cached before addGoRuntimeBaseToPath modified.
+let defaultPathEnv = '';
+
+// addGoRuntimeBaseToPATH adds the given path to the front of the PATH environment variable.
+// It removes duplicates.
+// TODO: can we avoid changing PATH but utilize toolExecutionEnv?
+function addGoRuntimeBaseToPATH(newGoRuntimeBase: string) {
+	if (!newGoRuntimeBase) {
+		return;
+	}
+
+	let pathEnvVar: string;
+	if (process.env.hasOwnProperty('PATH')) {
+		pathEnvVar = 'PATH';
+	} else if (process.platform === 'win32' && process.env.hasOwnProperty('Path')) {
+		pathEnvVar = 'Path';
+	} else {
+		return;
+	}
+
+	if (!defaultPathEnv) {  // cache the default value
+		defaultPathEnv = <string>process.env[pathEnvVar];
+	}
+
+	let pathVars = defaultPathEnv.split(path.delimiter);
+	pathVars = pathVars.filter((p) => p !== newGoRuntimeBase);
+	pathVars.unshift(newGoRuntimeBase);
+	process.env[pathEnvVar] = pathVars.join(path.delimiter);
+}
+
 let alreadyOfferedToInstallTools = false;
 
 export async function offerToInstallTools() {
diff --git a/src/goLanguageServer.ts b/src/goLanguageServer.ts
index 9c5a86c..d6d2768 100644
--- a/src/goLanguageServer.ts
+++ b/src/goLanguageServer.ts
@@ -20,6 +20,8 @@
 	RevealOutputChannelOn,
 } from 'vscode-languageclient';
 import WebRequest = require('web-request');
+import { extensionId } from './const';
+import { GoCodeActionProvider } from './goCodeAction';
 import { GoDefinitionProvider } from './goDeclaration';
 import { toolExecutionEnvironment } from './goEnv';
 import { GoHoverProvider } from './goExtraInfo';
@@ -62,6 +64,8 @@
 let languageServerDisposable: vscode.Disposable;
 let latestConfig: LanguageServerConfig;
 let serverOutputChannel: vscode.OutputChannel;
+let serverTraceChannel: vscode.OutputChannel;
+let crashCount = 0;
 
 // defaultLanguageProviders is the list of providers currently registered.
 let defaultLanguageProviders: vscode.Disposable[] = [];
@@ -151,6 +155,7 @@
 		// and rebuild the language client.
 		latestConfig = config;
 		languageClient = await buildLanguageClient(config, usingGo2Go);
+		crashCount = 0;
 	}
 
 	// If the user has not enabled the language server, return early.
@@ -162,10 +167,9 @@
 	// language server.
 	if (!restartCommand) {
 		restartCommand = vscode.commands.registerCommand('go.languageserver.restart', async () => {
-			// TODO(rstambler): Enable this behavior when gopls reaches v1.0.
-			if (false) {
-				await suggestGoplsIssueReport(`Looks like you're about to manually restart the language server.`);
-			}
+			await suggestGoplsIssueReport(
+				`Looks like you're about to manually restart the language server.`,
+				errorKind.manualRestart);
 			restartLanguageServer();
 		});
 		ctx.subscriptions.push(restartCommand);
@@ -182,8 +186,13 @@
 
 async function buildLanguageClient(config: LanguageServerConfig, usingGo2Go: boolean): Promise<LanguageClient> {
 	// Reuse the same output channel for each instance of the server.
-	if (config.enabled && !serverOutputChannel) {
-		serverOutputChannel = vscode.window.createOutputChannel(config.serverName);
+	if (config.enabled) {
+		if (!serverOutputChannel) {
+			serverOutputChannel = vscode.window.createOutputChannel(config.serverName + ' (server)');
+		}
+		if (!serverTraceChannel) {
+			serverTraceChannel = vscode.window.createOutputChannel(config.serverName);
+		}
 	}
 	const c = new LanguageClient(
 		'go',  // id
@@ -230,13 +239,13 @@
 				},
 			},
 			outputChannel: serverOutputChannel,
+			traceOutputChannel: serverTraceChannel,
 			revealOutputChannelOn: RevealOutputChannelOn.Never,
 			initializationFailedHandler: (error: WebRequest.ResponseError<InitializeError>): boolean => {
 				vscode.window.showErrorMessage(
 					`The language server is not able to serve any features. Initialization failed: ${error}. `
 				);
-				serverOutputChannel.show();
-				suggestGoplsIssueReport(`The gopls server failed to initialize.`);
+				suggestGoplsIssueReport(`The gopls server failed to initialize.`, errorKind.initializationFailure);
 				return false;
 			},
 			errorHandler: {
@@ -244,15 +253,21 @@
 					vscode.window.showErrorMessage(
 						`Error communicating with the language server: ${error}: ${message}.`
 					);
-					// Stick with the default number of 5 crashes before shutdown.
-					if (count >= 5) {
-						return ErrorAction.Shutdown;
+					// Allow 5 crashes before shutdown.
+					if (count < 5) {
+						return ErrorAction.Continue;
 					}
-					return ErrorAction.Continue;
+					return ErrorAction.Shutdown;
 				},
 				closed: (): CloseAction => {
-					serverOutputChannel.show();
-					suggestGoplsIssueReport(`The connection to gopls has been closed. The gopls server may have crashed.`);
+					// Allow 5 crashes before shutdown.
+					crashCount++;
+					if (crashCount < 5) {
+						return CloseAction.Restart;
+					}
+					suggestGoplsIssueReport(
+						`The connection to gopls has been closed. The gopls server may have crashed.`,
+						errorKind.crash);
 					return CloseAction.DoNotRestart;
 				},
 			},
@@ -368,6 +383,7 @@
 	);
 	defaultLanguageProviders.push(vscode.languages.registerRenameProvider(GO_MODE, new GoRenameProvider()));
 	defaultLanguageProviders.push(vscode.workspace.onDidChangeTextDocument(parseLiveFile, null, ctx.subscriptions));
+	defaultLanguageProviders.push(vscode.languages.registerCodeActionsProvider(GO_MODE, new GoCodeActionProvider()));
 
 	for (const provider of defaultLanguageProviders) {
 		ctx.subscriptions.push(provider);
@@ -389,7 +405,8 @@
 	if (
 		e.affectsConfiguration('go.useLanguageServer') ||
 		e.affectsConfiguration('go.languageServerFlags') ||
-		e.affectsConfiguration('go.languageServerExperimentalFeatures')
+		e.affectsConfiguration('go.languageServerExperimentalFeatures') ||
+		e.affectsConfiguration('go.alternateTools')
 	) {
 		restartLanguageServer();
 	}
@@ -495,7 +512,6 @@
 	return vscode.workspace.workspaceFolders.find((x) => tempGopath !== getCurrentGoPath(x.uri)) ? false : true;
 }
 
-const acceptGoplsPrerelease = true;  // For nightly, we accept the prerelease version.
 export async function shouldUpdateLanguageServer(
 	tool: Tool,
 	languageServerToolPath: string,
@@ -543,7 +559,10 @@
 
 	// If the user's version does not contain a timestamp,
 	// default to a semver comparison of the two versions.
-	const usersVersionSemver = semver.coerce(usersVersion, { includePrerelease: true, loose: true });
+	const usersVersionSemver = semver.parse(usersVersion, {
+		includePrerelease: true,
+		loose: true,
+	});
 	return semver.lt(usersVersionSemver, latestVersion) ? latestVersion : null;
 }
 
@@ -598,6 +617,8 @@
 	return time;
 };
 
+const acceptGoplsPrerelease = (extensionId === 'golang.go-nightly');
+
 export const getLatestGoplsVersion = async (tool: Tool) => {
 	// If the user has a version of gopls that we understand,
 	// ask the proxy for the latest version, and if the user's version is older,
@@ -696,7 +717,7 @@
 	}
 	// Try each URL set in the user's GOPROXY environment variable.
 	// If none is set, don't make the request.
-	const proxies = output.trim().split(',|');
+	const proxies = output.trim().split(/,|\|/);
 	for (const proxy of proxies) {
 		if (proxy === 'direct') {
 			continue;
@@ -708,6 +729,7 @@
 				throwResponseError: true
 			});
 		} catch (e) {
+			console.log(`Error sending request to ${proxy}: ${e}`);
 			return null;
 		}
 		return data;
@@ -844,40 +866,79 @@
 	updateGlobalState(goplsSurveyConfig, JSON.stringify(cfg));
 }
 
+// errorKind refers to the different possible kinds of gopls errors.
+enum errorKind {
+	initializationFailure,
+	crash,
+	manualRestart,
+}
+
 // suggestGoplsIssueReport prompts users to file an issue with gopls.
-async function suggestGoplsIssueReport(msg: string) {
+async function suggestGoplsIssueReport(msg: string, reason: errorKind) {
+	// Don't prompt users who manually restart to file issues until gopls/v1.0.
+	if (reason === errorKind.manualRestart) {
+		return;
+	}
+
+	// Show the user the output channel content to alert them to the issue.
+	serverOutputChannel.show();
+
 	if (latestConfig.serverName !== 'gopls') {
 		return;
 	}
 	const promptForIssueOnGoplsRestartKey = `promptForIssueOnGoplsRestart`;
 	let saved: any;
 	try {
-		saved = JSON.parse(getFromGlobalState(promptForIssueOnGoplsRestartKey, true));
+		saved = JSON.parse(getFromGlobalState(promptForIssueOnGoplsRestartKey, false));
 	} catch (err) {
 		console.log(`Failed to parse as JSON ${getFromGlobalState(promptForIssueOnGoplsRestartKey, true)}: ${err}`);
 		return;
 	}
 	// If the user has already seen this prompt, they may have opted-out for
 	// the future. Only prompt again if it's been more than a year since.
-	if (saved['date'] && saved['prompt']) {
+	if (saved) {
 		const dateSaved = new Date(saved['date']);
 		const prompt = <boolean>saved['prompt'];
 		if (!prompt && daysBetween(new Date(), dateSaved) <= 365) {
 			return;
 		}
 	}
-	const selected = await vscode.window.showInformationMessage(`${msg} Would you like to report a gopls issue ? `, 'Yes', 'Next time', 'Never');
+	const selected = await vscode.window.showInformationMessage(`${msg} Would you like to report a gopls issue on GitHub?
+You will be asked to provide additional information and logs, so PLEASE READ THE CONTENT IN YOUR BROWSER.`, 'Yes', 'Next time', 'Never');
 	switch (selected) {
 		case 'Yes':
-			// Run the `gopls bug` command directly for now. When
-			// https://github.com/golang/go/issues/38942 is
-			// resolved, we'll be able to do this through the
-			// language client.
+			// Prefill an issue title and report.
+			let errKind: string;
+			switch (reason) {
+				case errorKind.crash:
+					errKind = 'crash';
+					break;
+				case errorKind.initializationFailure:
+					errKind = 'initialization';
+					break;
+			}
+			const title = `gopls: automated issue report (${errKind})`;
+			const body = `ATTENTION: PLEASE PROVIDE THE DETAILS REQUESTED BELOW.
 
-			// Wait for the command to finish before restarting the
-			// server, but don't bother handling errors.
-			const execFile = util.promisify(cp.execFile);
-			await execFile(latestConfig.path, ['bug'], { env: toolExecutionEnvironment() });
+Describe what you observed.
+
+<ANSWER HERE>
+
+Please attach the stack trace from the crash.
+A window with the error message should have popped up in the lower half of your screen.
+Please copy the stack trace from that window and paste it in this issue.
+
+<PASTE STACK TRACE HERE>
+
+OPTIONAL: If you would like to share more information, you can attach your complete gopls logs.
+
+NOTE: THESE MAY CONTAIN SENSITIVE INFORMATION ABOUT YOUR CODEBASE.
+DO NOT SHARE LOGS IF YOU ARE WORKING IN A PRIVATE REPOSITORY.
+
+<OPTIONAL: ATTACH LOGS HERE>
+`;
+			const url = `https://github.com/golang/vscode-go/issues/new?title=${title}&labels=upstream-tools&body=${body}`;
+			await vscode.env.openExternal(vscode.Uri.parse(url));
 			break;
 		case 'Next time':
 			break;
diff --git a/src/goMain.ts b/src/goMain.ts
index 7bcf799..e25a862 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -8,10 +8,10 @@
 
 import * as path from 'path';
 import vscode = require('vscode');
+import { GoDlvDapDebugSession } from './debugAdapter2/goDlvDebug';
 import { browsePackages } from './goBrowsePackage';
 import { buildCode } from './goBuild';
 import { check, notifyIfGeneratedFile, removeTestStatus } from './goCheck';
-import { GoCodeActionProvider } from './goCodeAction';
 import {
 	applyCodeCoverage, applyCodeCoverageToAllEditors, initCoverageDecorators, removeCodeCoverageOnFileSave,
 	toggleCoverageCurrentPackage, trackCodeCoverageRemovalOnFileChange, updateCodeCoverageDecorators
@@ -19,6 +19,7 @@
 import { GoDebugConfigurationProvider } from './goDebugConfiguration';
 import { extractFunction, extractVariable } from './goDoctor';
 import { toolExecutionEnvironment } from './goEnv';
+import { chooseGoEnvironment } from './goEnvironmentStatus';
 import { runFillStruct } from './goFillStruct';
 import * as goGenerateTests from './goGenerateTests';
 import { goGetPackage } from './goGetPackage';
@@ -34,7 +35,7 @@
 import { GO_MODE } from './goMode';
 import { addTags, removeTags } from './goModifytags';
 import { GO111MODULE, isModSupported } from './goModules';
-import { clearCacheForTools, fileExists } from './goPath';
+import { clearCacheForTools, fileExists, getCurrentGoRoot, setCurrentGoRoot } from './goPath';
 import { playgroundCommand } from './goPlayground';
 import { GoReferencesCodeLensProvider } from './goReferencesCodelens';
 import { GoRunTestCodeLensProvider } from './goRunTestCodelens';
@@ -48,8 +49,16 @@
 } from './stateUtils';
 import { cancelRunningTests, showTestOutput } from './testUtils';
 import {
-	cleanupTempDir, getBinPath, getCurrentGoPath, getExtensionCommands, getGoConfig,
-	getGoVersion, getToolsGopath, getWorkspaceFolderPath, handleDiagnosticErrors, isGoPathSet
+	cleanupTempDir,
+	getBinPath,
+	getCurrentGoPath,
+	getExtensionCommands,
+	getGoConfig,
+	getGoVersion,
+	getToolsGopath,
+	getWorkspaceFolderPath,
+	handleDiagnosticErrors,
+	isGoPathSet
 } from './util';
 
 export let buildDiagnosticCollection: vscode.DiagnosticCollection;
@@ -64,6 +73,10 @@
 export function activate(ctx: vscode.ExtensionContext): void {
 	setGlobalState(ctx.globalState);
 	setWorkspaceState(ctx.workspaceState);
+	const configGOROOT = getGoConfig()['goroot'];
+	if (!!configGOROOT) {
+		setCurrentGoRoot(configGOROOT);
+	}
 
 	updateGoVarsFromConfig().then(async () => {
 		const updateToolsCmdText = 'Update tools';
@@ -77,7 +90,7 @@
 			toolsGoInfo[toolsGopath] = { goroot: null, version: null };
 		}
 		const prevGoroot = toolsGoInfo[toolsGopath].goroot;
-		const currentGoroot: string = process.env['GOROOT'] && process.env['GOROOT'].toLowerCase();
+		const currentGoroot: string = getCurrentGoRoot().toLowerCase();
 		if (prevGoroot && prevGoroot.toLowerCase() !== currentGoroot) {
 			// Don't suggest recompiling tools for the go2go version.
 			if (false) {
@@ -101,7 +114,7 @@
 					if (prevVersion) {
 						vscode.window
 							.showInformationMessage(
-								'Your Go version is different than before, few Go tools may need re-compiling',
+								'Your Go version is different than before, a few Go tools may need re-compiling',
 								updateToolsCmdText
 							)
 							.then((selected) => {
@@ -157,15 +170,22 @@
 			);
 		})
 	);
-	showHideStatus(vscode.window.activeTextEditor);
-
 	const testCodeLensProvider = new GoRunTestCodeLensProvider();
 	const referencesCodeLensProvider = new GoReferencesCodeLensProvider();
 
-	ctx.subscriptions.push(vscode.languages.registerCodeActionsProvider(GO_MODE, new GoCodeActionProvider()));
 	ctx.subscriptions.push(vscode.languages.registerCodeLensProvider(GO_MODE, testCodeLensProvider));
 	ctx.subscriptions.push(vscode.languages.registerCodeLensProvider(GO_MODE, referencesCodeLensProvider));
 	ctx.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('go', new GoDebugConfigurationProvider()));
+	ctx.subscriptions.push(
+		vscode.debug.registerDebugConfigurationProvider('godlvdap', new GoDebugConfigurationProvider()));
+
+	// Use an InlineDebugAdapterFactory to create a new debug adapter for
+	// the 'godlvdap' command in inline mode, without launching a subprocess.
+	const factory = new InlineDebugAdapterFactory();
+	ctx.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory('godlvdap', factory));
+	if ('dispose' in factory) {
+		ctx.subscriptions.push(factory);
+	}
 
 	buildDiagnosticCollection = vscode.languages.createDiagnosticCollection('go');
 	ctx.subscriptions.push(buildDiagnosticCollection);
@@ -214,7 +234,7 @@
 			outputChannel.appendLine('GOBIN: ' + process.env['GOBIN']);
 			outputChannel.appendLine('toolsGopath: ' + getToolsGopath());
 			outputChannel.appendLine('gopath: ' + getCurrentGoPath());
-			outputChannel.appendLine('GOROOT: ' + process.env['GOROOT']);
+			outputChannel.appendLine('GOROOT: ' + getCurrentGoRoot());
 			outputChannel.appendLine('PATH: ' + process.env['PATH']);
 			outputChannel.appendLine('');
 
@@ -285,6 +305,10 @@
 
 	ctx.subscriptions.push(
 		vscode.commands.registerCommand('go.debug.cursor', (args) => {
+			if (vscode.debug.activeDebugSession) {
+				vscode.window.showErrorMessage('Debug session has already been started.');
+				return;
+			}
 			const goConfig = getGoConfig();
 			testAtCursor(goConfig, 'debug', args);
 		})
@@ -395,8 +419,14 @@
 				return;
 			}
 			const updatedGoConfig = getGoConfig();
-			updateGoVarsFromConfig();
 
+			if (e.affectsConfiguration('go.goroot') ||
+				e.affectsConfiguration('go.alternateTools') ||
+				e.affectsConfiguration('go.gopath') ||
+				e.affectsConfiguration('go.toolsEnvVars') ||
+				e.affectsConfiguration('go.testEnvFile')) {
+				updateGoVarsFromConfig();
+			}
 			// If there was a change in "toolsGopath" setting, then clear cache for go tools
 			if (getToolsGopath() !== getToolsGopath(false)) {
 				clearCacheForTools();
@@ -542,13 +572,19 @@
 						updateWorkspaceState(lastCoverProfilePathKey, coverProfilePath);
 					}
 					applyCodeCoverageToAllEditors(
-						coverProfilePath,
-						path.dirname(vscode.window.activeTextEditor.document.fileName)
+						coverProfilePath
 					);
 				});
 		})
 	);
 
+	// Go Enviornment switching commands
+	ctx.subscriptions.push(
+		vscode.commands.registerCommand('go.environment.choose', () => {
+			chooseGoEnvironment();
+		})
+	);
+
 	vscode.languages.setLanguageConfiguration(GO_MODE.language, {
 		wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
 	});
@@ -626,3 +662,10 @@
 		promptForMissingTool(tool);
 	}
 }
+
+class InlineDebugAdapterFactory implements vscode.DebugAdapterDescriptorFactory {
+	public createDebugAdapterDescriptor(session: vscode.DebugSession
+	): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
+		return new vscode.DebugAdapterInlineImplementation(new GoDlvDapDebugSession());
+	}
+}
diff --git a/src/goModules.ts b/src/goModules.ts
index 1714066..2a41455 100644
--- a/src/goModules.ts
+++ b/src/goModules.ts
@@ -8,7 +8,7 @@
 import vscode = require('vscode');
 import { toolExecutionEnvironment } from './goEnv';
 import { installTools } from './goInstallTools';
-import { envPath, fixDriveCasingInWindows } from './goPath';
+import { envPath, fixDriveCasingInWindows, getCurrentGoRoot } from './goPath';
 import { getTool } from './goTools';
 import { getFromGlobalState, updateGlobalState } from './stateUtils';
 import { getBinPath, getGoConfig, getGoVersion, getModuleCache } from './util';
@@ -19,7 +19,7 @@
 	const goExecutable = getBinPath('go');
 	if (!goExecutable) {
 		console.warn(
-			`Failed to run "go env GOMOD" to find mod file as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go env GOMOD" to find mod file as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 		);
 		return;
 	}
@@ -80,10 +80,11 @@
 			const promptMsg =
 				'For better performance using Go modules, you can try the experimental Go language server, gopls.';
 			promptToUpdateToolForModules('gopls', promptMsg, goConfig);
-		}
-		if (goConfig['formatTool'] === 'goreturns') {
-			const promptMsgForFormatTool = `The goreturns tool does not support Go modules. Please update the "formatTool" setting to goimports.`;
-			promptToUpdateToolForModules('switchFormatToolToGoimports', promptMsgForFormatTool, goConfig);
+
+			if (goConfig['formatTool'] === 'goreturns') {
+				const promptMsgForFormatTool = `The goreturns tool does not support Go modules. Please update the "formatTool" setting to goimports.`;
+				promptToUpdateToolForModules('switchFormatToolToGoimports', promptMsgForFormatTool, goConfig);
+			}
 		}
 	}
 	packagePathToGoModPathMap[pkgPath] = goModEnvResult;
@@ -161,7 +162,7 @@
 	const goRuntimePath = getBinPath('go');
 	if (!goRuntimePath) {
 		console.warn(
-			`Failed to run "go list" to find current package as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go list" to find current package as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 		);
 		return;
 	}
diff --git a/src/goPackages.ts b/src/goPackages.ts
index 8965435..5c7fce7 100644
--- a/src/goPackages.ts
+++ b/src/goPackages.ts
@@ -8,7 +8,7 @@
 import vscode = require('vscode');
 import { toolExecutionEnvironment } from './goEnv';
 import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
-import { envPath, fixDriveCasingInWindows, getCurrentGoWorkspaceFromGOPATH } from './goPath';
+import { envPath, fixDriveCasingInWindows, getCurrentGoRoot, getCurrentGoWorkspaceFromGOPATH } from './goPath';
 import { getBinPath, getCurrentGoPath, getGoVersion, isVendorSupported } from './util';
 
 type GopkgsDone = (res: Map<string, PackageInfo>) => void;
@@ -72,7 +72,7 @@
 				);
 				return resolve(pkgs);
 			}
-			const goroot = process.env['GOROOT'];
+			const goroot = getCurrentGoRoot();
 			const output = chunks.join('');
 			if (output.indexOf(';') === -1) {
 				// User might be using the old gopkgs tool, prompt to update
@@ -262,7 +262,7 @@
 	const goRuntimePath = getBinPath('go');
 	if (!goRuntimePath) {
 		console.warn(
-			`Failed to run "go list" to find packages as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+			`Failed to run "go list" to find packages as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) PATH(${envPath})`
 		);
 		return;
 	}
diff --git a/src/goPath.ts b/src/goPath.ts
index 2f4402a..c29c572 100644
--- a/src/goPath.ts
+++ b/src/goPath.ts
@@ -12,6 +12,7 @@
 import fs = require('fs');
 import os = require('os');
 import path = require('path');
+import { promisify } from 'util';
 
 let binPathCache: { [bin: string]: string } = {};
 
@@ -31,16 +32,23 @@
 	return null;
 }
 
-export function getBinPathWithPreferredGopath(toolName: string, preferredGopaths: string[], alternateTool?: string) {
-	if (binPathCache[toolName]) {
-		return binPathCache[toolName];
-	}
-
+export function getBinPathWithPreferredGopathGoroot(
+	toolName: string,
+	preferredGopaths: string[],
+	preferredGoroot?: string,
+	alternateTool?: string,
+	useCache = true,
+) {
 	if (alternateTool && path.isAbsolute(alternateTool) && executableFileExists(alternateTool)) {
 		binPathCache[toolName] = alternateTool;
 		return alternateTool;
 	}
 
+	// FIXIT: this cache needs to be invalidated when go.goroot or go.alternateTool is changed.
+	if (useCache && binPathCache[toolName]) {
+		return binPathCache[toolName];
+	}
+
 	const binname = alternateTool && !path.isAbsolute(alternateTool) ? alternateTool : toolName;
 	const pathFromGoBin = getBinPathFromEnvVar(binname, process.env['GOBIN'], false);
 	if (pathFromGoBin) {
@@ -60,7 +68,7 @@
 	}
 
 	// Check GOROOT (go, gofmt, godoc would be found here)
-	const pathFromGoRoot = getBinPathFromEnvVar(binname, process.env['GOROOT'], true);
+	const pathFromGoRoot = getBinPathFromEnvVar(binname, preferredGoroot || getCurrentGoRoot(), true);
 	if (pathFromGoRoot) {
 		binPathCache[toolName] = pathFromGoRoot;
 		return pathFromGoRoot;
@@ -87,6 +95,18 @@
 	return toolName;
 }
 
+/**
+ * Returns the goroot path if it exists, otherwise returns an empty string
+ */
+let currentGoRoot = '';
+export function getCurrentGoRoot(): string {
+	return currentGoRoot || process.env['GOROOT'] || '';
+}
+
+export function setCurrentGoRoot(goroot: string) {
+	currentGoRoot = goroot;
+}
+
 function correctBinname(toolName: string) {
 	if (process.platform === 'win32') {
 		return toolName + '.exe';
@@ -115,6 +135,15 @@
 	}
 }
 
+export async function pathExists(p: string): Promise<boolean> {
+	try {
+		const stat = promisify(fs.stat);
+		return (await stat(p)).isDirectory();
+	} catch (e) {
+		return false;
+	}
+}
+
 export function clearCacheForTools() {
 	binPathCache = {};
 }
diff --git a/src/goRunTestCodelens.ts b/src/goRunTestCodelens.ts
index f53388b..587450a 100644
--- a/src/goRunTestCodelens.ts
+++ b/src/goRunTestCodelens.ts
@@ -10,21 +10,12 @@
 import { GoBaseCodeLensProvider } from './goBaseCodelens';
 import { GoDocumentSymbolProvider } from './goOutline';
 import { getBenchmarkFunctions, getTestFunctions } from './testUtils';
-import { getCurrentGoPath, getGoConfig } from './util';
+import { getGoConfig } from './util';
 
 export class GoRunTestCodeLensProvider extends GoBaseCodeLensProvider {
 	private readonly benchmarkRegex = /^Benchmark.+/;
-	private readonly debugConfig: any = {
-		name: 'Launch',
-		type: 'go',
-		request: 'launch',
-		mode: 'test',
-		env: {
-			GOPATH: getCurrentGoPath() // Passing current GOPATH to Delve as it runs in another process
-		}
-	};
 
-	public provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
+	public async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
 		if (!this.enabled) {
 			return [];
 		}
@@ -35,24 +26,19 @@
 			return [];
 		}
 
-		return Promise.all([
+		const codelenses = await Promise.all([
 			this.getCodeLensForPackage(document, token),
-			this.getCodeLensForFunctions(config, document, token)
-		]).then(([pkg, fns]) => {
-			let res: any[] = [];
-			if (pkg && Array.isArray(pkg)) {
-				res = res.concat(pkg);
-			}
-			if (fns && Array.isArray(fns)) {
-				res = res.concat(fns);
-			}
-			return res;
-		});
+			this.getCodeLensForFunctions(document, token)
+		]);
+		return ([] as CodeLens[]).concat(...codelenses);
 	}
 
 	private async getCodeLensForPackage(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
 		const documentSymbolProvider = new GoDocumentSymbolProvider();
 		const symbols = await documentSymbolProvider.provideDocumentSymbols(document, token);
+		if (!symbols || symbols.length === 0) {
+			return [];
+		}
 		const pkg = symbols[0];
 		if (!pkg) {
 			return [];
@@ -69,7 +55,7 @@
 			})
 		];
 		if (
-			symbols[0].children.some(
+			pkg.children.some(
 				(sym) => sym.kind === vscode.SymbolKind.Function && this.benchmarkRegex.test(sym.name)
 			)
 		) {
@@ -87,54 +73,50 @@
 		return packageCodeLens;
 	}
 
-	private async getCodeLensForFunctions(
-		vsConfig: vscode.WorkspaceConfiguration,
-		document: TextDocument,
-		token: CancellationToken
-	): Promise<CodeLens[]> {
-		const codelens: CodeLens[] = [];
-
-		const testPromise = getTestFunctions(document, token).then((testFunctions) => {
-			testFunctions.forEach((func) => {
-				const runTestCmd: Command = {
+	private async getCodeLensForFunctions(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
+		const testPromise = async (): Promise<CodeLens[]> => {
+			const testFunctions = await getTestFunctions(document, token);
+			if (!testFunctions) {
+				return [];
+			}
+			const codelens: CodeLens[] = [];
+			for (const f of testFunctions) {
+				codelens.push(new CodeLens(f.range, {
 					title: 'run test',
 					command: 'go.test.cursor',
-					arguments: [{ functionName: func.name }]
-				};
-
-				codelens.push(new CodeLens(func.range, runTestCmd));
-
-				const debugTestCmd: Command = {
+					arguments: [{ functionName: f.name }]
+				}));
+				codelens.push(new CodeLens(f.range, {
 					title: 'debug test',
 					command: 'go.debug.cursor',
-					arguments: [{ functionName: func.name }]
-				};
+					arguments: [{ functionName: f.name }]
+				}));
+			}
+			return codelens;
+		};
 
-				codelens.push(new CodeLens(func.range, debugTestCmd));
-			});
-		});
-
-		const benchmarkPromise = getBenchmarkFunctions(document, token).then((benchmarkFunctions) => {
-			benchmarkFunctions.forEach((func) => {
-				const runBenchmarkCmd: Command = {
+		const benchmarkPromise = (async (): Promise<CodeLens[]> => {
+			const benchmarkFunctions = await getBenchmarkFunctions(document, token);
+			if (!benchmarkFunctions) {
+				return [];
+			}
+			const codelens: CodeLens[] = [];
+			for (const f of benchmarkFunctions) {
+				codelens.push(new CodeLens(f.range, {
 					title: 'run benchmark',
 					command: 'go.benchmark.cursor',
-					arguments: [{ functionName: func.name }]
-				};
-
-				codelens.push(new CodeLens(func.range, runBenchmarkCmd));
-
-				const debugTestCmd: Command = {
+					arguments: [{ functionName: f.name }]
+				}));
+				codelens.push(new CodeLens(f.range, {
 					title: 'debug benchmark',
 					command: 'go.debug.cursor',
-					arguments: [{ functionName: func.name }]
-				};
-
-				codelens.push(new CodeLens(func.range, debugTestCmd));
-			});
+					arguments: [{ functionName: f.name }]
+				}));
+			}
+			return codelens;
 		});
 
-		await Promise.all([testPromise, benchmarkPromise]);
-		return codelens;
+		const codelenses = await Promise.all([testPromise(), benchmarkPromise()]);
+		return ([] as CodeLens[]).concat(...codelenses);
 	}
 }
diff --git a/src/goSymbol.ts b/src/goSymbol.ts
index ae8cf8c..b97e018 100644
--- a/src/goSymbol.ts
+++ b/src/goSymbol.ts
@@ -9,6 +9,7 @@
 import vscode = require('vscode');
 import { toolExecutionEnvironment } from './goEnv';
 import { promptForMissingTool, promptForUpdatingTool } from './goInstallTools';
+import { getCurrentGoRoot } from './goPath';
 import { getBinPath, getGoConfig, getWorkspaceFolderPath, killTree } from './util';
 
 // Keep in sync with github.com/acroca/go-symbols'
@@ -93,7 +94,7 @@
 	calls.push(callGoSymbols([...baseArgs, workspacePath, query], token));
 
 	if (gotoSymbolConfig.includeGoroot) {
-		const goRoot = process.env['GOROOT'];
+		const goRoot = getCurrentGoRoot();
 		const gorootCall = callGoSymbols([...baseArgs, goRoot, query], token);
 		calls.push(gorootCall);
 	}
diff --git a/src/goTest.ts b/src/goTest.ts
index a523a6e..b25c78a 100644
--- a/src/goTest.ts
+++ b/src/goTest.ts
@@ -6,7 +6,6 @@
 
 import path = require('path');
 import vscode = require('vscode');
-import { applyCodeCoverageToAllEditors } from './goCover';
 import { isModSupported } from './goModules';
 import {
 	extractInstanceTestName,
@@ -19,7 +18,6 @@
 	goTest,
 	TestConfig
 } from './testUtils';
-import { getTempFilePath } from './util';
 
 // lastTestConfig holds a reference to the last executed TestConfig which allows
 // the last test to be easily re-executed.
diff --git a/src/goTools.ts b/src/goTools.ts
index 99ed0ac..eaa2b87 100644
--- a/src/goTools.ts
+++ b/src/goTools.ts
@@ -176,7 +176,7 @@
 	return tools;
 }
 
-const allToolsInformation: { [key: string]: Tool } = {
+export const allToolsInformation: { [key: string]: Tool } = {
 	'gocode': {
 		name: 'gocode',
 		importPath: 'github.com/mdempsky/gocode',
diff --git a/src/testUtils.ts b/src/testUtils.ts
index d1a97f4..f983e0b 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -12,7 +12,7 @@
 import { getCurrentPackage } from './goModules';
 import { GoDocumentSymbolProvider } from './goOutline';
 import { getNonVendorPackages } from './goPackages';
-import { envPath, getCurrentGoWorkspaceFromGOPATH, parseEnvFile } from './goPath';
+import { envPath, getCurrentGoRoot, getCurrentGoWorkspaceFromGOPATH, parseEnvFile } from './goPath';
 import {
 	getBinPath,
 	getCurrentGoPath,
@@ -262,7 +262,7 @@
 
 		if (!goRuntimePath) {
 			vscode.window.showErrorMessage(
-				`Failed to run "go test" as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})`
+				`Failed to run "go test" as the "go" binary cannot be found in either GOROOT(${getCurrentGoRoot()}) or PATH(${envPath})`
 			);
 			return Promise.resolve();
 		}
@@ -402,7 +402,7 @@
 		);
 	});
 	if (testconfig.applyCodeCoverage) {
-		await applyCodeCoverageToAllEditors(tmpCoverPath, testconfig.dir);
+		await applyCodeCoverageToAllEditors(tmpCoverPath);
 	}
 	return testResult;
 }
@@ -464,7 +464,7 @@
 			// which will result in the correct thing to happen
 			if (testFunctions.length > 0) {
 				if (testFunctions.length === 1) {
-					params = params.concat(['-run', util.format('^%s$', testFunctions.pop())]);
+					params = params.concat(['-run', util.format('^%s$', testFunctions[0])]);
 				} else {
 					params = params.concat(['-run', util.format('^(%s)$', testFunctions.join('|'))]);
 				}
diff --git a/src/util.ts b/src/util.ts
index 0561001..ec2e6df 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -12,18 +12,19 @@
 import util = require('util');
 import vscode = require('vscode');
 import { NearestNeighborDict, Node } from './avlTree';
+import { extensionId } from './const';
 import { toolExecutionEnvironment } from './goEnv';
 import { buildDiagnosticCollection, lintDiagnosticCollection, vetDiagnosticCollection } from './goMain';
 import { getCurrentPackage } from './goModules';
 import {
 	envPath,
 	fixDriveCasingInWindows,
-	getBinPathWithPreferredGopath,
+	getBinPathWithPreferredGopathGoroot,
+	getCurrentGoRoot,
 	getInferredGopath,
-	resolveHomeDir
+	resolveHomeDir,
 } from './goPath';
 import { outputChannel } from './goStatus';
-import { extensionId } from './telemetry';
 
 let userNameHash: number = 0;
 
@@ -135,11 +136,13 @@
 	}
 }
 
+let cachedGoBinPath: string | undefined;
 let cachedGoVersion: GoVersion | undefined;
 let vendorSupport: boolean | undefined;
 let toolsGopath: string;
 
-export function getGoConfig(uri?: vscode.Uri): vscode.WorkspaceConfiguration {
+// getGoConfig is declared as an exported const rather than a function, so it can be stubbbed in testing.
+export const getGoConfig = (uri?: vscode.Uri) => {
 	if (!uri) {
 		if (vscode.window.activeTextEditor) {
 			uri = vscode.window.activeTextEditor.document.uri;
@@ -148,7 +151,7 @@
 		}
 	}
 	return vscode.workspace.getConfiguration('go', uri);
-}
+};
 
 export function byteOffsetAt(document: vscode.TextDocument, position: vscode.Position): number {
 	const offset = document.offsetAt(position);
@@ -307,10 +310,10 @@
 	};
 
 	if (!goRuntimePath) {
-		warn(`unable to locate "go" binary in GOROOT (${process.env['GOROOT']}) or PATH (${envPath})`);
+		warn(`unable to locate "go" binary in GOROOT (${getCurrentGoRoot()}) or PATH (${envPath})`);
 		return;
 	}
-	if (cachedGoVersion) {
+	if (cachedGoBinPath === goRuntimePath && cachedGoVersion) {
 		if (cachedGoVersion.isValid()) {
 			return Promise.resolve(cachedGoVersion);
 		}
@@ -323,6 +326,7 @@
 			warn(`failed to run "${goRuntimePath} version": stdout: ${stdout}, stderr: ${stderr}`);
 			return;
 		}
+		cachedGoBinPath = goRuntimePath;
 		cachedGoVersion = new GoVersion(goRuntimePath, stdout);
 	} catch (err) {
 		warn(`failed to run "${goRuntimePath} version": ${err}`);
@@ -431,14 +435,17 @@
 	}
 }
 
-export function getBinPath(tool: string): string {
-	const alternateTools: { [key: string]: string } = getGoConfig().get('alternateTools');
+export function getBinPath(tool: string, useCache = true): string {
+	const cfg = getGoConfig();
+	const alternateTools: { [key: string]: string } = cfg.get('alternateTools');
 	const alternateToolPath: string = alternateTools[tool];
 
-	return getBinPathWithPreferredGopath(
+	return getBinPathWithPreferredGopathGoroot(
 		tool,
 		tool === 'go' ? [] : [getToolsGopath(), getCurrentGoPath()],
-		resolvePath(alternateToolPath)
+		tool === 'go' && cfg.get('goroot') ? cfg.get('goroot') : undefined,
+		resolvePath(alternateToolPath),
+		useCache
 	);
 }
 
@@ -485,6 +492,9 @@
 }
 
 export function getModuleCache(): string {
+	if (process.env['GOMODCACHE']) {
+		return process.env['GOMODCACHE'];
+	}
 	if (currentGopath) {
 		return path.join(currentGopath.split(path.delimiter)[0], 'pkg', 'mod');
 	}
diff --git a/test/fixtures/codelens/codelens_benchmark_test.go b/test/fixtures/codelens/codelens_benchmark_test.go
new file mode 100644
index 0000000..ecd6ed6
--- /dev/null
+++ b/test/fixtures/codelens/codelens_benchmark_test.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+	"testing"
+)
+
+func BenchmarkSample(b *testing.B) {
+	b.Run("sample test passing", func(t *testing.B) {
+
+	})
+
+	b.Run("sample test failing", func(t *testing.B) {
+		t.FailNow()
+	})
+
+	testName := "dynamic test name"
+	b.Run(testName, func(t *testing.B) {
+		t.FailNow()
+	})
+}
diff --git a/test/fixtures/subtests/subtests_test.go b/test/fixtures/codelens/codelens_test.go
similarity index 100%
rename from test/fixtures/subtests/subtests_test.go
rename to test/fixtures/codelens/codelens_test.go
diff --git a/test/fixtures/subtests/go.mod b/test/fixtures/codelens/go.mod
similarity index 100%
rename from test/fixtures/subtests/go.mod
rename to test/fixtures/codelens/go.mod
diff --git a/test/fixtures/coverage/a/a.go b/test/fixtures/coverage/a/a.go
new file mode 100644
index 0000000..06eae93
--- /dev/null
+++ b/test/fixtures/coverage/a/a.go
@@ -0,0 +1,7 @@
+package a
+
+func main() {
+	x := 12
+	y := x + 17
+	panic(y)
+}
diff --git a/test/fixtures/coverage/b/b.go b/test/fixtures/coverage/b/b.go
new file mode 100644
index 0000000..7de3bb6
--- /dev/null
+++ b/test/fixtures/coverage/b/b.go
@@ -0,0 +1,11 @@
+package b
+
+import (
+	"fmt"
+	"os"
+)
+
+func main() {
+	v := os.Env()
+	fmt.Print(v)
+}
diff --git a/test/fixtures/coverage/cover.out b/test/fixtures/coverage/cover.out
new file mode 100644
index 0000000..3157dc6
--- /dev/null
+++ b/test/fixtures/coverage/cover.out
@@ -0,0 +1,3 @@
+mode: set
+github.com/microsoft/vscode-go/gofixtures/coveragetest/a/a.go:19.71,22.25 3 1
+github.com/microsoft/vscode-go/gofixtures/coveragetest/b/b.go:35.2,35.14 1 1
diff --git a/test/fixtures/coverage/go.mod b/test/fixtures/coverage/go.mod
new file mode 100644
index 0000000..5f77dbf
--- /dev/null
+++ b/test/fixtures/coverage/go.mod
@@ -0,0 +1,3 @@
+module github.com/microsoft/vscode-go/gofixtures/coveragetest
+
+go 1.14
diff --git a/test/fixtures/testhelpers/fakego.go b/test/fixtures/testhelpers/fakego.go
new file mode 100644
index 0000000..8116833
--- /dev/null
+++ b/test/fixtures/testhelpers/fakego.go
@@ -0,0 +1,47 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Licensed under the MIT License.
+// See LICENSE in the project root for license information.
+
+// This is a helper used to fake a go binary.
+// It currently fakes `go env` and `go version` commands.
+// For `go env`, it returns FAKEGOROOT for 'GOROOT', and an empty string for others.
+// For `go version`, it returns FAKEGOVERSION or a default dev version string.
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+func main() {
+	args := os.Args
+
+	if len(args) <= 1 {
+		return
+	}
+	switch args[1] {
+	case "env":
+		fakeEnv(args[2:])
+	case "version":
+		fakeVersion()
+	default:
+		fmt.Fprintf(os.Stderr, "not implemented")
+		os.Exit(1)
+	}
+	os.Exit(0)
+}
+
+func fakeEnv(args []string) {
+	for _, a := range args {
+		fmt.Println(os.Getenv("FAKE" + a))
+	}
+}
+
+func fakeVersion() {
+	ver := os.Getenv("FAKEGOVERSION")
+	if ver != "" {
+		fmt.Println(ver)
+		return
+	}
+	fmt.Println("go version devel +a07e2819 Thu Jun 18 20:58:26 2020 +0000 darwin/amd64")
+}
diff --git a/test/gopls/extension.test.ts b/test/gopls/extension.test.ts
index 3068a3b..64cddfc 100644
--- a/test/gopls/extension.test.ts
+++ b/test/gopls/extension.test.ts
@@ -7,7 +7,7 @@
 import * as fs from 'fs-extra';
 import * as path from 'path';
 import * as vscode from 'vscode';
-import { extensionId } from '../../src/telemetry';
+import { extensionId } from '../../src/const';
 
 // Env is a collection of test related variables
 // that define the test environment such as vscode workspace.
diff --git a/test/gopls/index.ts b/test/gopls/index.ts
index be16d86..eae81d7 100644
--- a/test/gopls/index.ts
+++ b/test/gopls/index.ts
@@ -10,7 +10,9 @@
 	const mocha = new Mocha({
 		ui: 'tdd'
 	});
-	mocha.useColors(true);
+
+	// @types/mocha is outdated
+	(mocha as any).color(true);
 
 	const testsRoot = path.resolve(__dirname, '..');
 
diff --git a/test/gopls/update.test.ts b/test/gopls/update.test.ts
index dbe5312..bac3aaf 100644
--- a/test/gopls/update.test.ts
+++ b/test/gopls/update.test.ts
@@ -14,7 +14,7 @@
 	test('prompt for update', async () => {
 		const tool = getTool('gopls');
 
-		const toSemver = (v: string) => semver.coerce(v, {includePrerelease: true, loose: true});
+		const toSemver = (v: string) => semver.parse(v, { includePrerelease: true, loose: true });
 
 		// Fake data stubbed functions will serve.
 		const latestVersion = toSemver('0.4.1');
diff --git a/test/integration/codelens.test.ts b/test/integration/codelens.test.ts
new file mode 100644
index 0000000..f28d81d
--- /dev/null
+++ b/test/integration/codelens.test.ts
@@ -0,0 +1,133 @@
+/*---------------------------------------------------------
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+'use strict';
+
+import * as assert from 'assert';
+import fs = require('fs-extra');
+import path = require('path');
+import sinon = require('sinon');
+import vscode = require('vscode');
+import { updateGoVarsFromConfig } from '../../src/goInstallTools';
+import { GoRunTestCodeLensProvider } from '../../src/goRunTestCodelens';
+import { subTestAtCursor } from '../../src/goTest';
+import { getCurrentGoPath } from '../../src/util';
+
+suite('Code lenses for testing and benchmarking', function () {
+	this.timeout(20000);
+
+	let gopath: string;
+	let repoPath: string;
+	let fixturePath: string;
+	let fixtureSourcePath: string;
+
+	let goConfig: vscode.WorkspaceConfiguration;
+	let document: vscode.TextDocument;
+
+	const cancellationTokenSource = new vscode.CancellationTokenSource();
+	const codeLensProvider = new GoRunTestCodeLensProvider();
+
+	suiteSetup(async () => {
+		await updateGoVarsFromConfig();
+
+		gopath = getCurrentGoPath();
+		if (!gopath) {
+			assert.fail('Cannot run tests without a configured GOPATH');
+		}
+		console.log(`Using GOPATH: ${gopath}`);
+
+		// Set up the test fixtures.
+		repoPath = path.join(gopath, 'src', 'test');
+		fixturePath = path.join(repoPath, 'testfixture');
+		fixtureSourcePath = path.join(__dirname, '..', '..', '..', 'test', 'fixtures', 'codelens');
+
+		fs.removeSync(repoPath);
+		fs.copySync(fixtureSourcePath, fixturePath, {
+			recursive: true,
+			// All of the tests run in GOPATH mode for now.
+			// TODO(rstambler): Run tests in GOPATH and module mode.
+			filter: (src: string): boolean => {
+				if (path.basename(src) === 'go.mod') {
+					return false;
+				}
+				return true;
+			},
+		});
+		goConfig = vscode.workspace.getConfiguration('go');
+		const uri = vscode.Uri.file(path.join(fixturePath, 'codelens_test.go'));
+		document = await vscode.workspace.openTextDocument(uri);
+	});
+
+	suiteTeardown(() => {
+		fs.removeSync(repoPath);
+	});
+
+	teardown(() => {
+		sinon.restore();
+	});
+
+	test('Subtests - runs a test with cursor on t.Run line', async () => {
+		const editor = await vscode.window.showTextDocument(document);
+		editor.selection = new vscode.Selection(7, 4, 7, 4);
+		const result = await subTestAtCursor(goConfig, []);
+		assert.equal(result, true);
+	});
+
+	test('Subtests - runs a test with cursor within t.Run function', async () => {
+		const editor = await vscode.window.showTextDocument(document);
+		editor.selection = new vscode.Selection(8, 4, 8, 4);
+		const result = await subTestAtCursor(goConfig, []);
+		assert.equal(result, true);
+	});
+
+	test('Subtests - returns false for a failing test', async () => {
+		const editor = await vscode.window.showTextDocument(document);
+		editor.selection = new vscode.Selection(11, 4, 11, 4);
+		const result = await subTestAtCursor(goConfig, []);
+		assert.equal(result, false);
+	});
+
+	test('Subtests - does nothing for a dynamically defined subtest', async () => {
+		const editor = await vscode.window.showTextDocument(document);
+		editor.selection = new vscode.Selection(17, 4, 17, 4);
+		const result = await subTestAtCursor(goConfig, []);
+		assert.equal(result, undefined);
+	});
+
+	test('Subtests - does nothing when cursor outside of a test function', async () => {
+		const editor = await vscode.window.showTextDocument(document);
+		editor.selection = new vscode.Selection(5, 0, 5, 0);
+		const result = await subTestAtCursor(goConfig, []);
+		assert.equal(result, undefined);
+	});
+
+	test('Subtests - does nothing when no test function covers the cursor and a function name is passed in', async () => {
+		const editor = await vscode.window.showTextDocument(document);
+		editor.selection = new vscode.Selection(5, 0, 5, 0);
+		const result = await subTestAtCursor(goConfig, { functionName: 'TestMyFunction' });
+		assert.equal(result, undefined);
+	});
+
+	test('Test codelenses', async () => {
+		const codeLenses = await codeLensProvider.provideCodeLenses(document, cancellationTokenSource.token);
+		assert.equal(codeLenses.length, 4);
+		const wantCommands = ['go.test.package', 'go.test.file', 'go.test.cursor', 'go.debug.cursor'];
+		for (let i = 0; i < codeLenses.length; i++) {
+			assert.equal(codeLenses[i].command.command, wantCommands[i]);
+		}
+	});
+
+	test('Benchmark codelenses', async () => {
+		const uri = vscode.Uri.file(path.join(fixturePath, 'codelens_benchmark_test.go'));
+		const benchmarkDocument = await vscode.workspace.openTextDocument(uri);
+		const codeLenses = await codeLensProvider.provideCodeLenses(benchmarkDocument, cancellationTokenSource.token);
+		assert.equal(codeLenses.length, 6);
+		const wantCommands = ['go.test.package', 'go.test.file', 'go.benchmark.package',
+			'go.benchmark.file', 'go.benchmark.cursor', 'go.debug.cursor'];
+		for (let i = 0; i < codeLenses.length; i++) {
+			assert.equal(codeLenses[i].command.command, wantCommands[i]);
+		}
+	});
+});
diff --git a/test/integration/coverage.test.ts b/test/integration/coverage.test.ts
new file mode 100644
index 0000000..10e37d2
--- /dev/null
+++ b/test/integration/coverage.test.ts
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------
+ * Copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+'use strict';
+
+import * as assert from 'assert';
+import fs = require('fs-extra');
+import path = require('path');
+import sinon = require('sinon');
+import vscode = require('vscode');
+import { applyCodeCoverageToAllEditors, coverageFilesForTest, initForTest } from '../../src/goCover';
+import { updateGoVarsFromConfig } from '../../src/goInstallTools';
+import { getCurrentGoPath, getWorkspaceFolderPath } from '../../src/util';
+
+// The ideal test would check that each open editor containing a file with coverage
+// information is displayed correctly. We cannot see the applied decorations, so the
+// test checks that the cover.out file has been read correctly, and the import paths
+// have been correctly converted to file system paths, which are what vscode uses.
+suite('Coverage for tests', function () {
+	this.timeout(10000);
+
+	let fixtureSourcePath: string;
+	let coverFilePath: string;
+
+	suiteSetup(async () => {
+		await updateGoVarsFromConfig();
+
+		// Set up the test fixtures.
+		fixtureSourcePath = path.join(__dirname, '..', '..', '..', 'test', 'fixtures', 'coverage');
+		coverFilePath = path.join(fixtureSourcePath, 'cover.out');
+		return;
+	});
+	test('resolve import paths', async () => {
+		initForTest();
+		const x = vscode.workspace.openTextDocument(coverFilePath);
+		await applyCodeCoverageToAllEditors(coverFilePath, fixtureSourcePath);
+		let aDotGo: boolean;
+		let bDotGo: boolean;
+		for (const fn in coverageFilesForTest()) {
+			if (true) { // TSLint insists the body for for..in.. be an if-statement
+				if (fn === `${fixtureSourcePath}/a/a.go`) { aDotGo = true; }
+				if (fn === `${fixtureSourcePath}/b/b.go`) { bDotGo = true; }
+		}
+	}
+		assert.equal(aDotGo && bDotGo, true);
+	});
+});
diff --git a/test/integration/extension.test.ts b/test/integration/extension.test.ts
index 1299a92..b8c752d 100644
--- a/test/integration/extension.test.ts
+++ b/test/integration/extension.test.ts
@@ -28,12 +28,11 @@
 import { GoSignatureHelpProvider } from '../../src/goSignature';
 import { GoCompletionItemProvider } from '../../src/goSuggest';
 import { getWorkspaceSymbols } from '../../src/goSymbol';
-import { subTestAtCursor, testCurrentFile } from '../../src/goTest';
+import { testCurrentFile } from '../../src/goTest';
 import {
 	getBinPath,
 	getCurrentGoPath,
 	getGoConfig,
-	getGoVersion,
 	getImportPath,
 	getToolsGopath,
 	ICheckResult,
@@ -113,10 +112,6 @@
 			path.join(fixtureSourcePath, 'diffTestData', 'file2.go'),
 			path.join(fixturePath, 'diffTest2Data', 'file2.go')
 		);
-		fs.copySync(
-			path.join(fixtureSourcePath, 'subtests', 'subtests_test.go'),
-			path.join(fixturePath, 'subtests', 'subtests_test.go')
-		);
 	});
 
 	suiteTeardown(() => {
@@ -1542,76 +1537,4 @@
 		await runFillStruct(editor);
 		assert.equal(vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.getText(), golden);
 	});
-
-	test('Subtests - runs a test with cursor on t.Run line', async () => {
-		const config = vscode.workspace.getConfiguration('go');
-		const uri = vscode.Uri.file(path.join(fixturePath, 'subtests', 'subtests_test.go'));
-		const document = await vscode.workspace.openTextDocument(uri);
-		const editor = await vscode.window.showTextDocument(document);
-		const selection = new vscode.Selection(7, 4, 7, 4);
-		editor.selection = selection;
-
-		const result = await subTestAtCursor(config, []);
-		assert.equal(result, true);
-	});
-
-	test('Subtests - runs a test with cursor within t.Run function', async () => {
-		const config = vscode.workspace.getConfiguration('go');
-		const uri = vscode.Uri.file(path.join(fixturePath, 'subtests', 'subtests_test.go'));
-		const document = await vscode.workspace.openTextDocument(uri);
-		const editor = await vscode.window.showTextDocument(document);
-		const selection = new vscode.Selection(8, 4, 8, 4);
-		editor.selection = selection;
-
-		const result = await subTestAtCursor(config, []);
-		assert.equal(result, true);
-	});
-
-	test('Subtests - returns false for a failing test', async () => {
-		const config = vscode.workspace.getConfiguration('go');
-		const uri = vscode.Uri.file(path.join(fixturePath, 'subtests', 'subtests_test.go'));
-		const document = await vscode.workspace.openTextDocument(uri);
-		const editor = await vscode.window.showTextDocument(document);
-		const selection = new vscode.Selection(11, 4, 11, 4);
-		editor.selection = selection;
-
-		const result = await subTestAtCursor(config, []);
-		assert.equal(result, false);
-	});
-
-	test('Subtests - does nothing for a dynamically defined subtest', async () => {
-		const config = vscode.workspace.getConfiguration('go');
-		const uri = vscode.Uri.file(path.join(fixturePath, 'subtests', 'subtests_test.go'));
-		const document = await vscode.workspace.openTextDocument(uri);
-		const editor = await vscode.window.showTextDocument(document);
-		const selection = new vscode.Selection(17, 4, 17, 4);
-		editor.selection = selection;
-
-		const result = await subTestAtCursor(config, []);
-		assert.equal(result, undefined);
-	});
-
-	test('Subtests - does nothing when cursor outside of a test function', async () => {
-		const config = vscode.workspace.getConfiguration('go');
-		const uri = vscode.Uri.file(path.join(fixturePath, 'subtests', 'subtests_test.go'));
-		const document = await vscode.workspace.openTextDocument(uri);
-		const editor = await vscode.window.showTextDocument(document);
-		const selection = new vscode.Selection(5, 0, 5, 0);
-		editor.selection = selection;
-
-		const result = await subTestAtCursor(config, []);
-		assert.equal(result, undefined);
-	});
-
-	test('Subtests - does nothing when no test function covers the cursor and a function name is passed in', async () => {
-		const config = vscode.workspace.getConfiguration('go');
-		const uri = vscode.Uri.file(path.join(fixturePath, 'subtests', 'subtests_test.go'));
-		const document = await vscode.workspace.openTextDocument(uri);
-		const editor = await vscode.window.showTextDocument(document);
-		const selection = new vscode.Selection(5, 0, 5, 0);
-		editor.selection = selection;
-
-		const result = await subTestAtCursor(config, {functionName: 'TestMyFunction'});
-		assert.equal(result, undefined);
-	});
 });
diff --git a/test/integration/goDebug.test.ts b/test/integration/goDebug.test.ts
index 23a9afa..618087f 100644
--- a/test/integration/goDebug.test.ts
+++ b/test/integration/goDebug.test.ts
@@ -3,8 +3,11 @@
 import * as path from 'path';
 import * as sinon from 'sinon';
 import {
-	Delve, escapeGoModPath, GoDebugSession,
-	PackageBuildInfo, RemoteSourcesAndPackages
+	Delve,
+	escapeGoModPath,
+	GoDebugSession,
+	PackageBuildInfo,
+	RemoteSourcesAndPackages,
 } from '../../src/debugAdapter/goDebug';
 
 suite('Path Manipulation Tests', () => {
@@ -13,19 +16,17 @@
 	});
 });
 
-suite('GoDebugSession Tests', () => {
+suite('GoDebugSession Tests', async () => {
 	const workspaceFolder = '/usr/workspacefolder';
 	const delve: Delve = {} as Delve;
 	let goDebugSession: GoDebugSession;
 	let remoteSourcesAndPackages: RemoteSourcesAndPackages;
 	let fileSystem: typeof fs;
 
-	let previousGoPath: string;
-	let previousGoRoot: string;
+	let previousEnv: any;
 
 	setup(() => {
-		previousGoPath = process.env.GOPATH;
-		previousGoRoot = process.env.GOROOT;
+		previousEnv = Object.assign({}, process.env);
 
 		process.env.GOPATH = '/usr/gopath';
 		process.env.GOROOT = '/usr/goroot';
@@ -39,8 +40,7 @@
 	});
 
 	teardown(() => {
-		process.env.GOPATH = previousGoPath;
-		process.env.GOROOT = previousGoRoot;
+		process.env = previousEnv;
 		sinon.restore();
 	});
 
diff --git a/test/integration/index.ts b/test/integration/index.ts
index 12e0292..0cc6ddd 100644
--- a/test/integration/index.ts
+++ b/test/integration/index.ts
@@ -6,11 +6,12 @@
 import * as Mocha from 'mocha';
 import * as path from 'path';
 export function run(): Promise<void> {
-	// Create the mocha test
 	const mocha = new Mocha({
 		ui: 'tdd',
 	});
-	mocha.useColors(true);
+
+	// @types/mocha is outdated
+	(mocha as any).color(true);
 
 	const testsRoot = path.resolve(__dirname, '..');
 
diff --git a/test/integration/install.test.ts b/test/integration/install.test.ts
index f2de7f7..2c663f5 100644
--- a/test/integration/install.test.ts
+++ b/test/integration/install.test.ts
@@ -12,31 +12,55 @@
 import sinon = require('sinon');
 import util = require('util');
 import vscode = require('vscode');
+import { toolInstallationEnvironment } from '../../src/goEnv';
 import { installTools } from '../../src/goInstallTools';
-import { getTool, getToolAtVersion } from '../../src/goTools';
+import { allToolsInformation, getTool, getToolAtVersion } from '../../src/goTools';
 import { getBinPath, getGoVersion, rmdirRecursive } from '../../src/util';
 
 suite('Installation Tests', function () {
-	this.timeout(10000);
+	// Disable timeout when we are running slow tests.
+	let timeout = 10000;
+	if (shouldRunSlowTests()) {
+		timeout = 0;
+	}
+	this.timeout(timeout);
 
-	test('install tools', async () => {
-		const goVersion = await getGoVersion();
-		const testCases: string[][] = [
-			['gopls'],
-			['gopls', 'guru'],
-		];
-		const proxyDir = buildFakeProxy([].concat(...testCases));
+	let tmpToolsGopath: string;
+	let sandbox: sinon.SinonSandbox;
+	let toolsGopathStub: sinon.SinonStub;
 
-		for (const missing of testCases) {
-			// Create a temporary directory in which to install tools.
-			const tmpToolsGopath = fs.mkdtempSync(path.join(os.tmpdir(), 'install-test'));
-			fs.mkdirSync(path.join(tmpToolsGopath, 'bin'));
-			fs.mkdirSync(path.join(tmpToolsGopath, 'src'));
+	setup(() => {
+		// Create a temporary directory in which to install tools.
+		tmpToolsGopath = fs.mkdtempSync(path.join(os.tmpdir(), 'install-test'));
+		fs.mkdirSync(path.join(tmpToolsGopath, 'bin'));
+		fs.mkdirSync(path.join(tmpToolsGopath, 'src'));
 
-			const sandbox = sinon.createSandbox();
-			const utils = require('../../src/util');
+		sandbox = sinon.createSandbox();
+		const utils = require('../../src/util');
+		toolsGopathStub = sandbox.stub(utils, 'getToolsGopath').returns(tmpToolsGopath);
+	});
 
-			const toolsGopathStub = sandbox.stub(utils, 'getToolsGopath').returns(tmpToolsGopath);
+	teardown(async () => {
+		sandbox.restore();
+
+		// Clean up the temporary GOPATH. To delete the module cache, run `go clean -modcache`.
+		const goRuntimePath = getBinPath('go');
+		const envForTest = Object.assign({}, process.env);
+		envForTest['GOPATH'] = tmpToolsGopath;
+		const execFile = util.promisify(cp.execFile);
+		await execFile(goRuntimePath, ['clean', '-modcache'], {
+			env: envForTest,
+		});
+		rmdirRecursive(tmpToolsGopath);
+	});
+
+	// runTest actually executes the logic of the test.
+	// If withLocalProxy is true, the test does not require internet.
+	async function runTest(testCases: string[], withLocalProxy?: boolean) {
+		let proxyDir: string;
+		let configStub: sinon.SinonStub;
+		if (withLocalProxy) {
+			proxyDir = buildFakeProxy([].concat(...testCases));
 			const goConfig = Object.create(vscode.workspace.getConfiguration('go'), {
 				toolsEnvVars: {
 					value: {
@@ -45,34 +69,57 @@
 					}
 				},
 			});
-			const configStub = sandbox.stub(vscode.workspace, 'getConfiguration').returns(goConfig);
-			// TODO(rstambler): Test with versions as well.
-			const missingTools = missing.map((tool) => getToolAtVersion(tool));
-			await installTools(missingTools, goVersion);
-
-			sinon.assert.calledWith(toolsGopathStub);
-			sinon.assert.calledWith(configStub);
-			sandbox.restore();
-
-			// Read the $GOPATH/bin to confirm that the expected tools were
-			// installed.
-			const readdir = util.promisify(fs.readdir);
-			const files = await readdir(path.join(tmpToolsGopath, 'bin'));
-			assert.deepEqual(files, missing, `tool installation failed for ${missing}`);
-
-			// Clean up the temporary GOPATH. To delete the module cache, run `go clean -modcache`.
-			const goRuntimePath = getBinPath('go');
-			const envForTest = Object.assign({}, process.env);
-			envForTest['GOPATH'] = tmpToolsGopath;
-			const execFile = util.promisify(cp.execFile);
-			await execFile(goRuntimePath, ['clean', '-modcache'], {
-				env: envForTest,
-			});
-			rmdirRecursive(tmpToolsGopath);
+			configStub = sandbox.stub(vscode.workspace, 'getConfiguration').returns(goConfig);
+		} else {
+			const env = toolInstallationEnvironment();
+			console.log(`Installing tools using GOPROXY=${env['GOPROXY']}`);
 		}
 
-		rmdirRecursive(proxyDir);
+		// TODO(rstambler): Test with versions as well.
+		const missingTools = testCases.map((tool) => getToolAtVersion(tool));
+		const goVersion = await getGoVersion();
+		await installTools(missingTools, goVersion);
+
+		// Confirm that each expected tool has been installed.
+		const checks: Promise<void>[] = [];
+		const exists = util.promisify(fs.exists);
+		for (const tool of testCases) {
+			checks.push(new Promise<void>(async (resolve) => {
+				// Check that the expect tool has been installed to $GOPATH/bin.
+				const ok = await exists(path.join(tmpToolsGopath, 'bin', tool));
+				if (!ok) {
+					assert.fail(`expected ${tmpToolsGopath}/bin/${tool}, not found`);
+				}
+				return resolve();
+			}));
+		}
+		await Promise.all(checks);
+
+		sandbox.assert.calledWith(toolsGopathStub);
+
+		if (withLocalProxy) {
+			sandbox.assert.calledWith(configStub);
+			rmdirRecursive(proxyDir);
+		}
+	}
+
+	test('Install one tool with a local proxy', async () => {
+		await runTest(['gopls'], true);
 	});
+
+	test('Install multiple tools with a local proxy', async () => {
+		await runTest(['gopls', 'guru'], true);
+	});
+
+	test('Install all tools via GOPROXY', async () => {
+		// Only run this test if we are in CI before a Nightly release.
+		if (!shouldRunSlowTests()) {
+			return;
+		}
+		const tools = Object.keys(allToolsInformation);
+		await runTest(tools);
+	});
+
 });
 
 // buildFakeProxy creates a fake file-based proxy used for testing. The code is
@@ -103,3 +150,10 @@
 	}
 	return proxyDir;
 }
+
+// Check if VSCODEGO_BEFORE_RELEASE_TESTS is set to true. This environment
+// variable is set by the CI system that releases the Nightly extension,
+// allowing us to opt-in to more rigorous testing only before releases.
+function shouldRunSlowTests(): boolean {
+	return !!process.env['VSCODEGO_BEFORE_RELEASE_TESTS'];
+}
diff --git a/test/integration/statusbar.test.ts b/test/integration/statusbar.test.ts
new file mode 100644
index 0000000..e4347aa
--- /dev/null
+++ b/test/integration/statusbar.test.ts
@@ -0,0 +1,248 @@
+/*---------------------------------------------------------
+ * Copyright (C) Microsoft Corporation. All rights reserved.
+ * Modification copyright 2020 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+import * as assert from 'assert';
+import * as cp from 'child_process';
+import * as fs from 'fs-extra';
+import { describe, it } from 'mocha';
+import * as os from 'os';
+import * as path from 'path';
+import * as sinon from 'sinon';
+import * as util from 'util';
+import * as vscode from 'vscode';
+
+import {
+	disposeGoStatusBar,
+	formatGoVersion,
+	getGoEnvironmentStatusbarItem,
+	getSelectedGo,
+	GoEnvironmentOption,
+	setSelectedGo,
+} from '../../src/goEnvironmentStatus';
+import { updateGoVarsFromConfig } from '../../src/goInstallTools';
+import { getCurrentGoRoot } from '../../src/goPath';
+import ourutil = require('../../src/util');
+
+describe('#initGoStatusBar()', function () {
+	this.beforeAll(async () => {
+		await updateGoVarsFromConfig();  // should initialize the status bar.
+	});
+
+	this.afterAll(() => {
+		disposeGoStatusBar();
+	});
+
+	it('should create a status bar item', () => {
+		assert.notEqual(getGoEnvironmentStatusbarItem(), undefined);
+	});
+
+	it('should create a status bar item with a label matching go.goroot version', async () => {
+		const version = await ourutil.getGoVersion();
+		const versionLabel = formatGoVersion(version.format());
+		assert.equal(
+			getGoEnvironmentStatusbarItem().text,
+			versionLabel,
+			'goroot version does not match status bar item text'
+		);
+	});
+});
+
+describe.skip('#setSelectedGo()', function () {
+	// Disabled due to https://github.com/golang/vscode-go/issues/303.
+	this.timeout(20000);
+	let sandbox: sinon.SinonSandbox | undefined;
+	let goOption: GoEnvironmentOption;
+	let defaultGoConfig: vscode.WorkspaceConfiguration;
+
+	this.beforeAll(async () => {
+		defaultGoConfig = ourutil.getGoConfig();
+	});
+
+	this.beforeEach(async () => {
+		goOption = await getSelectedGo();
+		sandbox = sinon.createSandbox();
+	});
+	this.afterEach(async () => {
+		await setSelectedGo(goOption, vscode.ConfigurationTarget.Workspace, false);
+		sandbox.restore();
+	});
+
+	it('should update the workspace settings.json', async () => {
+		let tmpAltToolsWorkspace: any = {};
+		let tmpAltToolsGlobal: any = {};
+		const getGoConfigStub = sandbox.stub(ourutil, 'getGoConfig').returns({
+			get: (s: string) => {
+				if (s === 'alternateTools') { return tmpAltToolsWorkspace || tmpAltToolsGlobal; }
+				return defaultGoConfig.get(s);
+			},
+			update: (key: string, value: any, scope: vscode.ConfigurationTarget) => {
+				if (key === 'alternateTools') {
+					if (scope === vscode.ConfigurationTarget.Global) {
+						tmpAltToolsGlobal = value;
+					} else {
+						tmpAltToolsWorkspace = value;
+					}
+				}
+			},
+		} as vscode.WorkspaceConfiguration);
+
+		// set workspace setting
+		const workspaceTestOption = new GoEnvironmentOption('workspacetestpath', 'testlabel');
+		await setSelectedGo(workspaceTestOption, vscode.ConfigurationTarget.Workspace, false);
+
+		// check that the stub was called
+		sandbox.assert.calledWith(getGoConfigStub);
+
+		// check that the new config is set
+		assert.equal(tmpAltToolsWorkspace['go'], 'workspacetestpath');
+	});
+
+	it('should download an uninstalled version of Go', async () => {
+		if (!!process.env['VSCODEGO_BEFORE_RELEASE_TESTS']) {
+			return;
+		}
+
+		let tmpAltToolsWorkspace = {};
+		let tmpAltToolsGlobal = {};
+		const getGoConfigStub = sandbox.stub(ourutil, 'getGoConfig').returns({
+			get: (s: string) => {
+				if (s === 'alternateTools') { return tmpAltToolsWorkspace || tmpAltToolsGlobal; }
+				return defaultGoConfig.get(s);
+			},
+			update: (key: string, value: any, scope: vscode.ConfigurationTarget) => {
+				if (key === 'alternateTools') {
+					if (scope === vscode.ConfigurationTarget.Global) {
+						tmpAltToolsGlobal = value;
+					} else {
+						tmpAltToolsWorkspace = value;
+					}
+				}
+			},
+		} as vscode.WorkspaceConfiguration);
+
+		// setup tmp home directory for sdk installation
+		const envCache = Object.assign({}, process.env);
+		process.env.HOME = os.tmpdir();
+
+		// set selected go as a version to download
+		const option = new GoEnvironmentOption('go get golang.org/dl/go1.13.12', 'Go 1.13.12');
+		await setSelectedGo(option, vscode.ConfigurationTarget.Workspace, false);
+		sandbox.assert.calledWith(getGoConfigStub);
+
+		// the temp sdk directory should now contain go1.13.12
+		const subdirs = await fs.readdir(path.join(os.tmpdir(), 'sdk'));
+		assert.ok(subdirs.includes('go1.13.12'), 'Go 1.13.12 was not installed');
+
+		// cleanup
+		process.env = envCache;
+	});
+});
+
+describe('#updateGoVarsFromConfig()', function () {
+	this.timeout(10000);
+
+	let defaultGoConfig: vscode.WorkspaceConfiguration | undefined;
+	let tmpRoot: string | undefined;
+	let tmpRootBin: string | undefined;
+	let sandbox: sinon.SinonSandbox | undefined;
+
+	this.beforeAll(async () => {
+		defaultGoConfig = ourutil.getGoConfig();
+
+		tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'rootchangetest'));
+		tmpRootBin = path.join(tmpRoot, 'bin');
+
+		// build a fake go binary and place it in tmpRootBin.
+		fs.mkdirSync(tmpRootBin);
+
+		const fixtureSourcePath = path.join(__dirname, '..', '..', '..', 'test', 'fixtures', 'testhelpers');
+		const execFile = util.promisify(cp.execFile);
+		const goRuntimePath = ourutil.getBinPath('go');
+		const { stdout, stderr } = await execFile(
+			goRuntimePath, ['build', '-o', path.join(tmpRootBin, 'go'), path.join(fixtureSourcePath, 'fakego.go')]);
+		if (stderr) {
+			assert.fail(`failed to build the fake go binary required for testing: ${stderr}`);
+		}
+	});
+
+	this.afterAll(() => {
+		ourutil.rmdirRecursive(tmpRoot);
+	});
+
+	this.beforeEach(() => {
+		sandbox = sinon.createSandbox();
+	});
+
+	this.afterEach(() => {
+		sandbox.restore();
+	});
+
+	function pathEnvVar(): string[] {
+		let paths = [] as string[];
+		if (process.env.hasOwnProperty('PATH')) {
+			paths = process.env['PATH'].split(path.delimiter);
+		} else if (process.platform === 'win32' && process.env.hasOwnProperty('Path')) {
+			paths = process.env['Path'].split(path.delimiter);
+		}
+		return paths;
+	}
+
+	it('should have a sensible goroot with the default setting', async () => {
+		await updateGoVarsFromConfig();
+
+		const b = getGoEnvironmentStatusbarItem();
+		assert.ok(b.text.startsWith('Go'), `go env statusbar item = ${b.text}, want "Go..."`);
+		assert.equal(pathEnvVar()[0], [path.join(getCurrentGoRoot(), 'bin')],
+			`the first element in PATH must match the current GOROOT/bin`);
+	});
+
+	it('should recognize the adjusted goroot using go.goroot', async () => {
+		// stub geteGoConfig to return "go.goroot": tmpRoot.
+		const getGoConfigStub = sandbox.stub(ourutil, 'getGoConfig').returns({
+			get: (s: string) => {
+				if (s === 'goroot') { return tmpRoot; }
+				return defaultGoConfig.get(s);
+			},
+		} as vscode.WorkspaceConfiguration);
+
+		// adjust the fake go binary's behavior.
+		process.env['FAKEGOROOT'] = tmpRoot;
+		process.env['FAKEGOVERSION'] = 'go version go2.0.0 darwin/amd64';
+
+		await updateGoVarsFromConfig();
+
+		sandbox.assert.calledWith(getGoConfigStub);
+		assert.equal((await ourutil.getGoVersion()).format(), '2.0.0');
+		assert.equal(getGoEnvironmentStatusbarItem().text, 'Go 2.0.0');
+		assert.equal(pathEnvVar()[0], [path.join(getCurrentGoRoot(), 'bin')],
+			`the first element in PATH must match the current GOROOT/bin`);
+	});
+
+	it('should recognize the adjusted goroot using go.alternateTools', async () => {
+		// "go.alternateTools" : {"go": "go3"}
+		fs.copyFileSync(path.join(tmpRootBin, 'go'), path.join(tmpRootBin, 'go3'));
+
+		const getGoConfigStub = sandbox.stub(ourutil, 'getGoConfig').returns({
+			get: (s: string) => {
+				if (s === 'alternateTools') {
+					return { go: path.join(tmpRootBin, 'go3') };
+				}
+				return defaultGoConfig.get(s);
+			},
+		} as vscode.WorkspaceConfiguration);
+
+		process.env['FAKEGOROOT'] = tmpRoot;
+		process.env['FAKEGOVERSION'] = 'go version go3.0.0 darwin/amd64';
+
+		await updateGoVarsFromConfig();
+
+		sandbox.assert.calledWith(getGoConfigStub);
+		assert.equal((await ourutil.getGoVersion()).format(), '3.0.0');
+		assert.equal(getGoEnvironmentStatusbarItem().text, 'Go 3.0.0');
+		assert.equal(pathEnvVar()[0], [path.join(getCurrentGoRoot(), 'bin')],
+			`the first element in PATH must match the current GOROOT/bin`);
+	});
+});
diff --git a/test/runTest.ts b/test/runTest.ts
index 1f5aa01..edb587e 100644
--- a/test/runTest.ts
+++ b/test/runTest.ts
@@ -1,7 +1,5 @@
-import * as fs from 'fs-extra';
 import * as path from 'path';
 import { runTests } from 'vscode-test';
-import { extensionId } from '../src/telemetry';
 
 async function main() {
 		// The folder containing the Extension Manifest package.json
diff --git a/third_party/tree-kill/index.js b/third_party/tree-kill/index.js
index 8df6a0f..9499a89 100755
--- a/third_party/tree-kill/index.js
+++ b/third_party/tree-kill/index.js
@@ -1,6 +1,7 @@
 'use strict';
 
 var childProcess = require('child_process');
+const { existsSync } = require('fs');
 var spawn = childProcess.spawn;
 var exec = childProcess.exec;
 
@@ -30,7 +31,7 @@
         break;
     case 'darwin':
         buildProcessTree(pid, tree, pidsToProcess, function (parentPid) {
-          return spawn('pgrep', ['-P', parentPid]);
+            return spawn(pathToPgrep(), ['-P', parentPid]);
         }, function () {
             killAll(tree, signal, callback);
         });
@@ -116,3 +117,20 @@
 
     ps.on('close', onClose);
 }
+
+var pgrep = '';
+function pathToPgrep () {
+    if (pgrep) {
+        return pgrep;
+    }
+    // Use the default pgrep, available since os x mountain lion.
+    // proctools' pgrep does not implement `-P` correctly and returns
+    // unrelated processes.
+    // https://github.com/golang/vscode-go/issues/90#issuecomment-634430428
+    try {
+        pgrep = existsSync('/usr/bin/pgrep') ? '/usr/bin/pgrep' : 'pgrep';
+    } catch (e) {
+        pgrep = 'pgrep';
+    }
+    return pgrep;
+}
\ No newline at end of file
diff --git a/thirdpartynotices.txt b/thirdpartynotices.txt
deleted file mode 100644
index d00316e..0000000
--- a/thirdpartynotices.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
-For Microsoft vscode-go
- 
-This project incorporates material from the projects listed below.  The original copyright notice 
-and the license under which Microsoft received such material are set out below. Microsoft reserves 
-all other rights not expressly granted, whether by implication, estoppel or otherwise.
-
-
-1. json-rpc2 version 1.0.2 (https://github.com/pocesar/node-jsonrpc2)
-
-The MIT License
-
-       Copyright (C) 2009 Eric Florenzano <eflorenzano.com/aboutme/> and
-                          Ryan Tomayko <tomayko.com/about>
- 
-Permission  is  hereby granted, free of charge, to any person ob-
-taining a copy of  this  software  and  associated  documentation
-files  (the "Software"), to deal in the Software without restric-
-tion, including without limitation the rights to use, copy, modi-
-fy, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is  fur-
-nished 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  NONIN-
-FRINGEMENT. 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/tools/generate.go b/tools/generate.go
index 6dc6745..f93ce88 100644
--- a/tools/generate.go
+++ b/tools/generate.go
@@ -8,12 +8,18 @@
 import (
 	"bytes"
 	"encoding/json"
+	"flag"
 	"fmt"
 	"io/ioutil"
 	"log"
 	"os"
 	"path/filepath"
 	"sort"
+	"strings"
+)
+
+var (
+	writeFlag = flag.Bool("w", true, "Write new file contents to disk.")
 )
 
 type PackageJSON struct {
@@ -40,14 +46,13 @@
 }
 
 func main() {
+	flag.Parse()
+
 	// Assume this is running from the vscode-go directory.
 	dir, err := os.Getwd()
 	if err != nil {
 		log.Fatal(err)
 	}
-	if filepath.Base(dir) != "vscode-go" {
-		log.Fatalf("run this script from the vscode-go root directory")
-	}
 	// Find the package.json file.
 	data, err := ioutil.ReadFile(filepath.Join(dir, "package.json"))
 	if err != nil {
@@ -58,24 +63,39 @@
 		log.Fatal(err)
 	}
 	rewrite := func(filename string, toAdd []byte) {
-		content, err := ioutil.ReadFile(filename)
+		oldContent, err := ioutil.ReadFile(filename)
 		if err != nil {
 			log.Fatal(err)
 		}
 		gen := []byte(`<!-- Everything below this line is generated. DO NOT EDIT. -->`)
-		split := bytes.Split(content, gen)
+		split := bytes.Split(oldContent, gen)
 		if len(split) == 1 {
-			log.Fatalf("expected to find %q in %s, not found", filename, gen)
+			log.Fatalf("expected to find %q in %s, not found", gen, filename)
 		}
 		s := bytes.Join([][]byte{
 			bytes.TrimSpace(split[0]),
 			gen,
 			toAdd,
 		}, []byte("\n\n"))
-		if err := ioutil.WriteFile(filename, append(s, '\n'), 0644); err != nil {
-			log.Fatal(err)
+		newContent := append(s, '\n')
+
+		// Return early if the contents are unchanged.
+		if bytes.Equal(oldContent, newContent) {
+			return
 		}
-		fmt.Printf("regenerated %s\n", filename)
+
+		// Either write out new contents or report an error (if in CI).
+		if *writeFlag {
+			if err := ioutil.WriteFile(filename, newContent, 0644); err != nil {
+				log.Fatal(err)
+			}
+			fmt.Printf("updated %s\n", filename)
+		} else {
+			base := filepath.Join("docs", filepath.Base(filename))
+			fmt.Printf(`%s have changed in the package.json, but documentation in %s was not updated.
+`, strings.TrimSuffix(base, ".md"), base)
+			os.Exit(1)
+		}
 	}
 	var b bytes.Buffer
 	for i, c := range pkgJSON.Contributes.Commands {
diff --git a/tools/license.sh b/tools/license.sh
new file mode 100755
index 0000000..9647e1f
--- /dev/null
+++ b/tools/license.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+# Copyright 2020 The Go Authors. All rights reserved.
+# Licensed under the MIT License. See LICENSE in the project root for license information.
+
+set -euo pipefail
+
+root_dir() {
+  local script_name="${0}"
+  local script_dir=$(dirname "${script_name}")
+  local parent_dir=$(cd "${script_dir}/.." && pwd)
+  echo "${parent_dir}"
+}
+
+ROOT="$(root_dir)"
+cd "${ROOT}"  # always run from the root directory.
+
+WORKTREE="$(mktemp -d)"
+BRANCH="license-gen-$(date +%Y%m%d%H%M%S)"
+
+git fetch
+git worktree add --track -b "${BRANCH}" "${WORKTREE}" origin/master
+
+cd "${WORKTREE}"
+export GIT_GOFMT_HOOK=off
+
+YARN="${ROOT}/node_modules/.bin/yarn"
+
+ALL_LICENSES=$(
+  $YARN licenses list --json --no-progress 2>/dev/null|
+  jq 'select(.type == "table") | .data.body | map( {name: .[0], version: .[1], license: .[2], url: .[3], verndor: .[4], vendorName: .[5]} )')
+
+NG=$(echo "${ALL_LICENSES}" | jq '
+{
+  "Apache-2.0": 1,
+  "BSD-2-Clause": 1,
+  "BSD-3-Clause": 1,
+  "ISC": 1,
+  "MIT": 1,
+  "Unlicense": 1,
+  "0BSD": 1,
+  "(Unlicense OR Apache-2.0)": 1,
+} as $allowed_licenses |
+{
+  "json-schema@0.2.3": 1,
+} as $allow_list |
+.[] | select(.license | in($allowed_licenses) | not)
+| select((.name+"@"+.version) | in($allow_list) | not) ')
+
+if [ -z "${NG}" ];
+then
+  echo "PASSED license check"
+else
+  echo "FAILED license check. The following dependencies need manual check: ${NG}" &&
+  echo "WORKTREE=${WORKTREE}" &&
+  exit 1
+fi
+
+LICENSEFILE="LICENSE.prod"
+cat LICENSE > "${LICENSEFILE}"
+printf "\n\n" >> "${LICENSEFILE}"
+"${YARN}" licenses generate-disclaimer --prod >> "${LICENSEFILE}"
+
+if [[ -f thirdpartynotices.txt ]]
+then
+  printf "\n" >> "${LICENSEFILE}"
+  cat thirdpartynotices.txt >> "${LICENSEFILE}"
+fi
+
+cd - && mv "${WORKTREE}/${LICENSEFILE}" . && git worktree remove "${WORKTREE}" -f
diff --git a/tsconfig.json b/tsconfig.json
index 6045bef..df30337 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,4 +20,4 @@
 		"node_modules",
 		"third_party"
 	]
-}
\ No newline at end of file
+}
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..80c8737
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,47 @@
+//@ts-check
+
+'use strict';
+
+const path = require('path');
+
+/**@type {import('webpack').WebpackOptions}*/
+const config = {
+	target: 'node',
+	entry: {
+		goMain: './src/goMain.ts',
+		debugAdapter: './src/debugAdapter/goDebug.ts',
+		debugAdapter2: './src/debugAdapter2/goDlvDebugMain.ts',
+	},
+	output: {
+		path: path.resolve(__dirname, 'dist'),
+		filename: '[name].js',
+		libraryTarget: 'commonjs2',
+		devtoolModuleFilenameTemplate: '../[resource-path]'
+	},
+	devtool: 'none',
+	externals: {
+		// the vscode-module is created on-the-fly and must be excluded.
+		vscode: 'commonjs vscode'
+	},
+	resolve: {
+		extensions: ['.ts', '.js']
+	},
+	module: {
+		rules: [
+			{
+				test: /\.ts$/,
+				exclude: /node_modules/,
+				use: [
+					{
+						loader: 'ts-loader'
+					}
+				]
+			}
+		]
+	},
+	optimization: {
+		// when this is true, the debugger breaks...
+		minimize: false
+	},
+};
+module.exports = config;