diff --git a/vendor/golang.org/x/lint/LICENSE b/vendor/golang.org/x/lint/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..65d761bc9f28c7de26b4f39c495d5ebd365b114d
--- /dev/null
+++ b/vendor/golang.org/x/lint/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/lint/golint/golint.go b/vendor/golang.org/x/lint/golint/golint.go
new file mode 100644
index 0000000000000000000000000000000000000000..d53bce3c12897126e458f5cc044490c0b843d96d
--- /dev/null
+++ b/vendor/golang.org/x/lint/golint/golint.go
@@ -0,0 +1,159 @@
+// Copyright (c) 2013 The Go Authors. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd.
+
+// golint lints the Go source files named on its command line.
+package main // import "golang.org/x/lint/golint"
+
+import (
+	"flag"
+	"fmt"
+	"go/build"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"golang.org/x/lint"
+)
+
+var (
+	minConfidence = flag.Float64("min_confidence", 0.8, "minimum confidence of a problem to print it")
+	setExitStatus = flag.Bool("set_exit_status", false, "set exit status to 1 if any issues are found")
+	suggestions   int
+)
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
+	fmt.Fprintf(os.Stderr, "\tgolint [flags] # runs on package in current directory\n")
+	fmt.Fprintf(os.Stderr, "\tgolint [flags] [packages]\n")
+	fmt.Fprintf(os.Stderr, "\tgolint [flags] [directories] # where a '/...' suffix includes all sub-directories\n")
+	fmt.Fprintf(os.Stderr, "\tgolint [flags] [files] # all must belong to a single package\n")
+	fmt.Fprintf(os.Stderr, "Flags:\n")
+	flag.PrintDefaults()
+}
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+
+	if flag.NArg() == 0 {
+		lintDir(".")
+	} else {
+		// dirsRun, filesRun, and pkgsRun indicate whether golint is applied to
+		// directory, file or package targets. The distinction affects which
+		// checks are run. It is no valid to mix target types.
+		var dirsRun, filesRun, pkgsRun int
+		var args []string
+		for _, arg := range flag.Args() {
+			if strings.HasSuffix(arg, "/...") && isDir(arg[:len(arg)-len("/...")]) {
+				dirsRun = 1
+				for _, dirname := range allPackagesInFS(arg) {
+					args = append(args, dirname)
+				}
+			} else if isDir(arg) {
+				dirsRun = 1
+				args = append(args, arg)
+			} else if exists(arg) {
+				filesRun = 1
+				args = append(args, arg)
+			} else {
+				pkgsRun = 1
+				args = append(args, arg)
+			}
+		}
+
+		if dirsRun+filesRun+pkgsRun != 1 {
+			usage()
+			os.Exit(2)
+		}
+		switch {
+		case dirsRun == 1:
+			for _, dir := range args {
+				lintDir(dir)
+			}
+		case filesRun == 1:
+			lintFiles(args...)
+		case pkgsRun == 1:
+			for _, pkg := range importPaths(args) {
+				lintPackage(pkg)
+			}
+		}
+	}
+
+	if *setExitStatus && suggestions > 0 {
+		fmt.Fprintf(os.Stderr, "Found %d lint suggestions; failing.\n", suggestions)
+		os.Exit(1)
+	}
+}
+
+func isDir(filename string) bool {
+	fi, err := os.Stat(filename)
+	return err == nil && fi.IsDir()
+}
+
+func exists(filename string) bool {
+	_, err := os.Stat(filename)
+	return err == nil
+}
+
+func lintFiles(filenames ...string) {
+	files := make(map[string][]byte)
+	for _, filename := range filenames {
+		src, err := ioutil.ReadFile(filename)
+		if err != nil {
+			fmt.Fprintln(os.Stderr, err)
+			continue
+		}
+		files[filename] = src
+	}
+
+	l := new(lint.Linter)
+	ps, err := l.LintFiles(files)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "%v\n", err)
+		return
+	}
+	for _, p := range ps {
+		if p.Confidence >= *minConfidence {
+			fmt.Printf("%v: %s\n", p.Position, p.Text)
+			suggestions++
+		}
+	}
+}
+
+func lintDir(dirname string) {
+	pkg, err := build.ImportDir(dirname, 0)
+	lintImportedPackage(pkg, err)
+}
+
+func lintPackage(pkgname string) {
+	pkg, err := build.Import(pkgname, ".", 0)
+	lintImportedPackage(pkg, err)
+}
+
+func lintImportedPackage(pkg *build.Package, err error) {
+	if err != nil {
+		if _, nogo := err.(*build.NoGoError); nogo {
+			// Don't complain if the failure is due to no Go source files.
+			return
+		}
+		fmt.Fprintln(os.Stderr, err)
+		return
+	}
+
+	var files []string
+	files = append(files, pkg.GoFiles...)
+	files = append(files, pkg.CgoFiles...)
+	files = append(files, pkg.TestGoFiles...)
+	if pkg.Dir != "." {
+		for i, f := range files {
+			files[i] = filepath.Join(pkg.Dir, f)
+		}
+	}
+	// TODO(dsymonds): Do foo_test too (pkg.XTestGoFiles)
+
+	lintFiles(files...)
+}
diff --git a/vendor/golang.org/x/lint/golint/import.go b/vendor/golang.org/x/lint/golint/import.go
new file mode 100644
index 0000000000000000000000000000000000000000..2ba9dea779273cfaafc5d506eb564e1ac8ac6025
--- /dev/null
+++ b/vendor/golang.org/x/lint/golint/import.go
@@ -0,0 +1,309 @@
+package main
+
+/*
+
+This file holds a direct copy of the import path matching code of
+https://github.com/golang/go/blob/master/src/cmd/go/main.go. It can be
+replaced when https://golang.org/issue/8768 is resolved.
+
+It has been updated to follow upstream changes in a few ways.
+
+*/
+
+import (
+	"fmt"
+	"go/build"
+	"log"
+	"os"
+	"path"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strings"
+)
+
+var (
+	buildContext = build.Default
+	goroot       = filepath.Clean(runtime.GOROOT())
+	gorootSrc    = filepath.Join(goroot, "src")
+)
+
+// importPathsNoDotExpansion returns the import paths to use for the given
+// command line, but it does no ... expansion.
+func importPathsNoDotExpansion(args []string) []string {
+	if len(args) == 0 {
+		return []string{"."}
+	}
+	var out []string
+	for _, a := range args {
+		// Arguments are supposed to be import paths, but
+		// as a courtesy to Windows developers, rewrite \ to /
+		// in command-line arguments.  Handles .\... and so on.
+		if filepath.Separator == '\\' {
+			a = strings.Replace(a, `\`, `/`, -1)
+		}
+
+		// Put argument in canonical form, but preserve leading ./.
+		if strings.HasPrefix(a, "./") {
+			a = "./" + path.Clean(a)
+			if a == "./." {
+				a = "."
+			}
+		} else {
+			a = path.Clean(a)
+		}
+		if a == "all" || a == "std" {
+			out = append(out, allPackages(a)...)
+			continue
+		}
+		out = append(out, a)
+	}
+	return out
+}
+
+// importPaths returns the import paths to use for the given command line.
+func importPaths(args []string) []string {
+	args = importPathsNoDotExpansion(args)
+	var out []string
+	for _, a := range args {
+		if strings.Contains(a, "...") {
+			if build.IsLocalImport(a) {
+				out = append(out, allPackagesInFS(a)...)
+			} else {
+				out = append(out, allPackages(a)...)
+			}
+			continue
+		}
+		out = append(out, a)
+	}
+	return out
+}
+
+// matchPattern(pattern)(name) reports whether
+// name matches pattern.  Pattern is a limited glob
+// pattern in which '...' means 'any string' and there
+// is no other special syntax.
+func matchPattern(pattern string) func(name string) bool {
+	re := regexp.QuoteMeta(pattern)
+	re = strings.Replace(re, `\.\.\.`, `.*`, -1)
+	// Special case: foo/... matches foo too.
+	if strings.HasSuffix(re, `/.*`) {
+		re = re[:len(re)-len(`/.*`)] + `(/.*)?`
+	}
+	reg := regexp.MustCompile(`^` + re + `$`)
+	return func(name string) bool {
+		return reg.MatchString(name)
+	}
+}
+
+// hasPathPrefix reports whether the path s begins with the
+// elements in prefix.
+func hasPathPrefix(s, prefix string) bool {
+	switch {
+	default:
+		return false
+	case len(s) == len(prefix):
+		return s == prefix
+	case len(s) > len(prefix):
+		if prefix != "" && prefix[len(prefix)-1] == '/' {
+			return strings.HasPrefix(s, prefix)
+		}
+		return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
+	}
+}
+
+// treeCanMatchPattern(pattern)(name) reports whether
+// name or children of name can possibly match pattern.
+// Pattern is the same limited glob accepted by matchPattern.
+func treeCanMatchPattern(pattern string) func(name string) bool {
+	wildCard := false
+	if i := strings.Index(pattern, "..."); i >= 0 {
+		wildCard = true
+		pattern = pattern[:i]
+	}
+	return func(name string) bool {
+		return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
+			wildCard && strings.HasPrefix(name, pattern)
+	}
+}
+
+// allPackages returns all the packages that can be found
+// under the $GOPATH directories and $GOROOT matching pattern.
+// The pattern is either "all" (all packages), "std" (standard packages)
+// or a path including "...".
+func allPackages(pattern string) []string {
+	pkgs := matchPackages(pattern)
+	if len(pkgs) == 0 {
+		fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
+	}
+	return pkgs
+}
+
+func matchPackages(pattern string) []string {
+	match := func(string) bool { return true }
+	treeCanMatch := func(string) bool { return true }
+	if pattern != "all" && pattern != "std" {
+		match = matchPattern(pattern)
+		treeCanMatch = treeCanMatchPattern(pattern)
+	}
+
+	have := map[string]bool{
+		"builtin": true, // ignore pseudo-package that exists only for documentation
+	}
+	if !buildContext.CgoEnabled {
+		have["runtime/cgo"] = true // ignore during walk
+	}
+	var pkgs []string
+
+	// Commands
+	cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
+	filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
+		if err != nil || !fi.IsDir() || path == cmd {
+			return nil
+		}
+		name := path[len(cmd):]
+		if !treeCanMatch(name) {
+			return filepath.SkipDir
+		}
+		// Commands are all in cmd/, not in subdirectories.
+		if strings.Contains(name, string(filepath.Separator)) {
+			return filepath.SkipDir
+		}
+
+		// We use, e.g., cmd/gofmt as the pseudo import path for gofmt.
+		name = "cmd/" + name
+		if have[name] {
+			return nil
+		}
+		have[name] = true
+		if !match(name) {
+			return nil
+		}
+		_, err = buildContext.ImportDir(path, 0)
+		if err != nil {
+			if _, noGo := err.(*build.NoGoError); !noGo {
+				log.Print(err)
+			}
+			return nil
+		}
+		pkgs = append(pkgs, name)
+		return nil
+	})
+
+	for _, src := range buildContext.SrcDirs() {
+		if (pattern == "std" || pattern == "cmd") && src != gorootSrc {
+			continue
+		}
+		src = filepath.Clean(src) + string(filepath.Separator)
+		root := src
+		if pattern == "cmd" {
+			root += "cmd" + string(filepath.Separator)
+		}
+		filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
+			if err != nil || !fi.IsDir() || path == src {
+				return nil
+			}
+
+			// Avoid .foo, _foo, and testdata directory trees.
+			_, elem := filepath.Split(path)
+			if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
+				return filepath.SkipDir
+			}
+
+			name := filepath.ToSlash(path[len(src):])
+			if pattern == "std" && (strings.Contains(name, ".") || name == "cmd") {
+				// The name "std" is only the standard library.
+				// If the name is cmd, it's the root of the command tree.
+				return filepath.SkipDir
+			}
+			if !treeCanMatch(name) {
+				return filepath.SkipDir
+			}
+			if have[name] {
+				return nil
+			}
+			have[name] = true
+			if !match(name) {
+				return nil
+			}
+			_, err = buildContext.ImportDir(path, 0)
+			if err != nil {
+				if _, noGo := err.(*build.NoGoError); noGo {
+					return nil
+				}
+			}
+			pkgs = append(pkgs, name)
+			return nil
+		})
+	}
+	return pkgs
+}
+
+// allPackagesInFS is like allPackages but is passed a pattern
+// beginning ./ or ../, meaning it should scan the tree rooted
+// at the given directory.  There are ... in the pattern too.
+func allPackagesInFS(pattern string) []string {
+	pkgs := matchPackagesInFS(pattern)
+	if len(pkgs) == 0 {
+		fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
+	}
+	return pkgs
+}
+
+func matchPackagesInFS(pattern string) []string {
+	// Find directory to begin the scan.
+	// Could be smarter but this one optimization
+	// is enough for now, since ... is usually at the
+	// end of a path.
+	i := strings.Index(pattern, "...")
+	dir, _ := path.Split(pattern[:i])
+
+	// pattern begins with ./ or ../.
+	// path.Clean will discard the ./ but not the ../.
+	// We need to preserve the ./ for pattern matching
+	// and in the returned import paths.
+	prefix := ""
+	if strings.HasPrefix(pattern, "./") {
+		prefix = "./"
+	}
+	match := matchPattern(pattern)
+
+	var pkgs []string
+	filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
+		if err != nil || !fi.IsDir() {
+			return nil
+		}
+		if path == dir {
+			// filepath.Walk starts at dir and recurses. For the recursive case,
+			// the path is the result of filepath.Join, which calls filepath.Clean.
+			// The initial case is not Cleaned, though, so we do this explicitly.
+			//
+			// This converts a path like "./io/" to "io". Without this step, running
+			// "cd $GOROOT/src/pkg; go list ./io/..." would incorrectly skip the io
+			// package, because prepending the prefix "./" to the unclean path would
+			// result in "././io", and match("././io") returns false.
+			path = filepath.Clean(path)
+		}
+
+		// Avoid .foo, _foo, and testdata directory trees, but do not avoid "." or "..".
+		_, elem := filepath.Split(path)
+		dot := strings.HasPrefix(elem, ".") && elem != "." && elem != ".."
+		if dot || strings.HasPrefix(elem, "_") || elem == "testdata" {
+			return filepath.SkipDir
+		}
+
+		name := prefix + filepath.ToSlash(path)
+		if !match(name) {
+			return nil
+		}
+		if _, err = build.ImportDir(path, 0); err != nil {
+			if _, noGo := err.(*build.NoGoError); !noGo {
+				log.Print(err)
+			}
+			return nil
+		}
+		pkgs = append(pkgs, name)
+		return nil
+	})
+	return pkgs
+}
diff --git a/vendor/golang.org/x/lint/lint.go b/vendor/golang.org/x/lint/lint.go
new file mode 100644
index 0000000000000000000000000000000000000000..915fbcb30026124fa1ce69055d69dd18a0b9cb89
--- /dev/null
+++ b/vendor/golang.org/x/lint/lint.go
@@ -0,0 +1,1671 @@
+// Copyright (c) 2013 The Go Authors. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd.
+
+// Package lint contains a linter for Go source code.
+package lint // import "golang.org/x/lint"
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/printer"
+	"go/token"
+	"go/types"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"golang.org/x/tools/go/ast/astutil"
+	"golang.org/x/tools/go/gcexportdata"
+)
+
+const styleGuideBase = "https://golang.org/wiki/CodeReviewComments"
+
+// A Linter lints Go source code.
+type Linter struct {
+}
+
+// Problem represents a problem in some source code.
+type Problem struct {
+	Position   token.Position // position in source file
+	Text       string         // the prose that describes the problem
+	Link       string         // (optional) the link to the style guide for the problem
+	Confidence float64        // a value in (0,1] estimating the confidence in this problem's correctness
+	LineText   string         // the source line
+	Category   string         // a short name for the general category of the problem
+
+	// If the problem has a suggested fix (the minority case),
+	// ReplacementLine is a full replacement for the relevant line of the source file.
+	ReplacementLine string
+}
+
+func (p *Problem) String() string {
+	if p.Link != "" {
+		return p.Text + "\n\n" + p.Link
+	}
+	return p.Text
+}
+
+type byPosition []Problem
+
+func (p byPosition) Len() int      { return len(p) }
+func (p byPosition) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+func (p byPosition) Less(i, j int) bool {
+	pi, pj := p[i].Position, p[j].Position
+
+	if pi.Filename != pj.Filename {
+		return pi.Filename < pj.Filename
+	}
+	if pi.Line != pj.Line {
+		return pi.Line < pj.Line
+	}
+	if pi.Column != pj.Column {
+		return pi.Column < pj.Column
+	}
+
+	return p[i].Text < p[j].Text
+}
+
+// Lint lints src.
+func (l *Linter) Lint(filename string, src []byte) ([]Problem, error) {
+	return l.LintFiles(map[string][]byte{filename: src})
+}
+
+// LintFiles lints a set of files of a single package.
+// The argument is a map of filename to source.
+func (l *Linter) LintFiles(files map[string][]byte) ([]Problem, error) {
+	pkg := &pkg{
+		fset:  token.NewFileSet(),
+		files: make(map[string]*file),
+	}
+	var pkgName string
+	for filename, src := range files {
+		if isGenerated(src) {
+			continue // See issue #239
+		}
+		f, err := parser.ParseFile(pkg.fset, filename, src, parser.ParseComments)
+		if err != nil {
+			return nil, err
+		}
+		if pkgName == "" {
+			pkgName = f.Name.Name
+		} else if f.Name.Name != pkgName {
+			return nil, fmt.Errorf("%s is in package %s, not %s", filename, f.Name.Name, pkgName)
+		}
+		pkg.files[filename] = &file{
+			pkg:      pkg,
+			f:        f,
+			fset:     pkg.fset,
+			src:      src,
+			filename: filename,
+		}
+	}
+	if len(pkg.files) == 0 {
+		return nil, nil
+	}
+	return pkg.lint(), nil
+}
+
+var (
+	genHdr = []byte("// Code generated ")
+	genFtr = []byte(" DO NOT EDIT.")
+)
+
+// isGenerated reports whether the source file is generated code
+// according the rules from https://golang.org/s/generatedcode.
+func isGenerated(src []byte) bool {
+	sc := bufio.NewScanner(bytes.NewReader(src))
+	for sc.Scan() {
+		b := sc.Bytes()
+		if bytes.HasPrefix(b, genHdr) && bytes.HasSuffix(b, genFtr) && len(b) >= len(genHdr)+len(genFtr) {
+			return true
+		}
+	}
+	return false
+}
+
+// pkg represents a package being linted.
+type pkg struct {
+	fset  *token.FileSet
+	files map[string]*file
+
+	typesPkg  *types.Package
+	typesInfo *types.Info
+
+	// sortable is the set of types in the package that implement sort.Interface.
+	sortable map[string]bool
+	// main is whether this is a "main" package.
+	main bool
+
+	problems []Problem
+}
+
+func (p *pkg) lint() []Problem {
+	if err := p.typeCheck(); err != nil {
+		/* TODO(dsymonds): Consider reporting these errors when golint operates on entire packages.
+		if e, ok := err.(types.Error); ok {
+			pos := p.fset.Position(e.Pos)
+			conf := 1.0
+			if strings.Contains(e.Msg, "can't find import: ") {
+				// Golint is probably being run in a context that doesn't support
+				// typechecking (e.g. package files aren't found), so don't warn about it.
+				conf = 0
+			}
+			if conf > 0 {
+				p.errorfAt(pos, conf, category("typechecking"), e.Msg)
+			}
+
+			// TODO(dsymonds): Abort if !e.Soft?
+		}
+		*/
+	}
+
+	p.scanSortable()
+	p.main = p.isMain()
+
+	for _, f := range p.files {
+		f.lint()
+	}
+
+	sort.Sort(byPosition(p.problems))
+
+	return p.problems
+}
+
+// file represents a file being linted.
+type file struct {
+	pkg      *pkg
+	f        *ast.File
+	fset     *token.FileSet
+	src      []byte
+	filename string
+}
+
+func (f *file) isTest() bool { return strings.HasSuffix(f.filename, "_test.go") }
+
+func (f *file) lint() {
+	f.lintPackageComment()
+	f.lintImports()
+	f.lintBlankImports()
+	f.lintExported()
+	f.lintNames()
+	f.lintVarDecls()
+	f.lintElses()
+	f.lintRanges()
+	f.lintErrorf()
+	f.lintErrors()
+	f.lintErrorStrings()
+	f.lintReceiverNames()
+	f.lintIncDec()
+	f.lintErrorReturn()
+	f.lintUnexportedReturn()
+	f.lintTimeNames()
+	f.lintContextKeyTypes()
+	f.lintContextArgs()
+}
+
+type link string
+type category string
+
+// The variadic arguments may start with link and category types,
+// and must end with a format string and any arguments.
+// It returns the new Problem.
+func (f *file) errorf(n ast.Node, confidence float64, args ...interface{}) *Problem {
+	pos := f.fset.Position(n.Pos())
+	if pos.Filename == "" {
+		pos.Filename = f.filename
+	}
+	return f.pkg.errorfAt(pos, confidence, args...)
+}
+
+func (p *pkg) errorfAt(pos token.Position, confidence float64, args ...interface{}) *Problem {
+	problem := Problem{
+		Position:   pos,
+		Confidence: confidence,
+	}
+	if pos.Filename != "" {
+		// The file might not exist in our mapping if a //line directive was encountered.
+		if f, ok := p.files[pos.Filename]; ok {
+			problem.LineText = srcLine(f.src, pos)
+		}
+	}
+
+argLoop:
+	for len(args) > 1 { // always leave at least the format string in args
+		switch v := args[0].(type) {
+		case link:
+			problem.Link = string(v)
+		case category:
+			problem.Category = string(v)
+		default:
+			break argLoop
+		}
+		args = args[1:]
+	}
+
+	problem.Text = fmt.Sprintf(args[0].(string), args[1:]...)
+
+	p.problems = append(p.problems, problem)
+	return &p.problems[len(p.problems)-1]
+}
+
+var newImporter = func(fset *token.FileSet) types.ImporterFrom {
+	return gcexportdata.NewImporter(fset, make(map[string]*types.Package))
+}
+
+func (p *pkg) typeCheck() error {
+	config := &types.Config{
+		// By setting a no-op error reporter, the type checker does as much work as possible.
+		Error:    func(error) {},
+		Importer: newImporter(p.fset),
+	}
+	info := &types.Info{
+		Types:  make(map[ast.Expr]types.TypeAndValue),
+		Defs:   make(map[*ast.Ident]types.Object),
+		Uses:   make(map[*ast.Ident]types.Object),
+		Scopes: make(map[ast.Node]*types.Scope),
+	}
+	var anyFile *file
+	var astFiles []*ast.File
+	for _, f := range p.files {
+		anyFile = f
+		astFiles = append(astFiles, f.f)
+	}
+	pkg, err := config.Check(anyFile.f.Name.Name, p.fset, astFiles, info)
+	// Remember the typechecking info, even if config.Check failed,
+	// since we will get partial information.
+	p.typesPkg = pkg
+	p.typesInfo = info
+	return err
+}
+
+func (p *pkg) typeOf(expr ast.Expr) types.Type {
+	if p.typesInfo == nil {
+		return nil
+	}
+	return p.typesInfo.TypeOf(expr)
+}
+
+func (p *pkg) isNamedType(typ types.Type, importPath, name string) bool {
+	n, ok := typ.(*types.Named)
+	if !ok {
+		return false
+	}
+	tn := n.Obj()
+	return tn != nil && tn.Pkg() != nil && tn.Pkg().Path() == importPath && tn.Name() == name
+}
+
+// scopeOf returns the tightest scope encompassing id.
+func (p *pkg) scopeOf(id *ast.Ident) *types.Scope {
+	var scope *types.Scope
+	if obj := p.typesInfo.ObjectOf(id); obj != nil {
+		scope = obj.Parent()
+	}
+	if scope == p.typesPkg.Scope() {
+		// We were given a top-level identifier.
+		// Use the file-level scope instead of the package-level scope.
+		pos := id.Pos()
+		for _, f := range p.files {
+			if f.f.Pos() <= pos && pos < f.f.End() {
+				scope = p.typesInfo.Scopes[f.f]
+				break
+			}
+		}
+	}
+	return scope
+}
+
+func (p *pkg) scanSortable() {
+	p.sortable = make(map[string]bool)
+
+	// bitfield for which methods exist on each type.
+	const (
+		Len = 1 << iota
+		Less
+		Swap
+	)
+	nmap := map[string]int{"Len": Len, "Less": Less, "Swap": Swap}
+	has := make(map[string]int)
+	for _, f := range p.files {
+		f.walk(func(n ast.Node) bool {
+			fn, ok := n.(*ast.FuncDecl)
+			if !ok || fn.Recv == nil || len(fn.Recv.List) == 0 {
+				return true
+			}
+			// TODO(dsymonds): We could check the signature to be more precise.
+			recv := receiverType(fn)
+			if i, ok := nmap[fn.Name.Name]; ok {
+				has[recv] |= i
+			}
+			return false
+		})
+	}
+	for typ, ms := range has {
+		if ms == Len|Less|Swap {
+			p.sortable[typ] = true
+		}
+	}
+}
+
+func (p *pkg) isMain() bool {
+	for _, f := range p.files {
+		if f.isMain() {
+			return true
+		}
+	}
+	return false
+}
+
+func (f *file) isMain() bool {
+	if f.f.Name.Name == "main" {
+		return true
+	}
+	return false
+}
+
+// lintPackageComment checks package comments. It complains if
+// there is no package comment, or if it is not of the right form.
+// This has a notable false positive in that a package comment
+// could rightfully appear in a different file of the same package,
+// but that's not easy to fix since this linter is file-oriented.
+func (f *file) lintPackageComment() {
+	if f.isTest() {
+		return
+	}
+
+	const ref = styleGuideBase + "#package-comments"
+	prefix := "Package " + f.f.Name.Name + " "
+
+	// Look for a detached package comment.
+	// First, scan for the last comment that occurs before the "package" keyword.
+	var lastCG *ast.CommentGroup
+	for _, cg := range f.f.Comments {
+		if cg.Pos() > f.f.Package {
+			// Gone past "package" keyword.
+			break
+		}
+		lastCG = cg
+	}
+	if lastCG != nil && strings.HasPrefix(lastCG.Text(), prefix) {
+		endPos := f.fset.Position(lastCG.End())
+		pkgPos := f.fset.Position(f.f.Package)
+		if endPos.Line+1 < pkgPos.Line {
+			// There isn't a great place to anchor this error;
+			// the start of the blank lines between the doc and the package statement
+			// is at least pointing at the location of the problem.
+			pos := token.Position{
+				Filename: endPos.Filename,
+				// Offset not set; it is non-trivial, and doesn't appear to be needed.
+				Line:   endPos.Line + 1,
+				Column: 1,
+			}
+			f.pkg.errorfAt(pos, 0.9, link(ref), category("comments"), "package comment is detached; there should be no blank lines between it and the package statement")
+			return
+		}
+	}
+
+	if f.f.Doc == nil {
+		f.errorf(f.f, 0.2, link(ref), category("comments"), "should have a package comment, unless it's in another file for this package")
+		return
+	}
+	s := f.f.Doc.Text()
+	if ts := strings.TrimLeft(s, " \t"); ts != s {
+		f.errorf(f.f.Doc, 1, link(ref), category("comments"), "package comment should not have leading space")
+		s = ts
+	}
+	// Only non-main packages need to keep to this form.
+	if !f.pkg.main && !strings.HasPrefix(s, prefix) {
+		f.errorf(f.f.Doc, 1, link(ref), category("comments"), `package comment should be of the form "%s..."`, prefix)
+	}
+}
+
+// lintBlankImports complains if a non-main package has blank imports that are
+// not documented.
+func (f *file) lintBlankImports() {
+	// In package main and in tests, we don't complain about blank imports.
+	if f.pkg.main || f.isTest() {
+		return
+	}
+
+	// The first element of each contiguous group of blank imports should have
+	// an explanatory comment of some kind.
+	for i, imp := range f.f.Imports {
+		pos := f.fset.Position(imp.Pos())
+
+		if !isBlank(imp.Name) {
+			continue // Ignore non-blank imports.
+		}
+		if i > 0 {
+			prev := f.f.Imports[i-1]
+			prevPos := f.fset.Position(prev.Pos())
+			if isBlank(prev.Name) && prevPos.Line+1 == pos.Line {
+				continue // A subsequent blank in a group.
+			}
+		}
+
+		// This is the first blank import of a group.
+		if imp.Doc == nil && imp.Comment == nil {
+			ref := ""
+			f.errorf(imp, 1, link(ref), category("imports"), "a blank import should be only in a main or test package, or have a comment justifying it")
+		}
+	}
+}
+
+// lintImports examines import blocks.
+func (f *file) lintImports() {
+	for i, is := range f.f.Imports {
+		_ = i
+		if is.Name != nil && is.Name.Name == "." && !f.isTest() {
+			f.errorf(is, 1, link(styleGuideBase+"#import-dot"), category("imports"), "should not use dot imports")
+		}
+
+	}
+}
+
+const docCommentsLink = styleGuideBase + "#doc-comments"
+
+// lintExported examines the exported names.
+// It complains if any required doc comments are missing,
+// or if they are not of the right form. The exact rules are in
+// lintFuncDoc, lintTypeDoc and lintValueSpecDoc; this function
+// also tracks the GenDecl structure being traversed to permit
+// doc comments for constants to be on top of the const block.
+// It also complains if the names stutter when combined with
+// the package name.
+func (f *file) lintExported() {
+	if f.isTest() {
+		return
+	}
+
+	var lastGen *ast.GenDecl // last GenDecl entered.
+
+	// Set of GenDecls that have already had missing comments flagged.
+	genDeclMissingComments := make(map[*ast.GenDecl]bool)
+
+	f.walk(func(node ast.Node) bool {
+		switch v := node.(type) {
+		case *ast.GenDecl:
+			if v.Tok == token.IMPORT {
+				return false
+			}
+			// token.CONST, token.TYPE or token.VAR
+			lastGen = v
+			return true
+		case *ast.FuncDecl:
+			f.lintFuncDoc(v)
+			if v.Recv == nil {
+				// Only check for stutter on functions, not methods.
+				// Method names are not used package-qualified.
+				f.checkStutter(v.Name, "func")
+			}
+			// Don't proceed inside funcs.
+			return false
+		case *ast.TypeSpec:
+			// inside a GenDecl, which usually has the doc
+			doc := v.Doc
+			if doc == nil {
+				doc = lastGen.Doc
+			}
+			f.lintTypeDoc(v, doc)
+			f.checkStutter(v.Name, "type")
+			// Don't proceed inside types.
+			return false
+		case *ast.ValueSpec:
+			f.lintValueSpecDoc(v, lastGen, genDeclMissingComments)
+			return false
+		}
+		return true
+	})
+}
+
+var (
+	allCapsRE = regexp.MustCompile(`^[A-Z0-9_]+$`)
+	anyCapsRE = regexp.MustCompile(`[A-Z]`)
+)
+
+// knownNameExceptions is a set of names that are known to be exempt from naming checks.
+// This is usually because they are constrained by having to match names in the
+// standard library.
+var knownNameExceptions = map[string]bool{
+	"LastInsertId": true, // must match database/sql
+	"kWh":          true,
+}
+
+// lintNames examines all names in the file.
+// It complains if any use underscores or incorrect known initialisms.
+func (f *file) lintNames() {
+	// Package names need slightly different handling than other names.
+	if strings.Contains(f.f.Name.Name, "_") && !strings.HasSuffix(f.f.Name.Name, "_test") {
+		f.errorf(f.f, 1, link("http://golang.org/doc/effective_go.html#package-names"), category("naming"), "don't use an underscore in package name")
+	}
+	if anyCapsRE.MatchString(f.f.Name.Name) {
+		f.errorf(f.f, 1, link("http://golang.org/doc/effective_go.html#package-names"), category("mixed-caps"), "don't use MixedCaps in package name; %s should be %s", f.f.Name.Name, strings.ToLower(f.f.Name.Name))
+	}
+
+	check := func(id *ast.Ident, thing string) {
+		if id.Name == "_" {
+			return
+		}
+		if knownNameExceptions[id.Name] {
+			return
+		}
+
+		// Handle two common styles from other languages that don't belong in Go.
+		if len(id.Name) >= 5 && allCapsRE.MatchString(id.Name) && strings.Contains(id.Name, "_") {
+			f.errorf(id, 0.8, link(styleGuideBase+"#mixed-caps"), category("naming"), "don't use ALL_CAPS in Go names; use CamelCase")
+			return
+		}
+		if len(id.Name) > 2 && id.Name[0] == 'k' && id.Name[1] >= 'A' && id.Name[1] <= 'Z' {
+			should := string(id.Name[1]+'a'-'A') + id.Name[2:]
+			f.errorf(id, 0.8, link(styleGuideBase+"#mixed-caps"), category("naming"), "don't use leading k in Go names; %s %s should be %s", thing, id.Name, should)
+		}
+
+		should := lintName(id.Name)
+		if id.Name == should {
+			return
+		}
+
+		if len(id.Name) > 2 && strings.Contains(id.Name[1:], "_") {
+			f.errorf(id, 0.9, link("http://golang.org/doc/effective_go.html#mixed-caps"), category("naming"), "don't use underscores in Go names; %s %s should be %s", thing, id.Name, should)
+			return
+		}
+		f.errorf(id, 0.8, link(styleGuideBase+"#initialisms"), category("naming"), "%s %s should be %s", thing, id.Name, should)
+	}
+	checkList := func(fl *ast.FieldList, thing string) {
+		if fl == nil {
+			return
+		}
+		for _, f := range fl.List {
+			for _, id := range f.Names {
+				check(id, thing)
+			}
+		}
+	}
+	f.walk(func(node ast.Node) bool {
+		switch v := node.(type) {
+		case *ast.AssignStmt:
+			if v.Tok == token.ASSIGN {
+				return true
+			}
+			for _, exp := range v.Lhs {
+				if id, ok := exp.(*ast.Ident); ok {
+					check(id, "var")
+				}
+			}
+		case *ast.FuncDecl:
+			if f.isTest() && (strings.HasPrefix(v.Name.Name, "Example") || strings.HasPrefix(v.Name.Name, "Test") || strings.HasPrefix(v.Name.Name, "Benchmark")) {
+				return true
+			}
+
+			thing := "func"
+			if v.Recv != nil {
+				thing = "method"
+			}
+
+			// Exclude naming warnings for functions that are exported to C but
+			// not exported in the Go API.
+			// See https://github.com/golang/lint/issues/144.
+			if ast.IsExported(v.Name.Name) || !isCgoExported(v) {
+				check(v.Name, thing)
+			}
+
+			checkList(v.Type.Params, thing+" parameter")
+			checkList(v.Type.Results, thing+" result")
+		case *ast.GenDecl:
+			if v.Tok == token.IMPORT {
+				return true
+			}
+			var thing string
+			switch v.Tok {
+			case token.CONST:
+				thing = "const"
+			case token.TYPE:
+				thing = "type"
+			case token.VAR:
+				thing = "var"
+			}
+			for _, spec := range v.Specs {
+				switch s := spec.(type) {
+				case *ast.TypeSpec:
+					check(s.Name, thing)
+				case *ast.ValueSpec:
+					for _, id := range s.Names {
+						check(id, thing)
+					}
+				}
+			}
+		case *ast.InterfaceType:
+			// Do not check interface method names.
+			// They are often constrainted by the method names of concrete types.
+			for _, x := range v.Methods.List {
+				ft, ok := x.Type.(*ast.FuncType)
+				if !ok { // might be an embedded interface name
+					continue
+				}
+				checkList(ft.Params, "interface method parameter")
+				checkList(ft.Results, "interface method result")
+			}
+		case *ast.RangeStmt:
+			if v.Tok == token.ASSIGN {
+				return true
+			}
+			if id, ok := v.Key.(*ast.Ident); ok {
+				check(id, "range var")
+			}
+			if id, ok := v.Value.(*ast.Ident); ok {
+				check(id, "range var")
+			}
+		case *ast.StructType:
+			for _, f := range v.Fields.List {
+				for _, id := range f.Names {
+					check(id, "struct field")
+				}
+			}
+		}
+		return true
+	})
+}
+
+// lintName returns a different name if it should be different.
+func lintName(name string) (should string) {
+	// Fast path for simple cases: "_" and all lowercase.
+	if name == "_" {
+		return name
+	}
+	allLower := true
+	for _, r := range name {
+		if !unicode.IsLower(r) {
+			allLower = false
+			break
+		}
+	}
+	if allLower {
+		return name
+	}
+
+	// Split camelCase at any lower->upper transition, and split on underscores.
+	// Check each word for common initialisms.
+	runes := []rune(name)
+	w, i := 0, 0 // index of start of word, scan
+	for i+1 <= len(runes) {
+		eow := false // whether we hit the end of a word
+		if i+1 == len(runes) {
+			eow = true
+		} else if runes[i+1] == '_' {
+			// underscore; shift the remainder forward over any run of underscores
+			eow = true
+			n := 1
+			for i+n+1 < len(runes) && runes[i+n+1] == '_' {
+				n++
+			}
+
+			// Leave at most one underscore if the underscore is between two digits
+			if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
+				n--
+			}
+
+			copy(runes[i+1:], runes[i+n+1:])
+			runes = runes[:len(runes)-n]
+		} else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
+			// lower->non-lower
+			eow = true
+		}
+		i++
+		if !eow {
+			continue
+		}
+
+		// [w,i) is a word.
+		word := string(runes[w:i])
+		if u := strings.ToUpper(word); commonInitialisms[u] {
+			// Keep consistent case, which is lowercase only at the start.
+			if w == 0 && unicode.IsLower(runes[w]) {
+				u = strings.ToLower(u)
+			}
+			// All the common initialisms are ASCII,
+			// so we can replace the bytes exactly.
+			copy(runes[w:], []rune(u))
+		} else if w > 0 && strings.ToLower(word) == word {
+			// already all lowercase, and not the first word, so uppercase the first character.
+			runes[w] = unicode.ToUpper(runes[w])
+		}
+		w = i
+	}
+	return string(runes)
+}
+
+// commonInitialisms is a set of common initialisms.
+// Only add entries that are highly unlikely to be non-initialisms.
+// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
+var commonInitialisms = map[string]bool{
+	"ACL":   true,
+	"API":   true,
+	"ASCII": true,
+	"CPU":   true,
+	"CSS":   true,
+	"DNS":   true,
+	"EOF":   true,
+	"GUID":  true,
+	"HTML":  true,
+	"HTTP":  true,
+	"HTTPS": true,
+	"ID":    true,
+	"IP":    true,
+	"JSON":  true,
+	"LHS":   true,
+	"QPS":   true,
+	"RAM":   true,
+	"RHS":   true,
+	"RPC":   true,
+	"SLA":   true,
+	"SMTP":  true,
+	"SQL":   true,
+	"SSH":   true,
+	"TCP":   true,
+	"TLS":   true,
+	"TTL":   true,
+	"UDP":   true,
+	"UI":    true,
+	"UID":   true,
+	"UUID":  true,
+	"URI":   true,
+	"URL":   true,
+	"UTF8":  true,
+	"VM":    true,
+	"XML":   true,
+	"XMPP":  true,
+	"XSRF":  true,
+	"XSS":   true,
+}
+
+// lintTypeDoc examines the doc comment on a type.
+// It complains if they are missing from an exported type,
+// or if they are not of the standard form.
+func (f *file) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) {
+	if !ast.IsExported(t.Name.Name) {
+		return
+	}
+	if doc == nil {
+		f.errorf(t, 1, link(docCommentsLink), category("comments"), "exported type %v should have comment or be unexported", t.Name)
+		return
+	}
+
+	s := doc.Text()
+	articles := [...]string{"A", "An", "The"}
+	for _, a := range articles {
+		if strings.HasPrefix(s, a+" ") {
+			s = s[len(a)+1:]
+			break
+		}
+	}
+	if !strings.HasPrefix(s, t.Name.Name+" ") {
+		f.errorf(doc, 1, link(docCommentsLink), category("comments"), `comment on exported type %v should be of the form "%v ..." (with optional leading article)`, t.Name, t.Name)
+	}
+}
+
+var commonMethods = map[string]bool{
+	"Error":     true,
+	"Read":      true,
+	"ServeHTTP": true,
+	"String":    true,
+	"Write":     true,
+}
+
+// lintFuncDoc examines doc comments on functions and methods.
+// It complains if they are missing, or not of the right form.
+// It has specific exclusions for well-known methods (see commonMethods above).
+func (f *file) lintFuncDoc(fn *ast.FuncDecl) {
+	if !ast.IsExported(fn.Name.Name) {
+		// func is unexported
+		return
+	}
+	kind := "function"
+	name := fn.Name.Name
+	if fn.Recv != nil && len(fn.Recv.List) > 0 {
+		// method
+		kind = "method"
+		recv := receiverType(fn)
+		if !ast.IsExported(recv) {
+			// receiver is unexported
+			return
+		}
+		if commonMethods[name] {
+			return
+		}
+		switch name {
+		case "Len", "Less", "Swap":
+			if f.pkg.sortable[recv] {
+				return
+			}
+		}
+		name = recv + "." + name
+	}
+	if fn.Doc == nil {
+		f.errorf(fn, 1, link(docCommentsLink), category("comments"), "exported %s %s should have comment or be unexported", kind, name)
+		return
+	}
+	s := fn.Doc.Text()
+	prefix := fn.Name.Name + " "
+	if !strings.HasPrefix(s, prefix) {
+		f.errorf(fn.Doc, 1, link(docCommentsLink), category("comments"), `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
+	}
+}
+
+// lintValueSpecDoc examines package-global variables and constants.
+// It complains if they are not individually declared,
+// or if they are not suitably documented in the right form (unless they are in a block that is commented).
+func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) {
+	kind := "var"
+	if gd.Tok == token.CONST {
+		kind = "const"
+	}
+
+	if len(vs.Names) > 1 {
+		// Check that none are exported except for the first.
+		for _, n := range vs.Names[1:] {
+			if ast.IsExported(n.Name) {
+				f.errorf(vs, 1, category("comments"), "exported %s %s should have its own declaration", kind, n.Name)
+				return
+			}
+		}
+	}
+
+	// Only one name.
+	name := vs.Names[0].Name
+	if !ast.IsExported(name) {
+		return
+	}
+
+	if vs.Doc == nil && gd.Doc == nil {
+		if genDeclMissingComments[gd] {
+			return
+		}
+		block := ""
+		if kind == "const" && gd.Lparen.IsValid() {
+			block = " (or a comment on this block)"
+		}
+		f.errorf(vs, 1, link(docCommentsLink), category("comments"), "exported %s %s should have comment%s or be unexported", kind, name, block)
+		genDeclMissingComments[gd] = true
+		return
+	}
+	// If this GenDecl has parens and a comment, we don't check its comment form.
+	if gd.Lparen.IsValid() && gd.Doc != nil {
+		return
+	}
+	// The relevant text to check will be on either vs.Doc or gd.Doc.
+	// Use vs.Doc preferentially.
+	doc := vs.Doc
+	if doc == nil {
+		doc = gd.Doc
+	}
+	prefix := name + " "
+	if !strings.HasPrefix(doc.Text(), prefix) {
+		f.errorf(doc, 1, link(docCommentsLink), category("comments"), `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
+	}
+}
+
+func (f *file) checkStutter(id *ast.Ident, thing string) {
+	pkg, name := f.f.Name.Name, id.Name
+	if !ast.IsExported(name) {
+		// unexported name
+		return
+	}
+	// A name stutters if the package name is a strict prefix
+	// and the next character of the name starts a new word.
+	if len(name) <= len(pkg) {
+		// name is too short to stutter.
+		// This permits the name to be the same as the package name.
+		return
+	}
+	if !strings.EqualFold(pkg, name[:len(pkg)]) {
+		return
+	}
+	// We can assume the name is well-formed UTF-8.
+	// If the next rune after the package name is uppercase or an underscore
+	// the it's starting a new word and thus this name stutters.
+	rem := name[len(pkg):]
+	if next, _ := utf8.DecodeRuneInString(rem); next == '_' || unicode.IsUpper(next) {
+		f.errorf(id, 0.8, link(styleGuideBase+"#package-names"), category("naming"), "%s name will be used as %s.%s by other packages, and that stutters; consider calling this %s", thing, pkg, name, rem)
+	}
+}
+
+// zeroLiteral is a set of ast.BasicLit values that are zero values.
+// It is not exhaustive.
+var zeroLiteral = map[string]bool{
+	"false": true, // bool
+	// runes
+	`'\x00'`: true,
+	`'\000'`: true,
+	// strings
+	`""`: true,
+	"``": true,
+	// numerics
+	"0":   true,
+	"0.":  true,
+	"0.0": true,
+	"0i":  true,
+}
+
+// lintVarDecls examines variable declarations. It complains about declarations with
+// redundant LHS types that can be inferred from the RHS.
+func (f *file) lintVarDecls() {
+	var lastGen *ast.GenDecl // last GenDecl entered.
+
+	f.walk(func(node ast.Node) bool {
+		switch v := node.(type) {
+		case *ast.GenDecl:
+			if v.Tok != token.CONST && v.Tok != token.VAR {
+				return false
+			}
+			lastGen = v
+			return true
+		case *ast.ValueSpec:
+			if lastGen.Tok == token.CONST {
+				return false
+			}
+			if len(v.Names) > 1 || v.Type == nil || len(v.Values) == 0 {
+				return false
+			}
+			rhs := v.Values[0]
+			// An underscore var appears in a common idiom for compile-time interface satisfaction,
+			// as in "var _ Interface = (*Concrete)(nil)".
+			if isIdent(v.Names[0], "_") {
+				return false
+			}
+			// If the RHS is a zero value, suggest dropping it.
+			zero := false
+			if lit, ok := rhs.(*ast.BasicLit); ok {
+				zero = zeroLiteral[lit.Value]
+			} else if isIdent(rhs, "nil") {
+				zero = true
+			}
+			if zero {
+				f.errorf(rhs, 0.9, category("zero-value"), "should drop = %s from declaration of var %s; it is the zero value", f.render(rhs), v.Names[0])
+				return false
+			}
+			lhsTyp := f.pkg.typeOf(v.Type)
+			rhsTyp := f.pkg.typeOf(rhs)
+
+			if !validType(lhsTyp) || !validType(rhsTyp) {
+				// Type checking failed (often due to missing imports).
+				return false
+			}
+
+			if !types.Identical(lhsTyp, rhsTyp) {
+				// Assignment to a different type is not redundant.
+				return false
+			}
+
+			// The next three conditions are for suppressing the warning in situations
+			// where we were unable to typecheck.
+
+			// If the LHS type is an interface, don't warn, since it is probably a
+			// concrete type on the RHS. Note that our feeble lexical check here
+			// will only pick up interface{} and other literal interface types;
+			// that covers most of the cases we care to exclude right now.
+			if _, ok := v.Type.(*ast.InterfaceType); ok {
+				return false
+			}
+			// If the RHS is an untyped const, only warn if the LHS type is its default type.
+			if defType, ok := f.isUntypedConst(rhs); ok && !isIdent(v.Type, defType) {
+				return false
+			}
+
+			f.errorf(v.Type, 0.8, category("type-inference"), "should omit type %s from declaration of var %s; it will be inferred from the right-hand side", f.render(v.Type), v.Names[0])
+			return false
+		}
+		return true
+	})
+}
+
+func validType(T types.Type) bool {
+	return T != nil &&
+		T != types.Typ[types.Invalid] &&
+		!strings.Contains(T.String(), "invalid type") // good but not foolproof
+}
+
+// lintElses examines else blocks. It complains about any else block whose if block ends in a return.
+func (f *file) lintElses() {
+	// We don't want to flag if { } else if { } else { } constructions.
+	// They will appear as an IfStmt whose Else field is also an IfStmt.
+	// Record such a node so we ignore it when we visit it.
+	ignore := make(map[*ast.IfStmt]bool)
+
+	f.walk(func(node ast.Node) bool {
+		ifStmt, ok := node.(*ast.IfStmt)
+		if !ok || ifStmt.Else == nil {
+			return true
+		}
+		if elseif, ok := ifStmt.Else.(*ast.IfStmt); ok {
+			ignore[elseif] = true
+			return true
+		}
+		if ignore[ifStmt] {
+			return true
+		}
+		if _, ok := ifStmt.Else.(*ast.BlockStmt); !ok {
+			// only care about elses without conditions
+			return true
+		}
+		if len(ifStmt.Body.List) == 0 {
+			return true
+		}
+		shortDecl := false // does the if statement have a ":=" initialization statement?
+		if ifStmt.Init != nil {
+			if as, ok := ifStmt.Init.(*ast.AssignStmt); ok && as.Tok == token.DEFINE {
+				shortDecl = true
+			}
+		}
+		lastStmt := ifStmt.Body.List[len(ifStmt.Body.List)-1]
+		if _, ok := lastStmt.(*ast.ReturnStmt); ok {
+			extra := ""
+			if shortDecl {
+				extra = " (move short variable declaration to its own line if necessary)"
+			}
+			f.errorf(ifStmt.Else, 1, link(styleGuideBase+"#indent-error-flow"), category("indent"), "if block ends with a return statement, so drop this else and outdent its block"+extra)
+		}
+		return true
+	})
+}
+
+// lintRanges examines range clauses. It complains about redundant constructions.
+func (f *file) lintRanges() {
+	f.walk(func(node ast.Node) bool {
+		rs, ok := node.(*ast.RangeStmt)
+		if !ok {
+			return true
+		}
+
+		if isIdent(rs.Key, "_") && (rs.Value == nil || isIdent(rs.Value, "_")) {
+			p := f.errorf(rs.Key, 1, category("range-loop"), "should omit values from range; this loop is equivalent to `for range ...`")
+
+			newRS := *rs // shallow copy
+			newRS.Value = nil
+			newRS.Key = nil
+			p.ReplacementLine = f.firstLineOf(&newRS, rs)
+
+			return true
+		}
+
+		if isIdent(rs.Value, "_") {
+			p := f.errorf(rs.Value, 1, category("range-loop"), "should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", f.render(rs.Key), rs.Tok)
+
+			newRS := *rs // shallow copy
+			newRS.Value = nil
+			p.ReplacementLine = f.firstLineOf(&newRS, rs)
+		}
+
+		return true
+	})
+}
+
+// lintErrorf examines errors.New and testing.Error calls. It complains if its only argument is an fmt.Sprintf invocation.
+func (f *file) lintErrorf() {
+	f.walk(func(node ast.Node) bool {
+		ce, ok := node.(*ast.CallExpr)
+		if !ok || len(ce.Args) != 1 {
+			return true
+		}
+		isErrorsNew := isPkgDot(ce.Fun, "errors", "New")
+		var isTestingError bool
+		se, ok := ce.Fun.(*ast.SelectorExpr)
+		if ok && se.Sel.Name == "Error" {
+			if typ := f.pkg.typeOf(se.X); typ != nil {
+				isTestingError = typ.String() == "*testing.T"
+			}
+		}
+		if !isErrorsNew && !isTestingError {
+			return true
+		}
+		if !f.imports("errors") {
+			return true
+		}
+		arg := ce.Args[0]
+		ce, ok = arg.(*ast.CallExpr)
+		if !ok || !isPkgDot(ce.Fun, "fmt", "Sprintf") {
+			return true
+		}
+		errorfPrefix := "fmt"
+		if isTestingError {
+			errorfPrefix = f.render(se.X)
+		}
+		p := f.errorf(node, 1, category("errors"), "should replace %s(fmt.Sprintf(...)) with %s.Errorf(...)", f.render(se), errorfPrefix)
+
+		m := f.srcLineWithMatch(ce, `^(.*)`+f.render(se)+`\(fmt\.Sprintf\((.*)\)\)(.*)$`)
+		if m != nil {
+			p.ReplacementLine = m[1] + errorfPrefix + ".Errorf(" + m[2] + ")" + m[3]
+		}
+
+		return true
+	})
+}
+
+// lintErrors examines global error vars. It complains if they aren't named in the standard way.
+func (f *file) lintErrors() {
+	for _, decl := range f.f.Decls {
+		gd, ok := decl.(*ast.GenDecl)
+		if !ok || gd.Tok != token.VAR {
+			continue
+		}
+		for _, spec := range gd.Specs {
+			spec := spec.(*ast.ValueSpec)
+			if len(spec.Names) != 1 || len(spec.Values) != 1 {
+				continue
+			}
+			ce, ok := spec.Values[0].(*ast.CallExpr)
+			if !ok {
+				continue
+			}
+			if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") {
+				continue
+			}
+
+			id := spec.Names[0]
+			prefix := "err"
+			if id.IsExported() {
+				prefix = "Err"
+			}
+			if !strings.HasPrefix(id.Name, prefix) {
+				f.errorf(id, 0.9, category("naming"), "error var %s should have name of the form %sFoo", id.Name, prefix)
+			}
+		}
+	}
+}
+
+func lintErrorString(s string) (isClean bool, conf float64) {
+	const basicConfidence = 0.8
+	const capConfidence = basicConfidence - 0.2
+	first, firstN := utf8.DecodeRuneInString(s)
+	last, _ := utf8.DecodeLastRuneInString(s)
+	if last == '.' || last == ':' || last == '!' || last == '\n' {
+		return false, basicConfidence
+	}
+	if unicode.IsUpper(first) {
+		// People use proper nouns and exported Go identifiers in error strings,
+		// so decrease the confidence of warnings for capitalization.
+		if len(s) <= firstN {
+			return false, capConfidence
+		}
+		// Flag strings starting with something that doesn't look like an initialism.
+		if second, _ := utf8.DecodeRuneInString(s[firstN:]); !unicode.IsUpper(second) {
+			return false, capConfidence
+		}
+	}
+	return true, 0
+}
+
+// lintErrorStrings examines error strings.
+// It complains if they are capitalized or end in punctuation or a newline.
+func (f *file) lintErrorStrings() {
+	f.walk(func(node ast.Node) bool {
+		ce, ok := node.(*ast.CallExpr)
+		if !ok {
+			return true
+		}
+		if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") {
+			return true
+		}
+		if len(ce.Args) < 1 {
+			return true
+		}
+		str, ok := ce.Args[0].(*ast.BasicLit)
+		if !ok || str.Kind != token.STRING {
+			return true
+		}
+		s, _ := strconv.Unquote(str.Value) // can assume well-formed Go
+		if s == "" {
+			return true
+		}
+		clean, conf := lintErrorString(s)
+		if clean {
+			return true
+		}
+
+		f.errorf(str, conf, link(styleGuideBase+"#error-strings"), category("errors"),
+			"error strings should not be capitalized or end with punctuation or a newline")
+		return true
+	})
+}
+
+// lintReceiverNames examines receiver names. It complains about inconsistent
+// names used for the same type and names such as "this".
+func (f *file) lintReceiverNames() {
+	typeReceiver := map[string]string{}
+	f.walk(func(n ast.Node) bool {
+		fn, ok := n.(*ast.FuncDecl)
+		if !ok || fn.Recv == nil || len(fn.Recv.List) == 0 {
+			return true
+		}
+		names := fn.Recv.List[0].Names
+		if len(names) < 1 {
+			return true
+		}
+		name := names[0].Name
+		const ref = styleGuideBase + "#receiver-names"
+		if name == "_" {
+			f.errorf(n, 1, link(ref), category("naming"), `receiver name should not be an underscore, omit the name if it is unused`)
+			return true
+		}
+		if name == "this" || name == "self" {
+			f.errorf(n, 1, link(ref), category("naming"), `receiver name should be a reflection of its identity; don't use generic names such as "this" or "self"`)
+			return true
+		}
+		recv := receiverType(fn)
+		if prev, ok := typeReceiver[recv]; ok && prev != name {
+			f.errorf(n, 1, link(ref), category("naming"), "receiver name %s should be consistent with previous receiver name %s for %s", name, prev, recv)
+			return true
+		}
+		typeReceiver[recv] = name
+		return true
+	})
+}
+
+// lintIncDec examines statements that increment or decrement a variable.
+// It complains if they don't use x++ or x--.
+func (f *file) lintIncDec() {
+	f.walk(func(n ast.Node) bool {
+		as, ok := n.(*ast.AssignStmt)
+		if !ok {
+			return true
+		}
+		if len(as.Lhs) != 1 {
+			return true
+		}
+		if !isOne(as.Rhs[0]) {
+			return true
+		}
+		var suffix string
+		switch as.Tok {
+		case token.ADD_ASSIGN:
+			suffix = "++"
+		case token.SUB_ASSIGN:
+			suffix = "--"
+		default:
+			return true
+		}
+		f.errorf(as, 0.8, category("unary-op"), "should replace %s with %s%s", f.render(as), f.render(as.Lhs[0]), suffix)
+		return true
+	})
+}
+
+// lintErrorReturn examines function declarations that return an error.
+// It complains if the error isn't the last parameter.
+func (f *file) lintErrorReturn() {
+	f.walk(func(n ast.Node) bool {
+		fn, ok := n.(*ast.FuncDecl)
+		if !ok || fn.Type.Results == nil {
+			return true
+		}
+		ret := fn.Type.Results.List
+		if len(ret) <= 1 {
+			return true
+		}
+		if isIdent(ret[len(ret)-1].Type, "error") {
+			return true
+		}
+		// An error return parameter should be the last parameter.
+		// Flag any error parameters found before the last.
+		for _, r := range ret[:len(ret)-1] {
+			if isIdent(r.Type, "error") {
+				f.errorf(fn, 0.9, category("arg-order"), "error should be the last type when returning multiple items")
+				break // only flag one
+			}
+		}
+		return true
+	})
+}
+
+// lintUnexportedReturn examines exported function declarations.
+// It complains if any return an unexported type.
+func (f *file) lintUnexportedReturn() {
+	f.walk(func(n ast.Node) bool {
+		fn, ok := n.(*ast.FuncDecl)
+		if !ok {
+			return true
+		}
+		if fn.Type.Results == nil {
+			return false
+		}
+		if !fn.Name.IsExported() {
+			return false
+		}
+		thing := "func"
+		if fn.Recv != nil && len(fn.Recv.List) > 0 {
+			thing = "method"
+			if !ast.IsExported(receiverType(fn)) {
+				// Don't report exported methods of unexported types,
+				// such as private implementations of sort.Interface.
+				return false
+			}
+		}
+		for _, ret := range fn.Type.Results.List {
+			typ := f.pkg.typeOf(ret.Type)
+			if exportedType(typ) {
+				continue
+			}
+			f.errorf(ret.Type, 0.8, category("unexported-type-in-api"),
+				"exported %s %s returns unexported type %s, which can be annoying to use",
+				thing, fn.Name.Name, typ)
+			break // only flag one
+		}
+		return false
+	})
+}
+
+// exportedType reports whether typ is an exported type.
+// It is imprecise, and will err on the side of returning true,
+// such as for composite types.
+func exportedType(typ types.Type) bool {
+	switch T := typ.(type) {
+	case *types.Named:
+		// Builtin types have no package.
+		return T.Obj().Pkg() == nil || T.Obj().Exported()
+	case *types.Map:
+		return exportedType(T.Key()) && exportedType(T.Elem())
+	case interface {
+		Elem() types.Type
+	}: // array, slice, pointer, chan
+		return exportedType(T.Elem())
+	}
+	// Be conservative about other types, such as struct, interface, etc.
+	return true
+}
+
+// timeSuffixes is a list of name suffixes that imply a time unit.
+// This is not an exhaustive list.
+var timeSuffixes = []string{
+	"Sec", "Secs", "Seconds",
+	"Msec", "Msecs",
+	"Milli", "Millis", "Milliseconds",
+	"Usec", "Usecs", "Microseconds",
+	"MS", "Ms",
+}
+
+func (f *file) lintTimeNames() {
+	f.walk(func(node ast.Node) bool {
+		v, ok := node.(*ast.ValueSpec)
+		if !ok {
+			return true
+		}
+		for _, name := range v.Names {
+			origTyp := f.pkg.typeOf(name)
+			// Look for time.Duration or *time.Duration;
+			// the latter is common when using flag.Duration.
+			typ := origTyp
+			if pt, ok := typ.(*types.Pointer); ok {
+				typ = pt.Elem()
+			}
+			if !f.pkg.isNamedType(typ, "time", "Duration") {
+				continue
+			}
+			suffix := ""
+			for _, suf := range timeSuffixes {
+				if strings.HasSuffix(name.Name, suf) {
+					suffix = suf
+					break
+				}
+			}
+			if suffix == "" {
+				continue
+			}
+			f.errorf(v, 0.9, category("time"), "var %s is of type %v; don't use unit-specific suffix %q", name.Name, origTyp, suffix)
+		}
+		return true
+	})
+}
+
+// lintContextKeyTypes checks for call expressions to context.WithValue with
+// basic types used for the key argument.
+// See: https://golang.org/issue/17293
+func (f *file) lintContextKeyTypes() {
+	f.walk(func(node ast.Node) bool {
+		switch node := node.(type) {
+		case *ast.CallExpr:
+			f.checkContextKeyType(node)
+		}
+
+		return true
+	})
+}
+
+// checkContextKeyType reports an error if the call expression calls
+// context.WithValue with a key argument of basic type.
+func (f *file) checkContextKeyType(x *ast.CallExpr) {
+	sel, ok := x.Fun.(*ast.SelectorExpr)
+	if !ok {
+		return
+	}
+	pkg, ok := sel.X.(*ast.Ident)
+	if !ok || pkg.Name != "context" {
+		return
+	}
+	if sel.Sel.Name != "WithValue" {
+		return
+	}
+
+	// key is second argument to context.WithValue
+	if len(x.Args) != 3 {
+		return
+	}
+	key := f.pkg.typesInfo.Types[x.Args[1]]
+
+	if ktyp, ok := key.Type.(*types.Basic); ok && ktyp.Kind() != types.Invalid {
+		f.errorf(x, 1.0, category("context"), fmt.Sprintf("should not use basic type %s as key in context.WithValue", key.Type))
+	}
+}
+
+// lintContextArgs examines function declarations that contain an
+// argument with a type of context.Context
+// It complains if that argument isn't the first parameter.
+func (f *file) lintContextArgs() {
+	f.walk(func(n ast.Node) bool {
+		fn, ok := n.(*ast.FuncDecl)
+		if !ok || len(fn.Type.Params.List) <= 1 {
+			return true
+		}
+		// A context.Context should be the first parameter of a function.
+		// Flag any that show up after the first.
+		for _, arg := range fn.Type.Params.List[1:] {
+			if isPkgDot(arg.Type, "context", "Context") {
+				f.errorf(fn, 0.9, link("https://golang.org/pkg/context/"), category("arg-order"), "context.Context should be the first parameter of a function")
+				break // only flag one
+			}
+		}
+		return true
+	})
+}
+
+// containsComments returns whether the interval [start, end) contains any
+// comments without "// MATCH " prefix.
+func (f *file) containsComments(start, end token.Pos) bool {
+	for _, cgroup := range f.f.Comments {
+		comments := cgroup.List
+		if comments[0].Slash >= end {
+			// All comments starting with this group are after end pos.
+			return false
+		}
+		if comments[len(comments)-1].Slash < start {
+			// Comments group ends before start pos.
+			continue
+		}
+		for _, c := range comments {
+			if start <= c.Slash && c.Slash < end && !strings.HasPrefix(c.Text, "// MATCH ") {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// receiverType returns the named type of the method receiver, sans "*",
+// or "invalid-type" if fn.Recv is ill formed.
+func receiverType(fn *ast.FuncDecl) string {
+	switch e := fn.Recv.List[0].Type.(type) {
+	case *ast.Ident:
+		return e.Name
+	case *ast.StarExpr:
+		if id, ok := e.X.(*ast.Ident); ok {
+			return id.Name
+		}
+	}
+	// The parser accepts much more than just the legal forms.
+	return "invalid-type"
+}
+
+func (f *file) walk(fn func(ast.Node) bool) {
+	ast.Walk(walker(fn), f.f)
+}
+
+func (f *file) render(x interface{}) string {
+	var buf bytes.Buffer
+	if err := printer.Fprint(&buf, f.fset, x); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func (f *file) debugRender(x interface{}) string {
+	var buf bytes.Buffer
+	if err := ast.Fprint(&buf, f.fset, x, nil); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+// walker adapts a function to satisfy the ast.Visitor interface.
+// The function return whether the walk should proceed into the node's children.
+type walker func(ast.Node) bool
+
+func (w walker) Visit(node ast.Node) ast.Visitor {
+	if w(node) {
+		return w
+	}
+	return nil
+}
+
+func isIdent(expr ast.Expr, ident string) bool {
+	id, ok := expr.(*ast.Ident)
+	return ok && id.Name == ident
+}
+
+// isBlank returns whether id is the blank identifier "_".
+// If id == nil, the answer is false.
+func isBlank(id *ast.Ident) bool { return id != nil && id.Name == "_" }
+
+func isPkgDot(expr ast.Expr, pkg, name string) bool {
+	sel, ok := expr.(*ast.SelectorExpr)
+	return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
+}
+
+func isOne(expr ast.Expr) bool {
+	lit, ok := expr.(*ast.BasicLit)
+	return ok && lit.Kind == token.INT && lit.Value == "1"
+}
+
+func isCgoExported(f *ast.FuncDecl) bool {
+	if f.Recv != nil || f.Doc == nil {
+		return false
+	}
+
+	cgoExport := regexp.MustCompile(fmt.Sprintf("(?m)^//export %s$", regexp.QuoteMeta(f.Name.Name)))
+	for _, c := range f.Doc.List {
+		if cgoExport.MatchString(c.Text) {
+			return true
+		}
+	}
+	return false
+}
+
+var basicTypeKinds = map[types.BasicKind]string{
+	types.UntypedBool:    "bool",
+	types.UntypedInt:     "int",
+	types.UntypedRune:    "rune",
+	types.UntypedFloat:   "float64",
+	types.UntypedComplex: "complex128",
+	types.UntypedString:  "string",
+}
+
+// isUntypedConst reports whether expr is an untyped constant,
+// and indicates what its default type is.
+// scope may be nil.
+func (f *file) isUntypedConst(expr ast.Expr) (defType string, ok bool) {
+	// Re-evaluate expr outside of its context to see if it's untyped.
+	// (An expr evaluated within, for example, an assignment context will get the type of the LHS.)
+	exprStr := f.render(expr)
+	tv, err := types.Eval(f.fset, f.pkg.typesPkg, expr.Pos(), exprStr)
+	if err != nil {
+		return "", false
+	}
+	if b, ok := tv.Type.(*types.Basic); ok {
+		if dt, ok := basicTypeKinds[b.Kind()]; ok {
+			return dt, true
+		}
+	}
+
+	return "", false
+}
+
+// firstLineOf renders the given node and returns its first line.
+// It will also match the indentation of another node.
+func (f *file) firstLineOf(node, match ast.Node) string {
+	line := f.render(node)
+	if i := strings.Index(line, "\n"); i >= 0 {
+		line = line[:i]
+	}
+	return f.indentOf(match) + line
+}
+
+func (f *file) indentOf(node ast.Node) string {
+	line := srcLine(f.src, f.fset.Position(node.Pos()))
+	for i, r := range line {
+		switch r {
+		case ' ', '\t':
+		default:
+			return line[:i]
+		}
+	}
+	return line // unusual or empty line
+}
+
+func (f *file) srcLineWithMatch(node ast.Node, pattern string) (m []string) {
+	line := srcLine(f.src, f.fset.Position(node.Pos()))
+	line = strings.TrimSuffix(line, "\n")
+	rx := regexp.MustCompile(pattern)
+	return rx.FindStringSubmatch(line)
+}
+
+// imports returns true if the current file imports the specified package path.
+func (f *file) imports(importPath string) bool {
+	all := astutil.Imports(f.fset, f.f)
+	for _, p := range all {
+		for _, i := range p {
+			uq, err := strconv.Unquote(i.Path.Value)
+			if err == nil && importPath == uq {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// srcLine returns the complete line at p, including the terminating newline.
+func srcLine(src []byte, p token.Position) string {
+	// Run to end of line in both directions if not at line start/end.
+	lo, hi := p.Offset, p.Offset+1
+	for lo > 0 && src[lo-1] != '\n' {
+		lo--
+	}
+	for hi < len(src) && src[hi-1] != '\n' {
+		hi++
+	}
+	return string(src[lo:hi])
+}
diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..6a66aea5eafe0ca6a688840c47219556c552488e
--- /dev/null
+++ b/vendor/golang.org/x/tools/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS
new file mode 100644
index 0000000000000000000000000000000000000000..733099041f84fa1e58611ab2e11af51c1f26d1d2
--- /dev/null
+++ b/vendor/golang.org/x/tools/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
new file mode 100644
index 0000000000000000000000000000000000000000..6b7052b892ca07ba23a1eddd35645d50992dc42c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
@@ -0,0 +1,627 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+// This file defines utilities for working with source positions.
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"sort"
+)
+
+// PathEnclosingInterval returns the node that encloses the source
+// interval [start, end), and all its ancestors up to the AST root.
+//
+// The definition of "enclosing" used by this function considers
+// additional whitespace abutting a node to be enclosed by it.
+// In this example:
+//
+//              z := x + y // add them
+//                   <-A->
+//                  <----B----->
+//
+// the ast.BinaryExpr(+) node is considered to enclose interval B
+// even though its [Pos()..End()) is actually only interval A.
+// This behaviour makes user interfaces more tolerant of imperfect
+// input.
+//
+// This function treats tokens as nodes, though they are not included
+// in the result. e.g. PathEnclosingInterval("+") returns the
+// enclosing ast.BinaryExpr("x + y").
+//
+// If start==end, the 1-char interval following start is used instead.
+//
+// The 'exact' result is true if the interval contains only path[0]
+// and perhaps some adjacent whitespace.  It is false if the interval
+// overlaps multiple children of path[0], or if it contains only
+// interior whitespace of path[0].
+// In this example:
+//
+//              z := x + y // add them
+//                <--C-->     <---E-->
+//                  ^
+//                  D
+//
+// intervals C, D and E are inexact.  C is contained by the
+// z-assignment statement, because it spans three of its children (:=,
+// x, +).  So too is the 1-char interval D, because it contains only
+// interior whitespace of the assignment.  E is considered interior
+// whitespace of the BlockStmt containing the assignment.
+//
+// Precondition: [start, end) both lie within the same file as root.
+// TODO(adonovan): return (nil, false) in this case and remove precond.
+// Requires FileSet; see loader.tokenFileContainsPos.
+//
+// Postcondition: path is never nil; it always contains at least 'root'.
+//
+func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
+	// fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
+
+	// Precondition: node.[Pos..End) and adjoining whitespace contain [start, end).
+	var visit func(node ast.Node) bool
+	visit = func(node ast.Node) bool {
+		path = append(path, node)
+
+		nodePos := node.Pos()
+		nodeEnd := node.End()
+
+		// fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging
+
+		// Intersect [start, end) with interval of node.
+		if start < nodePos {
+			start = nodePos
+		}
+		if end > nodeEnd {
+			end = nodeEnd
+		}
+
+		// Find sole child that contains [start, end).
+		children := childrenOf(node)
+		l := len(children)
+		for i, child := range children {
+			// [childPos, childEnd) is unaugmented interval of child.
+			childPos := child.Pos()
+			childEnd := child.End()
+
+			// [augPos, augEnd) is whitespace-augmented interval of child.
+			augPos := childPos
+			augEnd := childEnd
+			if i > 0 {
+				augPos = children[i-1].End() // start of preceding whitespace
+			}
+			if i < l-1 {
+				nextChildPos := children[i+1].Pos()
+				// Does [start, end) lie between child and next child?
+				if start >= augEnd && end <= nextChildPos {
+					return false // inexact match
+				}
+				augEnd = nextChildPos // end of following whitespace
+			}
+
+			// fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n",
+			// 	i, augPos, augEnd, start, end) // debugging
+
+			// Does augmented child strictly contain [start, end)?
+			if augPos <= start && end <= augEnd {
+				_, isToken := child.(tokenNode)
+				return isToken || visit(child)
+			}
+
+			// Does [start, end) overlap multiple children?
+			// i.e. left-augmented child contains start
+			// but LR-augmented child does not contain end.
+			if start < childEnd && end > augEnd {
+				break
+			}
+		}
+
+		// No single child contained [start, end),
+		// so node is the result.  Is it exact?
+
+		// (It's tempting to put this condition before the
+		// child loop, but it gives the wrong result in the
+		// case where a node (e.g. ExprStmt) and its sole
+		// child have equal intervals.)
+		if start == nodePos && end == nodeEnd {
+			return true // exact match
+		}
+
+		return false // inexact: overlaps multiple children
+	}
+
+	if start > end {
+		start, end = end, start
+	}
+
+	if start < root.End() && end > root.Pos() {
+		if start == end {
+			end = start + 1 // empty interval => interval of size 1
+		}
+		exact = visit(root)
+
+		// Reverse the path:
+		for i, l := 0, len(path); i < l/2; i++ {
+			path[i], path[l-1-i] = path[l-1-i], path[i]
+		}
+	} else {
+		// Selection lies within whitespace preceding the
+		// first (or following the last) declaration in the file.
+		// The result nonetheless always includes the ast.File.
+		path = append(path, root)
+	}
+
+	return
+}
+
+// tokenNode is a dummy implementation of ast.Node for a single token.
+// They are used transiently by PathEnclosingInterval but never escape
+// this package.
+//
+type tokenNode struct {
+	pos token.Pos
+	end token.Pos
+}
+
+func (n tokenNode) Pos() token.Pos {
+	return n.pos
+}
+
+func (n tokenNode) End() token.Pos {
+	return n.end
+}
+
+func tok(pos token.Pos, len int) ast.Node {
+	return tokenNode{pos, pos + token.Pos(len)}
+}
+
+// childrenOf returns the direct non-nil children of ast.Node n.
+// It may include fake ast.Node implementations for bare tokens.
+// it is not safe to call (e.g.) ast.Walk on such nodes.
+//
+func childrenOf(n ast.Node) []ast.Node {
+	var children []ast.Node
+
+	// First add nodes for all true subtrees.
+	ast.Inspect(n, func(node ast.Node) bool {
+		if node == n { // push n
+			return true // recur
+		}
+		if node != nil { // push child
+			children = append(children, node)
+		}
+		return false // no recursion
+	})
+
+	// Then add fake Nodes for bare tokens.
+	switch n := n.(type) {
+	case *ast.ArrayType:
+		children = append(children,
+			tok(n.Lbrack, len("[")),
+			tok(n.Elt.End(), len("]")))
+
+	case *ast.AssignStmt:
+		children = append(children,
+			tok(n.TokPos, len(n.Tok.String())))
+
+	case *ast.BasicLit:
+		children = append(children,
+			tok(n.ValuePos, len(n.Value)))
+
+	case *ast.BinaryExpr:
+		children = append(children, tok(n.OpPos, len(n.Op.String())))
+
+	case *ast.BlockStmt:
+		children = append(children,
+			tok(n.Lbrace, len("{")),
+			tok(n.Rbrace, len("}")))
+
+	case *ast.BranchStmt:
+		children = append(children,
+			tok(n.TokPos, len(n.Tok.String())))
+
+	case *ast.CallExpr:
+		children = append(children,
+			tok(n.Lparen, len("(")),
+			tok(n.Rparen, len(")")))
+		if n.Ellipsis != 0 {
+			children = append(children, tok(n.Ellipsis, len("...")))
+		}
+
+	case *ast.CaseClause:
+		if n.List == nil {
+			children = append(children,
+				tok(n.Case, len("default")))
+		} else {
+			children = append(children,
+				tok(n.Case, len("case")))
+		}
+		children = append(children, tok(n.Colon, len(":")))
+
+	case *ast.ChanType:
+		switch n.Dir {
+		case ast.RECV:
+			children = append(children, tok(n.Begin, len("<-chan")))
+		case ast.SEND:
+			children = append(children, tok(n.Begin, len("chan<-")))
+		case ast.RECV | ast.SEND:
+			children = append(children, tok(n.Begin, len("chan")))
+		}
+
+	case *ast.CommClause:
+		if n.Comm == nil {
+			children = append(children,
+				tok(n.Case, len("default")))
+		} else {
+			children = append(children,
+				tok(n.Case, len("case")))
+		}
+		children = append(children, tok(n.Colon, len(":")))
+
+	case *ast.Comment:
+		// nop
+
+	case *ast.CommentGroup:
+		// nop
+
+	case *ast.CompositeLit:
+		children = append(children,
+			tok(n.Lbrace, len("{")),
+			tok(n.Rbrace, len("{")))
+
+	case *ast.DeclStmt:
+		// nop
+
+	case *ast.DeferStmt:
+		children = append(children,
+			tok(n.Defer, len("defer")))
+
+	case *ast.Ellipsis:
+		children = append(children,
+			tok(n.Ellipsis, len("...")))
+
+	case *ast.EmptyStmt:
+		// nop
+
+	case *ast.ExprStmt:
+		// nop
+
+	case *ast.Field:
+		// TODO(adonovan): Field.{Doc,Comment,Tag}?
+
+	case *ast.FieldList:
+		children = append(children,
+			tok(n.Opening, len("(")),
+			tok(n.Closing, len(")")))
+
+	case *ast.File:
+		// TODO test: Doc
+		children = append(children,
+			tok(n.Package, len("package")))
+
+	case *ast.ForStmt:
+		children = append(children,
+			tok(n.For, len("for")))
+
+	case *ast.FuncDecl:
+		// TODO(adonovan): FuncDecl.Comment?
+
+		// Uniquely, FuncDecl breaks the invariant that
+		// preorder traversal yields tokens in lexical order:
+		// in fact, FuncDecl.Recv precedes FuncDecl.Type.Func.
+		//
+		// As a workaround, we inline the case for FuncType
+		// here and order things correctly.
+		//
+		children = nil // discard ast.Walk(FuncDecl) info subtrees
+		children = append(children, tok(n.Type.Func, len("func")))
+		if n.Recv != nil {
+			children = append(children, n.Recv)
+		}
+		children = append(children, n.Name)
+		if n.Type.Params != nil {
+			children = append(children, n.Type.Params)
+		}
+		if n.Type.Results != nil {
+			children = append(children, n.Type.Results)
+		}
+		if n.Body != nil {
+			children = append(children, n.Body)
+		}
+
+	case *ast.FuncLit:
+		// nop
+
+	case *ast.FuncType:
+		if n.Func != 0 {
+			children = append(children,
+				tok(n.Func, len("func")))
+		}
+
+	case *ast.GenDecl:
+		children = append(children,
+			tok(n.TokPos, len(n.Tok.String())))
+		if n.Lparen != 0 {
+			children = append(children,
+				tok(n.Lparen, len("(")),
+				tok(n.Rparen, len(")")))
+		}
+
+	case *ast.GoStmt:
+		children = append(children,
+			tok(n.Go, len("go")))
+
+	case *ast.Ident:
+		children = append(children,
+			tok(n.NamePos, len(n.Name)))
+
+	case *ast.IfStmt:
+		children = append(children,
+			tok(n.If, len("if")))
+
+	case *ast.ImportSpec:
+		// TODO(adonovan): ImportSpec.{Doc,EndPos}?
+
+	case *ast.IncDecStmt:
+		children = append(children,
+			tok(n.TokPos, len(n.Tok.String())))
+
+	case *ast.IndexExpr:
+		children = append(children,
+			tok(n.Lbrack, len("{")),
+			tok(n.Rbrack, len("}")))
+
+	case *ast.InterfaceType:
+		children = append(children,
+			tok(n.Interface, len("interface")))
+
+	case *ast.KeyValueExpr:
+		children = append(children,
+			tok(n.Colon, len(":")))
+
+	case *ast.LabeledStmt:
+		children = append(children,
+			tok(n.Colon, len(":")))
+
+	case *ast.MapType:
+		children = append(children,
+			tok(n.Map, len("map")))
+
+	case *ast.ParenExpr:
+		children = append(children,
+			tok(n.Lparen, len("(")),
+			tok(n.Rparen, len(")")))
+
+	case *ast.RangeStmt:
+		children = append(children,
+			tok(n.For, len("for")),
+			tok(n.TokPos, len(n.Tok.String())))
+
+	case *ast.ReturnStmt:
+		children = append(children,
+			tok(n.Return, len("return")))
+
+	case *ast.SelectStmt:
+		children = append(children,
+			tok(n.Select, len("select")))
+
+	case *ast.SelectorExpr:
+		// nop
+
+	case *ast.SendStmt:
+		children = append(children,
+			tok(n.Arrow, len("<-")))
+
+	case *ast.SliceExpr:
+		children = append(children,
+			tok(n.Lbrack, len("[")),
+			tok(n.Rbrack, len("]")))
+
+	case *ast.StarExpr:
+		children = append(children, tok(n.Star, len("*")))
+
+	case *ast.StructType:
+		children = append(children, tok(n.Struct, len("struct")))
+
+	case *ast.SwitchStmt:
+		children = append(children, tok(n.Switch, len("switch")))
+
+	case *ast.TypeAssertExpr:
+		children = append(children,
+			tok(n.Lparen-1, len(".")),
+			tok(n.Lparen, len("(")),
+			tok(n.Rparen, len(")")))
+
+	case *ast.TypeSpec:
+		// TODO(adonovan): TypeSpec.{Doc,Comment}?
+
+	case *ast.TypeSwitchStmt:
+		children = append(children, tok(n.Switch, len("switch")))
+
+	case *ast.UnaryExpr:
+		children = append(children, tok(n.OpPos, len(n.Op.String())))
+
+	case *ast.ValueSpec:
+		// TODO(adonovan): ValueSpec.{Doc,Comment}?
+
+	case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt:
+		// nop
+	}
+
+	// TODO(adonovan): opt: merge the logic of ast.Inspect() into
+	// the switch above so we can make interleaved callbacks for
+	// both Nodes and Tokens in the right order and avoid the need
+	// to sort.
+	sort.Sort(byPos(children))
+
+	return children
+}
+
+type byPos []ast.Node
+
+func (sl byPos) Len() int {
+	return len(sl)
+}
+func (sl byPos) Less(i, j int) bool {
+	return sl[i].Pos() < sl[j].Pos()
+}
+func (sl byPos) Swap(i, j int) {
+	sl[i], sl[j] = sl[j], sl[i]
+}
+
+// NodeDescription returns a description of the concrete type of n suitable
+// for a user interface.
+//
+// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident,
+// StarExpr) we could be much more specific given the path to the AST
+// root.  Perhaps we should do that.
+//
+func NodeDescription(n ast.Node) string {
+	switch n := n.(type) {
+	case *ast.ArrayType:
+		return "array type"
+	case *ast.AssignStmt:
+		return "assignment"
+	case *ast.BadDecl:
+		return "bad declaration"
+	case *ast.BadExpr:
+		return "bad expression"
+	case *ast.BadStmt:
+		return "bad statement"
+	case *ast.BasicLit:
+		return "basic literal"
+	case *ast.BinaryExpr:
+		return fmt.Sprintf("binary %s operation", n.Op)
+	case *ast.BlockStmt:
+		return "block"
+	case *ast.BranchStmt:
+		switch n.Tok {
+		case token.BREAK:
+			return "break statement"
+		case token.CONTINUE:
+			return "continue statement"
+		case token.GOTO:
+			return "goto statement"
+		case token.FALLTHROUGH:
+			return "fall-through statement"
+		}
+	case *ast.CallExpr:
+		if len(n.Args) == 1 && !n.Ellipsis.IsValid() {
+			return "function call (or conversion)"
+		}
+		return "function call"
+	case *ast.CaseClause:
+		return "case clause"
+	case *ast.ChanType:
+		return "channel type"
+	case *ast.CommClause:
+		return "communication clause"
+	case *ast.Comment:
+		return "comment"
+	case *ast.CommentGroup:
+		return "comment group"
+	case *ast.CompositeLit:
+		return "composite literal"
+	case *ast.DeclStmt:
+		return NodeDescription(n.Decl) + " statement"
+	case *ast.DeferStmt:
+		return "defer statement"
+	case *ast.Ellipsis:
+		return "ellipsis"
+	case *ast.EmptyStmt:
+		return "empty statement"
+	case *ast.ExprStmt:
+		return "expression statement"
+	case *ast.Field:
+		// Can be any of these:
+		// struct {x, y int}  -- struct field(s)
+		// struct {T}         -- anon struct field
+		// interface {I}      -- interface embedding
+		// interface {f()}    -- interface method
+		// func (A) func(B) C -- receiver, param(s), result(s)
+		return "field/method/parameter"
+	case *ast.FieldList:
+		return "field/method/parameter list"
+	case *ast.File:
+		return "source file"
+	case *ast.ForStmt:
+		return "for loop"
+	case *ast.FuncDecl:
+		return "function declaration"
+	case *ast.FuncLit:
+		return "function literal"
+	case *ast.FuncType:
+		return "function type"
+	case *ast.GenDecl:
+		switch n.Tok {
+		case token.IMPORT:
+			return "import declaration"
+		case token.CONST:
+			return "constant declaration"
+		case token.TYPE:
+			return "type declaration"
+		case token.VAR:
+			return "variable declaration"
+		}
+	case *ast.GoStmt:
+		return "go statement"
+	case *ast.Ident:
+		return "identifier"
+	case *ast.IfStmt:
+		return "if statement"
+	case *ast.ImportSpec:
+		return "import specification"
+	case *ast.IncDecStmt:
+		if n.Tok == token.INC {
+			return "increment statement"
+		}
+		return "decrement statement"
+	case *ast.IndexExpr:
+		return "index expression"
+	case *ast.InterfaceType:
+		return "interface type"
+	case *ast.KeyValueExpr:
+		return "key/value association"
+	case *ast.LabeledStmt:
+		return "statement label"
+	case *ast.MapType:
+		return "map type"
+	case *ast.Package:
+		return "package"
+	case *ast.ParenExpr:
+		return "parenthesized " + NodeDescription(n.X)
+	case *ast.RangeStmt:
+		return "range loop"
+	case *ast.ReturnStmt:
+		return "return statement"
+	case *ast.SelectStmt:
+		return "select statement"
+	case *ast.SelectorExpr:
+		return "selector"
+	case *ast.SendStmt:
+		return "channel send"
+	case *ast.SliceExpr:
+		return "slice expression"
+	case *ast.StarExpr:
+		return "*-operation" // load/store expr or pointer type
+	case *ast.StructType:
+		return "struct type"
+	case *ast.SwitchStmt:
+		return "switch statement"
+	case *ast.TypeAssertExpr:
+		return "type assertion"
+	case *ast.TypeSpec:
+		return "type specification"
+	case *ast.TypeSwitchStmt:
+		return "type switch"
+	case *ast.UnaryExpr:
+		return fmt.Sprintf("unary %s operation", n.Op)
+	case *ast.ValueSpec:
+		return "value specification"
+
+	}
+	panic(fmt.Sprintf("unexpected node type: %T", n))
+}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
new file mode 100644
index 0000000000000000000000000000000000000000..04ad6795d921eb9613c383b37e3784e7d04eb44c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
@@ -0,0 +1,471 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package astutil contains common utilities for working with the Go AST.
+package astutil // import "golang.org/x/tools/go/ast/astutil"
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+	"strconv"
+	"strings"
+)
+
+// AddImport adds the import path to the file f, if absent.
+func AddImport(fset *token.FileSet, f *ast.File, ipath string) (added bool) {
+	return AddNamedImport(fset, f, "", ipath)
+}
+
+// AddNamedImport adds the import path to the file f, if absent.
+// If name is not empty, it is used to rename the import.
+//
+// For example, calling
+//	AddNamedImport(fset, f, "pathpkg", "path")
+// adds
+//	import pathpkg "path"
+func AddNamedImport(fset *token.FileSet, f *ast.File, name, ipath string) (added bool) {
+	if imports(f, ipath) {
+		return false
+	}
+
+	newImport := &ast.ImportSpec{
+		Path: &ast.BasicLit{
+			Kind:  token.STRING,
+			Value: strconv.Quote(ipath),
+		},
+	}
+	if name != "" {
+		newImport.Name = &ast.Ident{Name: name}
+	}
+
+	// Find an import decl to add to.
+	// The goal is to find an existing import
+	// whose import path has the longest shared
+	// prefix with ipath.
+	var (
+		bestMatch  = -1         // length of longest shared prefix
+		lastImport = -1         // index in f.Decls of the file's final import decl
+		impDecl    *ast.GenDecl // import decl containing the best match
+		impIndex   = -1         // spec index in impDecl containing the best match
+
+		isThirdPartyPath = isThirdParty(ipath)
+	)
+	for i, decl := range f.Decls {
+		gen, ok := decl.(*ast.GenDecl)
+		if ok && gen.Tok == token.IMPORT {
+			lastImport = i
+			// Do not add to import "C", to avoid disrupting the
+			// association with its doc comment, breaking cgo.
+			if declImports(gen, "C") {
+				continue
+			}
+
+			// Match an empty import decl if that's all that is available.
+			if len(gen.Specs) == 0 && bestMatch == -1 {
+				impDecl = gen
+			}
+
+			// Compute longest shared prefix with imports in this group and find best
+			// matched import spec.
+			// 1. Always prefer import spec with longest shared prefix.
+			// 2. While match length is 0,
+			// - for stdlib package: prefer first import spec.
+			// - for third party package: prefer first third party import spec.
+			// We cannot use last import spec as best match for third party package
+			// because grouped imports are usually placed last by goimports -local
+			// flag.
+			// See issue #19190.
+			seenAnyThirdParty := false
+			for j, spec := range gen.Specs {
+				impspec := spec.(*ast.ImportSpec)
+				p := importPath(impspec)
+				n := matchLen(p, ipath)
+				if n > bestMatch || (bestMatch == 0 && !seenAnyThirdParty && isThirdPartyPath) {
+					bestMatch = n
+					impDecl = gen
+					impIndex = j
+				}
+				seenAnyThirdParty = seenAnyThirdParty || isThirdParty(p)
+			}
+		}
+	}
+
+	// If no import decl found, add one after the last import.
+	if impDecl == nil {
+		impDecl = &ast.GenDecl{
+			Tok: token.IMPORT,
+		}
+		if lastImport >= 0 {
+			impDecl.TokPos = f.Decls[lastImport].End()
+		} else {
+			// There are no existing imports.
+			// Our new import, preceded by a blank line,  goes after the package declaration
+			// and after the comment, if any, that starts on the same line as the
+			// package declaration.
+			impDecl.TokPos = f.Package
+
+			file := fset.File(f.Package)
+			pkgLine := file.Line(f.Package)
+			for _, c := range f.Comments {
+				if file.Line(c.Pos()) > pkgLine {
+					break
+				}
+				// +2 for a blank line
+				impDecl.TokPos = c.End() + 2
+			}
+		}
+		f.Decls = append(f.Decls, nil)
+		copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
+		f.Decls[lastImport+1] = impDecl
+	}
+
+	// Insert new import at insertAt.
+	insertAt := 0
+	if impIndex >= 0 {
+		// insert after the found import
+		insertAt = impIndex + 1
+	}
+	impDecl.Specs = append(impDecl.Specs, nil)
+	copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
+	impDecl.Specs[insertAt] = newImport
+	pos := impDecl.Pos()
+	if insertAt > 0 {
+		// If there is a comment after an existing import, preserve the comment
+		// position by adding the new import after the comment.
+		if spec, ok := impDecl.Specs[insertAt-1].(*ast.ImportSpec); ok && spec.Comment != nil {
+			pos = spec.Comment.End()
+		} else {
+			// Assign same position as the previous import,
+			// so that the sorter sees it as being in the same block.
+			pos = impDecl.Specs[insertAt-1].Pos()
+		}
+	}
+	if newImport.Name != nil {
+		newImport.Name.NamePos = pos
+	}
+	newImport.Path.ValuePos = pos
+	newImport.EndPos = pos
+
+	// Clean up parens. impDecl contains at least one spec.
+	if len(impDecl.Specs) == 1 {
+		// Remove unneeded parens.
+		impDecl.Lparen = token.NoPos
+	} else if !impDecl.Lparen.IsValid() {
+		// impDecl needs parens added.
+		impDecl.Lparen = impDecl.Specs[0].Pos()
+	}
+
+	f.Imports = append(f.Imports, newImport)
+
+	if len(f.Decls) <= 1 {
+		return true
+	}
+
+	// Merge all the import declarations into the first one.
+	var first *ast.GenDecl
+	for i := 0; i < len(f.Decls); i++ {
+		decl := f.Decls[i]
+		gen, ok := decl.(*ast.GenDecl)
+		if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") {
+			continue
+		}
+		if first == nil {
+			first = gen
+			continue // Don't touch the first one.
+		}
+		// We now know there is more than one package in this import
+		// declaration. Ensure that it ends up parenthesized.
+		first.Lparen = first.Pos()
+		// Move the imports of the other import declaration to the first one.
+		for _, spec := range gen.Specs {
+			spec.(*ast.ImportSpec).Path.ValuePos = first.Pos()
+			first.Specs = append(first.Specs, spec)
+		}
+		f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
+		i--
+	}
+
+	return true
+}
+
+func isThirdParty(importPath string) bool {
+	// Third party package import path usually contains "." (".com", ".org", ...)
+	// This logic is taken from golang.org/x/tools/imports package.
+	return strings.Contains(importPath, ".")
+}
+
+// DeleteImport deletes the import path from the file f, if present.
+func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) {
+	return DeleteNamedImport(fset, f, "", path)
+}
+
+// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
+func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
+	var delspecs []*ast.ImportSpec
+	var delcomments []*ast.CommentGroup
+
+	// Find the import nodes that import path, if any.
+	for i := 0; i < len(f.Decls); i++ {
+		decl := f.Decls[i]
+		gen, ok := decl.(*ast.GenDecl)
+		if !ok || gen.Tok != token.IMPORT {
+			continue
+		}
+		for j := 0; j < len(gen.Specs); j++ {
+			spec := gen.Specs[j]
+			impspec := spec.(*ast.ImportSpec)
+			if impspec.Name == nil && name != "" {
+				continue
+			}
+			if impspec.Name != nil && impspec.Name.Name != name {
+				continue
+			}
+			if importPath(impspec) != path {
+				continue
+			}
+
+			// We found an import spec that imports path.
+			// Delete it.
+			delspecs = append(delspecs, impspec)
+			deleted = true
+			copy(gen.Specs[j:], gen.Specs[j+1:])
+			gen.Specs = gen.Specs[:len(gen.Specs)-1]
+
+			// If this was the last import spec in this decl,
+			// delete the decl, too.
+			if len(gen.Specs) == 0 {
+				copy(f.Decls[i:], f.Decls[i+1:])
+				f.Decls = f.Decls[:len(f.Decls)-1]
+				i--
+				break
+			} else if len(gen.Specs) == 1 {
+				if impspec.Doc != nil {
+					delcomments = append(delcomments, impspec.Doc)
+				}
+				if impspec.Comment != nil {
+					delcomments = append(delcomments, impspec.Comment)
+				}
+				for _, cg := range f.Comments {
+					// Found comment on the same line as the import spec.
+					if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line {
+						delcomments = append(delcomments, cg)
+						break
+					}
+				}
+
+				spec := gen.Specs[0].(*ast.ImportSpec)
+
+				// Move the documentation right after the import decl.
+				if spec.Doc != nil {
+					for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Doc.Pos()).Line {
+						fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
+					}
+				}
+				for _, cg := range f.Comments {
+					if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line {
+						for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Pos()).Line {
+							fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
+						}
+						break
+					}
+				}
+			}
+			if j > 0 {
+				lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
+				lastLine := fset.Position(lastImpspec.Path.ValuePos).Line
+				line := fset.Position(impspec.Path.ValuePos).Line
+
+				// We deleted an entry but now there may be
+				// a blank line-sized hole where the import was.
+				if line-lastLine > 1 {
+					// There was a blank line immediately preceding the deleted import,
+					// so there's no need to close the hole.
+					// Do nothing.
+				} else if line != fset.File(gen.Rparen).LineCount() {
+					// There was no blank line. Close the hole.
+					fset.File(gen.Rparen).MergeLine(line)
+				}
+			}
+			j--
+		}
+	}
+
+	// Delete imports from f.Imports.
+	for i := 0; i < len(f.Imports); i++ {
+		imp := f.Imports[i]
+		for j, del := range delspecs {
+			if imp == del {
+				copy(f.Imports[i:], f.Imports[i+1:])
+				f.Imports = f.Imports[:len(f.Imports)-1]
+				copy(delspecs[j:], delspecs[j+1:])
+				delspecs = delspecs[:len(delspecs)-1]
+				i--
+				break
+			}
+		}
+	}
+
+	// Delete comments from f.Comments.
+	for i := 0; i < len(f.Comments); i++ {
+		cg := f.Comments[i]
+		for j, del := range delcomments {
+			if cg == del {
+				copy(f.Comments[i:], f.Comments[i+1:])
+				f.Comments = f.Comments[:len(f.Comments)-1]
+				copy(delcomments[j:], delcomments[j+1:])
+				delcomments = delcomments[:len(delcomments)-1]
+				i--
+				break
+			}
+		}
+	}
+
+	if len(delspecs) > 0 {
+		panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
+	}
+
+	return
+}
+
+// RewriteImport rewrites any import of path oldPath to path newPath.
+func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) {
+	for _, imp := range f.Imports {
+		if importPath(imp) == oldPath {
+			rewrote = true
+			// record old End, because the default is to compute
+			// it using the length of imp.Path.Value.
+			imp.EndPos = imp.End()
+			imp.Path.Value = strconv.Quote(newPath)
+		}
+	}
+	return
+}
+
+// UsesImport reports whether a given import is used.
+func UsesImport(f *ast.File, path string) (used bool) {
+	spec := importSpec(f, path)
+	if spec == nil {
+		return
+	}
+
+	name := spec.Name.String()
+	switch name {
+	case "<nil>":
+		// If the package name is not explicitly specified,
+		// make an educated guess. This is not guaranteed to be correct.
+		lastSlash := strings.LastIndex(path, "/")
+		if lastSlash == -1 {
+			name = path
+		} else {
+			name = path[lastSlash+1:]
+		}
+	case "_", ".":
+		// Not sure if this import is used - err on the side of caution.
+		return true
+	}
+
+	ast.Walk(visitFn(func(n ast.Node) {
+		sel, ok := n.(*ast.SelectorExpr)
+		if ok && isTopName(sel.X, name) {
+			used = true
+		}
+	}), f)
+
+	return
+}
+
+type visitFn func(node ast.Node)
+
+func (fn visitFn) Visit(node ast.Node) ast.Visitor {
+	fn(node)
+	return fn
+}
+
+// imports returns true if f imports path.
+func imports(f *ast.File, path string) bool {
+	return importSpec(f, path) != nil
+}
+
+// importSpec returns the import spec if f imports path,
+// or nil otherwise.
+func importSpec(f *ast.File, path string) *ast.ImportSpec {
+	for _, s := range f.Imports {
+		if importPath(s) == path {
+			return s
+		}
+	}
+	return nil
+}
+
+// importPath returns the unquoted import path of s,
+// or "" if the path is not properly quoted.
+func importPath(s *ast.ImportSpec) string {
+	t, err := strconv.Unquote(s.Path.Value)
+	if err == nil {
+		return t
+	}
+	return ""
+}
+
+// declImports reports whether gen contains an import of path.
+func declImports(gen *ast.GenDecl, path string) bool {
+	if gen.Tok != token.IMPORT {
+		return false
+	}
+	for _, spec := range gen.Specs {
+		impspec := spec.(*ast.ImportSpec)
+		if importPath(impspec) == path {
+			return true
+		}
+	}
+	return false
+}
+
+// matchLen returns the length of the longest path segment prefix shared by x and y.
+func matchLen(x, y string) int {
+	n := 0
+	for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ {
+		if x[i] == '/' {
+			n++
+		}
+	}
+	return n
+}
+
+// isTopName returns true if n is a top-level unresolved identifier with the given name.
+func isTopName(n ast.Expr, name string) bool {
+	id, ok := n.(*ast.Ident)
+	return ok && id.Name == name && id.Obj == nil
+}
+
+// Imports returns the file imports grouped by paragraph.
+func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec {
+	var groups [][]*ast.ImportSpec
+
+	for _, decl := range f.Decls {
+		genDecl, ok := decl.(*ast.GenDecl)
+		if !ok || genDecl.Tok != token.IMPORT {
+			break
+		}
+
+		group := []*ast.ImportSpec{}
+
+		var lastLine int
+		for _, spec := range genDecl.Specs {
+			importSpec := spec.(*ast.ImportSpec)
+			pos := importSpec.Path.ValuePos
+			line := fset.Position(pos).Line
+			if lastLine > 0 && pos > 0 && line-lastLine > 1 {
+				groups = append(groups, group)
+				group = []*ast.ImportSpec{}
+			}
+			group = append(group, importSpec)
+			lastLine = line
+		}
+		groups = append(groups, group)
+	}
+
+	return groups
+}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
new file mode 100644
index 0000000000000000000000000000000000000000..cf72ea990bda2c11ae7a87865c352b7fc9029730
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
@@ -0,0 +1,477 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+import (
+	"fmt"
+	"go/ast"
+	"reflect"
+	"sort"
+)
+
+// An ApplyFunc is invoked by Apply for each node n, even if n is nil,
+// before and/or after the node's children, using a Cursor describing
+// the current node and providing operations on it.
+//
+// The return value of ApplyFunc controls the syntax tree traversal.
+// See Apply for details.
+type ApplyFunc func(*Cursor) bool
+
+// Apply traverses a syntax tree recursively, starting with root,
+// and calling pre and post for each node as described below.
+// Apply returns the syntax tree, possibly modified.
+//
+// If pre is not nil, it is called for each node before the node's
+// children are traversed (pre-order). If pre returns false, no
+// children are traversed, and post is not called for that node.
+//
+// If post is not nil, and a prior call of pre didn't return false,
+// post is called for each node after its children are traversed
+// (post-order). If post returns false, traversal is terminated and
+// Apply returns immediately.
+//
+// Only fields that refer to AST nodes are considered children;
+// i.e., token.Pos, Scopes, Objects, and fields of basic types
+// (strings, etc.) are ignored.
+//
+// Children are traversed in the order in which they appear in the
+// respective node's struct definition. A package's files are
+// traversed in the filenames' alphabetical order.
+//
+func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) {
+	parent := &struct{ ast.Node }{root}
+	defer func() {
+		if r := recover(); r != nil && r != abort {
+			panic(r)
+		}
+		result = parent.Node
+	}()
+	a := &application{pre: pre, post: post}
+	a.apply(parent, "Node", nil, root)
+	return
+}
+
+var abort = new(int) // singleton, to signal termination of Apply
+
+// A Cursor describes a node encountered during Apply.
+// Information about the node and its parent is available
+// from the Node, Parent, Name, and Index methods.
+//
+// If p is a variable of type and value of the current parent node
+// c.Parent(), and f is the field identifier with name c.Name(),
+// the following invariants hold:
+//
+//   p.f            == c.Node()  if c.Index() <  0
+//   p.f[c.Index()] == c.Node()  if c.Index() >= 0
+//
+// The methods Replace, Delete, InsertBefore, and InsertAfter
+// can be used to change the AST without disrupting Apply.
+type Cursor struct {
+	parent ast.Node
+	name   string
+	iter   *iterator // valid if non-nil
+	node   ast.Node
+}
+
+// Node returns the current Node.
+func (c *Cursor) Node() ast.Node { return c.node }
+
+// Parent returns the parent of the current Node.
+func (c *Cursor) Parent() ast.Node { return c.parent }
+
+// Name returns the name of the parent Node field that contains the current Node.
+// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns
+// the filename for the current Node.
+func (c *Cursor) Name() string { return c.name }
+
+// Index reports the index >= 0 of the current Node in the slice of Nodes that
+// contains it, or a value < 0 if the current Node is not part of a slice.
+// The index of the current node changes if InsertBefore is called while
+// processing the current node.
+func (c *Cursor) Index() int {
+	if c.iter != nil {
+		return c.iter.index
+	}
+	return -1
+}
+
+// field returns the current node's parent field value.
+func (c *Cursor) field() reflect.Value {
+	return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name)
+}
+
+// Replace replaces the current Node with n.
+// The replacement node is not walked by Apply.
+func (c *Cursor) Replace(n ast.Node) {
+	if _, ok := c.node.(*ast.File); ok {
+		file, ok := n.(*ast.File)
+		if !ok {
+			panic("attempt to replace *ast.File with non-*ast.File")
+		}
+		c.parent.(*ast.Package).Files[c.name] = file
+		return
+	}
+
+	v := c.field()
+	if i := c.Index(); i >= 0 {
+		v = v.Index(i)
+	}
+	v.Set(reflect.ValueOf(n))
+}
+
+// Delete deletes the current Node from its containing slice.
+// If the current Node is not part of a slice, Delete panics.
+// As a special case, if the current node is a package file,
+// Delete removes it from the package's Files map.
+func (c *Cursor) Delete() {
+	if _, ok := c.node.(*ast.File); ok {
+		delete(c.parent.(*ast.Package).Files, c.name)
+		return
+	}
+
+	i := c.Index()
+	if i < 0 {
+		panic("Delete node not contained in slice")
+	}
+	v := c.field()
+	l := v.Len()
+	reflect.Copy(v.Slice(i, l), v.Slice(i+1, l))
+	v.Index(l - 1).Set(reflect.Zero(v.Type().Elem()))
+	v.SetLen(l - 1)
+	c.iter.step--
+}
+
+// InsertAfter inserts n after the current Node in its containing slice.
+// If the current Node is not part of a slice, InsertAfter panics.
+// Apply does not walk n.
+func (c *Cursor) InsertAfter(n ast.Node) {
+	i := c.Index()
+	if i < 0 {
+		panic("InsertAfter node not contained in slice")
+	}
+	v := c.field()
+	v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
+	l := v.Len()
+	reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l))
+	v.Index(i + 1).Set(reflect.ValueOf(n))
+	c.iter.step++
+}
+
+// InsertBefore inserts n before the current Node in its containing slice.
+// If the current Node is not part of a slice, InsertBefore panics.
+// Apply will not walk n.
+func (c *Cursor) InsertBefore(n ast.Node) {
+	i := c.Index()
+	if i < 0 {
+		panic("InsertBefore node not contained in slice")
+	}
+	v := c.field()
+	v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
+	l := v.Len()
+	reflect.Copy(v.Slice(i+1, l), v.Slice(i, l))
+	v.Index(i).Set(reflect.ValueOf(n))
+	c.iter.index++
+}
+
+// application carries all the shared data so we can pass it around cheaply.
+type application struct {
+	pre, post ApplyFunc
+	cursor    Cursor
+	iter      iterator
+}
+
+func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) {
+	// convert typed nil into untyped nil
+	if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() {
+		n = nil
+	}
+
+	// avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead
+	saved := a.cursor
+	a.cursor.parent = parent
+	a.cursor.name = name
+	a.cursor.iter = iter
+	a.cursor.node = n
+
+	if a.pre != nil && !a.pre(&a.cursor) {
+		a.cursor = saved
+		return
+	}
+
+	// walk children
+	// (the order of the cases matches the order of the corresponding node types in go/ast)
+	switch n := n.(type) {
+	case nil:
+		// nothing to do
+
+	// Comments and fields
+	case *ast.Comment:
+		// nothing to do
+
+	case *ast.CommentGroup:
+		if n != nil {
+			a.applyList(n, "List")
+		}
+
+	case *ast.Field:
+		a.apply(n, "Doc", nil, n.Doc)
+		a.applyList(n, "Names")
+		a.apply(n, "Type", nil, n.Type)
+		a.apply(n, "Tag", nil, n.Tag)
+		a.apply(n, "Comment", nil, n.Comment)
+
+	case *ast.FieldList:
+		a.applyList(n, "List")
+
+	// Expressions
+	case *ast.BadExpr, *ast.Ident, *ast.BasicLit:
+		// nothing to do
+
+	case *ast.Ellipsis:
+		a.apply(n, "Elt", nil, n.Elt)
+
+	case *ast.FuncLit:
+		a.apply(n, "Type", nil, n.Type)
+		a.apply(n, "Body", nil, n.Body)
+
+	case *ast.CompositeLit:
+		a.apply(n, "Type", nil, n.Type)
+		a.applyList(n, "Elts")
+
+	case *ast.ParenExpr:
+		a.apply(n, "X", nil, n.X)
+
+	case *ast.SelectorExpr:
+		a.apply(n, "X", nil, n.X)
+		a.apply(n, "Sel", nil, n.Sel)
+
+	case *ast.IndexExpr:
+		a.apply(n, "X", nil, n.X)
+		a.apply(n, "Index", nil, n.Index)
+
+	case *ast.SliceExpr:
+		a.apply(n, "X", nil, n.X)
+		a.apply(n, "Low", nil, n.Low)
+		a.apply(n, "High", nil, n.High)
+		a.apply(n, "Max", nil, n.Max)
+
+	case *ast.TypeAssertExpr:
+		a.apply(n, "X", nil, n.X)
+		a.apply(n, "Type", nil, n.Type)
+
+	case *ast.CallExpr:
+		a.apply(n, "Fun", nil, n.Fun)
+		a.applyList(n, "Args")
+
+	case *ast.StarExpr:
+		a.apply(n, "X", nil, n.X)
+
+	case *ast.UnaryExpr:
+		a.apply(n, "X", nil, n.X)
+
+	case *ast.BinaryExpr:
+		a.apply(n, "X", nil, n.X)
+		a.apply(n, "Y", nil, n.Y)
+
+	case *ast.KeyValueExpr:
+		a.apply(n, "Key", nil, n.Key)
+		a.apply(n, "Value", nil, n.Value)
+
+	// Types
+	case *ast.ArrayType:
+		a.apply(n, "Len", nil, n.Len)
+		a.apply(n, "Elt", nil, n.Elt)
+
+	case *ast.StructType:
+		a.apply(n, "Fields", nil, n.Fields)
+
+	case *ast.FuncType:
+		a.apply(n, "Params", nil, n.Params)
+		a.apply(n, "Results", nil, n.Results)
+
+	case *ast.InterfaceType:
+		a.apply(n, "Methods", nil, n.Methods)
+
+	case *ast.MapType:
+		a.apply(n, "Key", nil, n.Key)
+		a.apply(n, "Value", nil, n.Value)
+
+	case *ast.ChanType:
+		a.apply(n, "Value", nil, n.Value)
+
+	// Statements
+	case *ast.BadStmt:
+		// nothing to do
+
+	case *ast.DeclStmt:
+		a.apply(n, "Decl", nil, n.Decl)
+
+	case *ast.EmptyStmt:
+		// nothing to do
+
+	case *ast.LabeledStmt:
+		a.apply(n, "Label", nil, n.Label)
+		a.apply(n, "Stmt", nil, n.Stmt)
+
+	case *ast.ExprStmt:
+		a.apply(n, "X", nil, n.X)
+
+	case *ast.SendStmt:
+		a.apply(n, "Chan", nil, n.Chan)
+		a.apply(n, "Value", nil, n.Value)
+
+	case *ast.IncDecStmt:
+		a.apply(n, "X", nil, n.X)
+
+	case *ast.AssignStmt:
+		a.applyList(n, "Lhs")
+		a.applyList(n, "Rhs")
+
+	case *ast.GoStmt:
+		a.apply(n, "Call", nil, n.Call)
+
+	case *ast.DeferStmt:
+		a.apply(n, "Call", nil, n.Call)
+
+	case *ast.ReturnStmt:
+		a.applyList(n, "Results")
+
+	case *ast.BranchStmt:
+		a.apply(n, "Label", nil, n.Label)
+
+	case *ast.BlockStmt:
+		a.applyList(n, "List")
+
+	case *ast.IfStmt:
+		a.apply(n, "Init", nil, n.Init)
+		a.apply(n, "Cond", nil, n.Cond)
+		a.apply(n, "Body", nil, n.Body)
+		a.apply(n, "Else", nil, n.Else)
+
+	case *ast.CaseClause:
+		a.applyList(n, "List")
+		a.applyList(n, "Body")
+
+	case *ast.SwitchStmt:
+		a.apply(n, "Init", nil, n.Init)
+		a.apply(n, "Tag", nil, n.Tag)
+		a.apply(n, "Body", nil, n.Body)
+
+	case *ast.TypeSwitchStmt:
+		a.apply(n, "Init", nil, n.Init)
+		a.apply(n, "Assign", nil, n.Assign)
+		a.apply(n, "Body", nil, n.Body)
+
+	case *ast.CommClause:
+		a.apply(n, "Comm", nil, n.Comm)
+		a.applyList(n, "Body")
+
+	case *ast.SelectStmt:
+		a.apply(n, "Body", nil, n.Body)
+
+	case *ast.ForStmt:
+		a.apply(n, "Init", nil, n.Init)
+		a.apply(n, "Cond", nil, n.Cond)
+		a.apply(n, "Post", nil, n.Post)
+		a.apply(n, "Body", nil, n.Body)
+
+	case *ast.RangeStmt:
+		a.apply(n, "Key", nil, n.Key)
+		a.apply(n, "Value", nil, n.Value)
+		a.apply(n, "X", nil, n.X)
+		a.apply(n, "Body", nil, n.Body)
+
+	// Declarations
+	case *ast.ImportSpec:
+		a.apply(n, "Doc", nil, n.Doc)
+		a.apply(n, "Name", nil, n.Name)
+		a.apply(n, "Path", nil, n.Path)
+		a.apply(n, "Comment", nil, n.Comment)
+
+	case *ast.ValueSpec:
+		a.apply(n, "Doc", nil, n.Doc)
+		a.applyList(n, "Names")
+		a.apply(n, "Type", nil, n.Type)
+		a.applyList(n, "Values")
+		a.apply(n, "Comment", nil, n.Comment)
+
+	case *ast.TypeSpec:
+		a.apply(n, "Doc", nil, n.Doc)
+		a.apply(n, "Name", nil, n.Name)
+		a.apply(n, "Type", nil, n.Type)
+		a.apply(n, "Comment", nil, n.Comment)
+
+	case *ast.BadDecl:
+		// nothing to do
+
+	case *ast.GenDecl:
+		a.apply(n, "Doc", nil, n.Doc)
+		a.applyList(n, "Specs")
+
+	case *ast.FuncDecl:
+		a.apply(n, "Doc", nil, n.Doc)
+		a.apply(n, "Recv", nil, n.Recv)
+		a.apply(n, "Name", nil, n.Name)
+		a.apply(n, "Type", nil, n.Type)
+		a.apply(n, "Body", nil, n.Body)
+
+	// Files and packages
+	case *ast.File:
+		a.apply(n, "Doc", nil, n.Doc)
+		a.apply(n, "Name", nil, n.Name)
+		a.applyList(n, "Decls")
+		// Don't walk n.Comments; they have either been walked already if
+		// they are Doc comments, or they can be easily walked explicitly.
+
+	case *ast.Package:
+		// collect and sort names for reproducible behavior
+		var names []string
+		for name := range n.Files {
+			names = append(names, name)
+		}
+		sort.Strings(names)
+		for _, name := range names {
+			a.apply(n, name, nil, n.Files[name])
+		}
+
+	default:
+		panic(fmt.Sprintf("Apply: unexpected node type %T", n))
+	}
+
+	if a.post != nil && !a.post(&a.cursor) {
+		panic(abort)
+	}
+
+	a.cursor = saved
+}
+
+// An iterator controls iteration over a slice of nodes.
+type iterator struct {
+	index, step int
+}
+
+func (a *application) applyList(parent ast.Node, name string) {
+	// avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead
+	saved := a.iter
+	a.iter.index = 0
+	for {
+		// must reload parent.name each time, since cursor modifications might change it
+		v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name)
+		if a.iter.index >= v.Len() {
+			break
+		}
+
+		// element x may be nil in a bad AST - be cautious
+		var x ast.Node
+		if e := v.Index(a.iter.index); e.IsValid() {
+			x = e.Interface().(ast.Node)
+		}
+
+		a.iter.step = 1
+		a.apply(parent, name, &a.iter, x)
+		a.iter.index += a.iter.step
+	}
+	a.iter = saved
+}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go
new file mode 100644
index 0000000000000000000000000000000000000000..7630629824af1e839b5954b72a5d5021191d69ae
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/astutil/util.go
@@ -0,0 +1,14 @@
+package astutil
+
+import "go/ast"
+
+// Unparen returns e with any enclosing parentheses stripped.
+func Unparen(e ast.Expr) ast.Expr {
+	for {
+		p, ok := e.(*ast.ParenExpr)
+		if !ok {
+			return e
+		}
+		e = p.X
+	}
+}
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
new file mode 100644
index 0000000000000000000000000000000000000000..4c238d10131c0632bdf6c50d06e591af9de2daa8
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
@@ -0,0 +1,109 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gcexportdata provides functions for locating, reading, and
+// writing export data files containing type information produced by the
+// gc compiler.  This package supports go1.7 export data format and all
+// later versions.
+//
+// Although it might seem convenient for this package to live alongside
+// go/types in the standard library, this would cause version skew
+// problems for developer tools that use it, since they must be able to
+// consume the outputs of the gc compiler both before and after a Go
+// update such as from Go 1.7 to Go 1.8.  Because this package lives in
+// golang.org/x/tools, sites can update their version of this repo some
+// time before the Go 1.8 release and rebuild and redeploy their
+// developer tools, which will then be able to consume both Go 1.7 and
+// Go 1.8 export data files, so they will work before and after the
+// Go update. (See discussion at https://github.com/golang/go/issues/15651.)
+//
+package gcexportdata // import "golang.org/x/tools/go/gcexportdata"
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"go/token"
+	"go/types"
+	"io"
+	"io/ioutil"
+
+	"golang.org/x/tools/go/internal/gcimporter"
+)
+
+// Find returns the name of an object (.o) or archive (.a) file
+// containing type information for the specified import path,
+// using the workspace layout conventions of go/build.
+// If no file was found, an empty filename is returned.
+//
+// A relative srcDir is interpreted relative to the current working directory.
+//
+// Find also returns the package's resolved (canonical) import path,
+// reflecting the effects of srcDir and vendoring on importPath.
+func Find(importPath, srcDir string) (filename, path string) {
+	return gcimporter.FindPkg(importPath, srcDir)
+}
+
+// NewReader returns a reader for the export data section of an object
+// (.o) or archive (.a) file read from r.  The new reader may provide
+// additional trailing data beyond the end of the export data.
+func NewReader(r io.Reader) (io.Reader, error) {
+	buf := bufio.NewReader(r)
+	_, err := gcimporter.FindExportData(buf)
+	// If we ever switch to a zip-like archive format with the ToC
+	// at the end, we can return the correct portion of export data,
+	// but for now we must return the entire rest of the file.
+	return buf, err
+}
+
+// Read reads export data from in, decodes it, and returns type
+// information for the package.
+// The package name is specified by path.
+// File position information is added to fset.
+//
+// Read may inspect and add to the imports map to ensure that references
+// within the export data to other packages are consistent.  The caller
+// must ensure that imports[path] does not exist, or exists but is
+// incomplete (see types.Package.Complete), and Read inserts the
+// resulting package into this map entry.
+//
+// On return, the state of the reader is undefined.
+func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) {
+	data, err := ioutil.ReadAll(in)
+	if err != nil {
+		return nil, fmt.Errorf("reading export data for %q: %v", path, err)
+	}
+
+	if bytes.HasPrefix(data, []byte("!<arch>")) {
+		return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path)
+	}
+
+	// The App Engine Go runtime v1.6 uses the old export data format.
+	// TODO(adonovan): delete once v1.7 has been around for a while.
+	if bytes.HasPrefix(data, []byte("package ")) {
+		return gcimporter.ImportData(imports, path, path, bytes.NewReader(data))
+	}
+
+	// The indexed export format starts with an 'i'; the older
+	// binary export format starts with a 'c', 'd', or 'v'
+	// (from "version"). Select appropriate importer.
+	if len(data) > 0 && data[0] == 'i' {
+		_, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path)
+		return pkg, err
+	}
+
+	_, pkg, err := gcimporter.BImportData(fset, imports, data, path)
+	return pkg, err
+}
+
+// Write writes encoded type information for the specified package to out.
+// The FileSet provides file position information for named objects.
+func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
+	b, err := gcimporter.BExportData(fset, pkg)
+	if err != nil {
+		return err
+	}
+	_, err = out.Write(b)
+	return err
+}
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go
new file mode 100644
index 0000000000000000000000000000000000000000..efe221e7e1423e370d968eb512be02bb7ea6601e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go
@@ -0,0 +1,73 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gcexportdata
+
+import (
+	"fmt"
+	"go/token"
+	"go/types"
+	"os"
+)
+
+// NewImporter returns a new instance of the types.Importer interface
+// that reads type information from export data files written by gc.
+// The Importer also satisfies types.ImporterFrom.
+//
+// Export data files are located using "go build" workspace conventions
+// and the build.Default context.
+//
+// Use this importer instead of go/importer.For("gc", ...) to avoid the
+// version-skew problems described in the documentation of this package,
+// or to control the FileSet or access the imports map populated during
+// package loading.
+//
+func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom {
+	return importer{fset, imports}
+}
+
+type importer struct {
+	fset    *token.FileSet
+	imports map[string]*types.Package
+}
+
+func (imp importer) Import(importPath string) (*types.Package, error) {
+	return imp.ImportFrom(importPath, "", 0)
+}
+
+func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) {
+	filename, path := Find(importPath, srcDir)
+	if filename == "" {
+		if importPath == "unsafe" {
+			// Even for unsafe, call Find first in case
+			// the package was vendored.
+			return types.Unsafe, nil
+		}
+		return nil, fmt.Errorf("can't find import: %s", importPath)
+	}
+
+	if pkg, ok := imp.imports[path]; ok && pkg.Complete() {
+		return pkg, nil // cache hit
+	}
+
+	// open file
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		f.Close()
+		if err != nil {
+			// add file name to error
+			err = fmt.Errorf("reading export data: %s: %v", filename, err)
+		}
+	}()
+
+	r, err := NewReader(f)
+	if err != nil {
+		return nil, err
+	}
+
+	return Read(r, imp.fset, imp.imports, path)
+}
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/main.go b/vendor/golang.org/x/tools/go/gcexportdata/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..2713dce64a9bf2c427953e3f62d68152740c356a
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcexportdata/main.go
@@ -0,0 +1,99 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// The gcexportdata command is a diagnostic tool that displays the
+// contents of gc export data files.
+package main
+
+import (
+	"flag"
+	"fmt"
+	"go/token"
+	"go/types"
+	"log"
+	"os"
+
+	"golang.org/x/tools/go/gcexportdata"
+	"golang.org/x/tools/go/types/typeutil"
+)
+
+var packageFlag = flag.String("package", "", "alternative package to print")
+
+func main() {
+	log.SetPrefix("gcexportdata: ")
+	log.SetFlags(0)
+	flag.Usage = func() {
+		fmt.Fprintln(os.Stderr, "usage: gcexportdata [-package path] file.a")
+	}
+	flag.Parse()
+	if flag.NArg() != 1 {
+		flag.Usage()
+		os.Exit(2)
+	}
+	filename := flag.Args()[0]
+
+	f, err := os.Open(filename)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	r, err := gcexportdata.NewReader(f)
+	if err != nil {
+		log.Fatalf("%s: %s", filename, err)
+	}
+
+	// Decode the package.
+	const primary = "<primary>"
+	imports := make(map[string]*types.Package)
+	fset := token.NewFileSet()
+	pkg, err := gcexportdata.Read(r, fset, imports, primary)
+	if err != nil {
+		log.Fatalf("%s: %s", filename, err)
+	}
+
+	// Optionally select an indirectly mentioned package.
+	if *packageFlag != "" {
+		pkg = imports[*packageFlag]
+		if pkg == nil {
+			fmt.Fprintf(os.Stderr, "export data file %s does not mention %s; has:\n",
+				filename, *packageFlag)
+			for p := range imports {
+				if p != primary {
+					fmt.Fprintf(os.Stderr, "\t%s\n", p)
+				}
+			}
+			os.Exit(1)
+		}
+	}
+
+	// Print all package-level declarations, including non-exported ones.
+	fmt.Printf("package %s\n", pkg.Name())
+	for _, imp := range pkg.Imports() {
+		fmt.Printf("import %q\n", imp.Path())
+	}
+	qual := func(p *types.Package) string {
+		if pkg == p {
+			return ""
+		}
+		return p.Name()
+	}
+	scope := pkg.Scope()
+	for _, name := range scope.Names() {
+		obj := scope.Lookup(name)
+		fmt.Printf("%s: %s\n",
+			fset.Position(obj.Pos()),
+			types.ObjectString(obj, qual))
+
+		// For types, print each method.
+		if _, ok := obj.(*types.TypeName); ok {
+			for _, method := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
+				fmt.Printf("%s: %s\n",
+					fset.Position(method.Obj().Pos()),
+					types.SelectionString(method, qual))
+			}
+		}
+	}
+}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
new file mode 100644
index 0000000000000000000000000000000000000000..9f65049140438bd16cbe6c6e68e0118d574982e9
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
@@ -0,0 +1,852 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Binary package export.
+// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go;
+// see that file for specification of the format.
+
+package gcimporter
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"math"
+	"math/big"
+	"sort"
+	"strings"
+)
+
+// If debugFormat is set, each integer and string value is preceded by a marker
+// and position information in the encoding. This mechanism permits an importer
+// to recognize immediately when it is out of sync. The importer recognizes this
+// mode automatically (i.e., it can import export data produced with debugging
+// support even if debugFormat is not set at the time of import). This mode will
+// lead to massively larger export data (by a factor of 2 to 3) and should only
+// be enabled during development and debugging.
+//
+// NOTE: This flag is the first flag to enable if importing dies because of
+// (suspected) format errors, and whenever a change is made to the format.
+const debugFormat = false // default: false
+
+// If trace is set, debugging output is printed to std out.
+const trace = false // default: false
+
+// Current export format version. Increase with each format change.
+// Note: The latest binary (non-indexed) export format is at version 6.
+//       This exporter is still at level 4, but it doesn't matter since
+//       the binary importer can handle older versions just fine.
+// 6: package height (CL 105038) -- NOT IMPLEMENTED HERE
+// 5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMEMTED HERE
+// 4: type name objects support type aliases, uses aliasTag
+// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used)
+// 2: removed unused bool in ODCL export (compiler only)
+// 1: header format change (more regular), export package for _ struct fields
+// 0: Go1.7 encoding
+const exportVersion = 4
+
+// trackAllTypes enables cycle tracking for all types, not just named
+// types. The existing compiler invariants assume that unnamed types
+// that are not completely set up are not used, or else there are spurious
+// errors.
+// If disabled, only named types are tracked, possibly leading to slightly
+// less efficient encoding in rare cases. It also prevents the export of
+// some corner-case type declarations (but those are not handled correctly
+// with with the textual export format either).
+// TODO(gri) enable and remove once issues caused by it are fixed
+const trackAllTypes = false
+
+type exporter struct {
+	fset *token.FileSet
+	out  bytes.Buffer
+
+	// object -> index maps, indexed in order of serialization
+	strIndex map[string]int
+	pkgIndex map[*types.Package]int
+	typIndex map[types.Type]int
+
+	// position encoding
+	posInfoFormat bool
+	prevFile      string
+	prevLine      int
+
+	// debugging support
+	written int // bytes written
+	indent  int // for trace
+}
+
+// internalError represents an error generated inside this package.
+type internalError string
+
+func (e internalError) Error() string { return "gcimporter: " + string(e) }
+
+func internalErrorf(format string, args ...interface{}) error {
+	return internalError(fmt.Sprintf(format, args...))
+}
+
+// BExportData returns binary export data for pkg.
+// If no file set is provided, position info will be missing.
+func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
+	defer func() {
+		if e := recover(); e != nil {
+			if ierr, ok := e.(internalError); ok {
+				err = ierr
+				return
+			}
+			// Not an internal error; panic again.
+			panic(e)
+		}
+	}()
+
+	p := exporter{
+		fset:          fset,
+		strIndex:      map[string]int{"": 0}, // empty string is mapped to 0
+		pkgIndex:      make(map[*types.Package]int),
+		typIndex:      make(map[types.Type]int),
+		posInfoFormat: true, // TODO(gri) might become a flag, eventually
+	}
+
+	// write version info
+	// The version string must start with "version %d" where %d is the version
+	// number. Additional debugging information may follow after a blank; that
+	// text is ignored by the importer.
+	p.rawStringln(fmt.Sprintf("version %d", exportVersion))
+	var debug string
+	if debugFormat {
+		debug = "debug"
+	}
+	p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
+	p.bool(trackAllTypes)
+	p.bool(p.posInfoFormat)
+
+	// --- generic export data ---
+
+	// populate type map with predeclared "known" types
+	for index, typ := range predeclared {
+		p.typIndex[typ] = index
+	}
+	if len(p.typIndex) != len(predeclared) {
+		return nil, internalError("duplicate entries in type map?")
+	}
+
+	// write package data
+	p.pkg(pkg, true)
+	if trace {
+		p.tracef("\n")
+	}
+
+	// write objects
+	objcount := 0
+	scope := pkg.Scope()
+	for _, name := range scope.Names() {
+		if !ast.IsExported(name) {
+			continue
+		}
+		if trace {
+			p.tracef("\n")
+		}
+		p.obj(scope.Lookup(name))
+		objcount++
+	}
+
+	// indicate end of list
+	if trace {
+		p.tracef("\n")
+	}
+	p.tag(endTag)
+
+	// for self-verification only (redundant)
+	p.int(objcount)
+
+	if trace {
+		p.tracef("\n")
+	}
+
+	// --- end of export data ---
+
+	return p.out.Bytes(), nil
+}
+
+func (p *exporter) pkg(pkg *types.Package, emptypath bool) {
+	if pkg == nil {
+		panic(internalError("unexpected nil pkg"))
+	}
+
+	// if we saw the package before, write its index (>= 0)
+	if i, ok := p.pkgIndex[pkg]; ok {
+		p.index('P', i)
+		return
+	}
+
+	// otherwise, remember the package, write the package tag (< 0) and package data
+	if trace {
+		p.tracef("P%d = { ", len(p.pkgIndex))
+		defer p.tracef("} ")
+	}
+	p.pkgIndex[pkg] = len(p.pkgIndex)
+
+	p.tag(packageTag)
+	p.string(pkg.Name())
+	if emptypath {
+		p.string("")
+	} else {
+		p.string(pkg.Path())
+	}
+}
+
+func (p *exporter) obj(obj types.Object) {
+	switch obj := obj.(type) {
+	case *types.Const:
+		p.tag(constTag)
+		p.pos(obj)
+		p.qualifiedName(obj)
+		p.typ(obj.Type())
+		p.value(obj.Val())
+
+	case *types.TypeName:
+		if obj.IsAlias() {
+			p.tag(aliasTag)
+			p.pos(obj)
+			p.qualifiedName(obj)
+		} else {
+			p.tag(typeTag)
+		}
+		p.typ(obj.Type())
+
+	case *types.Var:
+		p.tag(varTag)
+		p.pos(obj)
+		p.qualifiedName(obj)
+		p.typ(obj.Type())
+
+	case *types.Func:
+		p.tag(funcTag)
+		p.pos(obj)
+		p.qualifiedName(obj)
+		sig := obj.Type().(*types.Signature)
+		p.paramList(sig.Params(), sig.Variadic())
+		p.paramList(sig.Results(), false)
+
+	default:
+		panic(internalErrorf("unexpected object %v (%T)", obj, obj))
+	}
+}
+
+func (p *exporter) pos(obj types.Object) {
+	if !p.posInfoFormat {
+		return
+	}
+
+	file, line := p.fileLine(obj)
+	if file == p.prevFile {
+		// common case: write line delta
+		// delta == 0 means different file or no line change
+		delta := line - p.prevLine
+		p.int(delta)
+		if delta == 0 {
+			p.int(-1) // -1 means no file change
+		}
+	} else {
+		// different file
+		p.int(0)
+		// Encode filename as length of common prefix with previous
+		// filename, followed by (possibly empty) suffix. Filenames
+		// frequently share path prefixes, so this can save a lot
+		// of space and make export data size less dependent on file
+		// path length. The suffix is unlikely to be empty because
+		// file names tend to end in ".go".
+		n := commonPrefixLen(p.prevFile, file)
+		p.int(n)           // n >= 0
+		p.string(file[n:]) // write suffix only
+		p.prevFile = file
+		p.int(line)
+	}
+	p.prevLine = line
+}
+
+func (p *exporter) fileLine(obj types.Object) (file string, line int) {
+	if p.fset != nil {
+		pos := p.fset.Position(obj.Pos())
+		file = pos.Filename
+		line = pos.Line
+	}
+	return
+}
+
+func commonPrefixLen(a, b string) int {
+	if len(a) > len(b) {
+		a, b = b, a
+	}
+	// len(a) <= len(b)
+	i := 0
+	for i < len(a) && a[i] == b[i] {
+		i++
+	}
+	return i
+}
+
+func (p *exporter) qualifiedName(obj types.Object) {
+	p.string(obj.Name())
+	p.pkg(obj.Pkg(), false)
+}
+
+func (p *exporter) typ(t types.Type) {
+	if t == nil {
+		panic(internalError("nil type"))
+	}
+
+	// Possible optimization: Anonymous pointer types *T where
+	// T is a named type are common. We could canonicalize all
+	// such types *T to a single type PT = *T. This would lead
+	// to at most one *T entry in typIndex, and all future *T's
+	// would be encoded as the respective index directly. Would
+	// save 1 byte (pointerTag) per *T and reduce the typIndex
+	// size (at the cost of a canonicalization map). We can do
+	// this later, without encoding format change.
+
+	// if we saw the type before, write its index (>= 0)
+	if i, ok := p.typIndex[t]; ok {
+		p.index('T', i)
+		return
+	}
+
+	// otherwise, remember the type, write the type tag (< 0) and type data
+	if trackAllTypes {
+		if trace {
+			p.tracef("T%d = {>\n", len(p.typIndex))
+			defer p.tracef("<\n} ")
+		}
+		p.typIndex[t] = len(p.typIndex)
+	}
+
+	switch t := t.(type) {
+	case *types.Named:
+		if !trackAllTypes {
+			// if we don't track all types, track named types now
+			p.typIndex[t] = len(p.typIndex)
+		}
+
+		p.tag(namedTag)
+		p.pos(t.Obj())
+		p.qualifiedName(t.Obj())
+		p.typ(t.Underlying())
+		if !types.IsInterface(t) {
+			p.assocMethods(t)
+		}
+
+	case *types.Array:
+		p.tag(arrayTag)
+		p.int64(t.Len())
+		p.typ(t.Elem())
+
+	case *types.Slice:
+		p.tag(sliceTag)
+		p.typ(t.Elem())
+
+	case *dddSlice:
+		p.tag(dddTag)
+		p.typ(t.elem)
+
+	case *types.Struct:
+		p.tag(structTag)
+		p.fieldList(t)
+
+	case *types.Pointer:
+		p.tag(pointerTag)
+		p.typ(t.Elem())
+
+	case *types.Signature:
+		p.tag(signatureTag)
+		p.paramList(t.Params(), t.Variadic())
+		p.paramList(t.Results(), false)
+
+	case *types.Interface:
+		p.tag(interfaceTag)
+		p.iface(t)
+
+	case *types.Map:
+		p.tag(mapTag)
+		p.typ(t.Key())
+		p.typ(t.Elem())
+
+	case *types.Chan:
+		p.tag(chanTag)
+		p.int(int(3 - t.Dir())) // hack
+		p.typ(t.Elem())
+
+	default:
+		panic(internalErrorf("unexpected type %T: %s", t, t))
+	}
+}
+
+func (p *exporter) assocMethods(named *types.Named) {
+	// Sort methods (for determinism).
+	var methods []*types.Func
+	for i := 0; i < named.NumMethods(); i++ {
+		methods = append(methods, named.Method(i))
+	}
+	sort.Sort(methodsByName(methods))
+
+	p.int(len(methods))
+
+	if trace && methods != nil {
+		p.tracef("associated methods {>\n")
+	}
+
+	for i, m := range methods {
+		if trace && i > 0 {
+			p.tracef("\n")
+		}
+
+		p.pos(m)
+		name := m.Name()
+		p.string(name)
+		if !exported(name) {
+			p.pkg(m.Pkg(), false)
+		}
+
+		sig := m.Type().(*types.Signature)
+		p.paramList(types.NewTuple(sig.Recv()), false)
+		p.paramList(sig.Params(), sig.Variadic())
+		p.paramList(sig.Results(), false)
+		p.int(0) // dummy value for go:nointerface pragma - ignored by importer
+	}
+
+	if trace && methods != nil {
+		p.tracef("<\n} ")
+	}
+}
+
+type methodsByName []*types.Func
+
+func (x methodsByName) Len() int           { return len(x) }
+func (x methodsByName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x methodsByName) Less(i, j int) bool { return x[i].Name() < x[j].Name() }
+
+func (p *exporter) fieldList(t *types.Struct) {
+	if trace && t.NumFields() > 0 {
+		p.tracef("fields {>\n")
+		defer p.tracef("<\n} ")
+	}
+
+	p.int(t.NumFields())
+	for i := 0; i < t.NumFields(); i++ {
+		if trace && i > 0 {
+			p.tracef("\n")
+		}
+		p.field(t.Field(i))
+		p.string(t.Tag(i))
+	}
+}
+
+func (p *exporter) field(f *types.Var) {
+	if !f.IsField() {
+		panic(internalError("field expected"))
+	}
+
+	p.pos(f)
+	p.fieldName(f)
+	p.typ(f.Type())
+}
+
+func (p *exporter) iface(t *types.Interface) {
+	// TODO(gri): enable importer to load embedded interfaces,
+	// then emit Embeddeds and ExplicitMethods separately here.
+	p.int(0)
+
+	n := t.NumMethods()
+	if trace && n > 0 {
+		p.tracef("methods {>\n")
+		defer p.tracef("<\n} ")
+	}
+	p.int(n)
+	for i := 0; i < n; i++ {
+		if trace && i > 0 {
+			p.tracef("\n")
+		}
+		p.method(t.Method(i))
+	}
+}
+
+func (p *exporter) method(m *types.Func) {
+	sig := m.Type().(*types.Signature)
+	if sig.Recv() == nil {
+		panic(internalError("method expected"))
+	}
+
+	p.pos(m)
+	p.string(m.Name())
+	if m.Name() != "_" && !ast.IsExported(m.Name()) {
+		p.pkg(m.Pkg(), false)
+	}
+
+	// interface method; no need to encode receiver.
+	p.paramList(sig.Params(), sig.Variadic())
+	p.paramList(sig.Results(), false)
+}
+
+func (p *exporter) fieldName(f *types.Var) {
+	name := f.Name()
+
+	if f.Anonymous() {
+		// anonymous field - we distinguish between 3 cases:
+		// 1) field name matches base type name and is exported
+		// 2) field name matches base type name and is not exported
+		// 3) field name doesn't match base type name (alias name)
+		bname := basetypeName(f.Type())
+		if name == bname {
+			if ast.IsExported(name) {
+				name = "" // 1) we don't need to know the field name or package
+			} else {
+				name = "?" // 2) use unexported name "?" to force package export
+			}
+		} else {
+			// 3) indicate alias and export name as is
+			// (this requires an extra "@" but this is a rare case)
+			p.string("@")
+		}
+	}
+
+	p.string(name)
+	if name != "" && !ast.IsExported(name) {
+		p.pkg(f.Pkg(), false)
+	}
+}
+
+func basetypeName(typ types.Type) string {
+	switch typ := deref(typ).(type) {
+	case *types.Basic:
+		return typ.Name()
+	case *types.Named:
+		return typ.Obj().Name()
+	default:
+		return "" // unnamed type
+	}
+}
+
+func (p *exporter) paramList(params *types.Tuple, variadic bool) {
+	// use negative length to indicate unnamed parameters
+	// (look at the first parameter only since either all
+	// names are present or all are absent)
+	n := params.Len()
+	if n > 0 && params.At(0).Name() == "" {
+		n = -n
+	}
+	p.int(n)
+	for i := 0; i < params.Len(); i++ {
+		q := params.At(i)
+		t := q.Type()
+		if variadic && i == params.Len()-1 {
+			t = &dddSlice{t.(*types.Slice).Elem()}
+		}
+		p.typ(t)
+		if n > 0 {
+			name := q.Name()
+			p.string(name)
+			if name != "_" {
+				p.pkg(q.Pkg(), false)
+			}
+		}
+		p.string("") // no compiler-specific info
+	}
+}
+
+func (p *exporter) value(x constant.Value) {
+	if trace {
+		p.tracef("= ")
+	}
+
+	switch x.Kind() {
+	case constant.Bool:
+		tag := falseTag
+		if constant.BoolVal(x) {
+			tag = trueTag
+		}
+		p.tag(tag)
+
+	case constant.Int:
+		if v, exact := constant.Int64Val(x); exact {
+			// common case: x fits into an int64 - use compact encoding
+			p.tag(int64Tag)
+			p.int64(v)
+			return
+		}
+		// uncommon case: large x - use float encoding
+		// (powers of 2 will be encoded efficiently with exponent)
+		p.tag(floatTag)
+		p.float(constant.ToFloat(x))
+
+	case constant.Float:
+		p.tag(floatTag)
+		p.float(x)
+
+	case constant.Complex:
+		p.tag(complexTag)
+		p.float(constant.Real(x))
+		p.float(constant.Imag(x))
+
+	case constant.String:
+		p.tag(stringTag)
+		p.string(constant.StringVal(x))
+
+	case constant.Unknown:
+		// package contains type errors
+		p.tag(unknownTag)
+
+	default:
+		panic(internalErrorf("unexpected value %v (%T)", x, x))
+	}
+}
+
+func (p *exporter) float(x constant.Value) {
+	if x.Kind() != constant.Float {
+		panic(internalErrorf("unexpected constant %v, want float", x))
+	}
+	// extract sign (there is no -0)
+	sign := constant.Sign(x)
+	if sign == 0 {
+		// x == 0
+		p.int(0)
+		return
+	}
+	// x != 0
+
+	var f big.Float
+	if v, exact := constant.Float64Val(x); exact {
+		// float64
+		f.SetFloat64(v)
+	} else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
+		// TODO(gri): add big.Rat accessor to constant.Value.
+		r := valueToRat(num)
+		f.SetRat(r.Quo(r, valueToRat(denom)))
+	} else {
+		// Value too large to represent as a fraction => inaccessible.
+		// TODO(gri): add big.Float accessor to constant.Value.
+		f.SetFloat64(math.MaxFloat64) // FIXME
+	}
+
+	// extract exponent such that 0.5 <= m < 1.0
+	var m big.Float
+	exp := f.MantExp(&m)
+
+	// extract mantissa as *big.Int
+	// - set exponent large enough so mant satisfies mant.IsInt()
+	// - get *big.Int from mant
+	m.SetMantExp(&m, int(m.MinPrec()))
+	mant, acc := m.Int(nil)
+	if acc != big.Exact {
+		panic(internalError("internal error"))
+	}
+
+	p.int(sign)
+	p.int(exp)
+	p.string(string(mant.Bytes()))
+}
+
+func valueToRat(x constant.Value) *big.Rat {
+	// Convert little-endian to big-endian.
+	// I can't believe this is necessary.
+	bytes := constant.Bytes(x)
+	for i := 0; i < len(bytes)/2; i++ {
+		bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
+	}
+	return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
+}
+
+func (p *exporter) bool(b bool) bool {
+	if trace {
+		p.tracef("[")
+		defer p.tracef("= %v] ", b)
+	}
+
+	x := 0
+	if b {
+		x = 1
+	}
+	p.int(x)
+	return b
+}
+
+// ----------------------------------------------------------------------------
+// Low-level encoders
+
+func (p *exporter) index(marker byte, index int) {
+	if index < 0 {
+		panic(internalError("invalid index < 0"))
+	}
+	if debugFormat {
+		p.marker('t')
+	}
+	if trace {
+		p.tracef("%c%d ", marker, index)
+	}
+	p.rawInt64(int64(index))
+}
+
+func (p *exporter) tag(tag int) {
+	if tag >= 0 {
+		panic(internalError("invalid tag >= 0"))
+	}
+	if debugFormat {
+		p.marker('t')
+	}
+	if trace {
+		p.tracef("%s ", tagString[-tag])
+	}
+	p.rawInt64(int64(tag))
+}
+
+func (p *exporter) int(x int) {
+	p.int64(int64(x))
+}
+
+func (p *exporter) int64(x int64) {
+	if debugFormat {
+		p.marker('i')
+	}
+	if trace {
+		p.tracef("%d ", x)
+	}
+	p.rawInt64(x)
+}
+
+func (p *exporter) string(s string) {
+	if debugFormat {
+		p.marker('s')
+	}
+	if trace {
+		p.tracef("%q ", s)
+	}
+	// if we saw the string before, write its index (>= 0)
+	// (the empty string is mapped to 0)
+	if i, ok := p.strIndex[s]; ok {
+		p.rawInt64(int64(i))
+		return
+	}
+	// otherwise, remember string and write its negative length and bytes
+	p.strIndex[s] = len(p.strIndex)
+	p.rawInt64(-int64(len(s)))
+	for i := 0; i < len(s); i++ {
+		p.rawByte(s[i])
+	}
+}
+
+// marker emits a marker byte and position information which makes
+// it easy for a reader to detect if it is "out of sync". Used for
+// debugFormat format only.
+func (p *exporter) marker(m byte) {
+	p.rawByte(m)
+	// Enable this for help tracking down the location
+	// of an incorrect marker when running in debugFormat.
+	if false && trace {
+		p.tracef("#%d ", p.written)
+	}
+	p.rawInt64(int64(p.written))
+}
+
+// rawInt64 should only be used by low-level encoders.
+func (p *exporter) rawInt64(x int64) {
+	var tmp [binary.MaxVarintLen64]byte
+	n := binary.PutVarint(tmp[:], x)
+	for i := 0; i < n; i++ {
+		p.rawByte(tmp[i])
+	}
+}
+
+// rawStringln should only be used to emit the initial version string.
+func (p *exporter) rawStringln(s string) {
+	for i := 0; i < len(s); i++ {
+		p.rawByte(s[i])
+	}
+	p.rawByte('\n')
+}
+
+// rawByte is the bottleneck interface to write to p.out.
+// rawByte escapes b as follows (any encoding does that
+// hides '$'):
+//
+//	'$'  => '|' 'S'
+//	'|'  => '|' '|'
+//
+// Necessary so other tools can find the end of the
+// export data by searching for "$$".
+// rawByte should only be used by low-level encoders.
+func (p *exporter) rawByte(b byte) {
+	switch b {
+	case '$':
+		// write '$' as '|' 'S'
+		b = 'S'
+		fallthrough
+	case '|':
+		// write '|' as '|' '|'
+		p.out.WriteByte('|')
+		p.written++
+	}
+	p.out.WriteByte(b)
+	p.written++
+}
+
+// tracef is like fmt.Printf but it rewrites the format string
+// to take care of indentation.
+func (p *exporter) tracef(format string, args ...interface{}) {
+	if strings.ContainsAny(format, "<>\n") {
+		var buf bytes.Buffer
+		for i := 0; i < len(format); i++ {
+			// no need to deal with runes
+			ch := format[i]
+			switch ch {
+			case '>':
+				p.indent++
+				continue
+			case '<':
+				p.indent--
+				continue
+			}
+			buf.WriteByte(ch)
+			if ch == '\n' {
+				for j := p.indent; j > 0; j-- {
+					buf.WriteString(".  ")
+				}
+			}
+		}
+		format = buf.String()
+	}
+	fmt.Printf(format, args...)
+}
+
+// Debugging support.
+// (tagString is only used when tracing is enabled)
+var tagString = [...]string{
+	// Packages
+	-packageTag: "package",
+
+	// Types
+	-namedTag:     "named type",
+	-arrayTag:     "array",
+	-sliceTag:     "slice",
+	-dddTag:       "ddd",
+	-structTag:    "struct",
+	-pointerTag:   "pointer",
+	-signatureTag: "signature",
+	-interfaceTag: "interface",
+	-mapTag:       "map",
+	-chanTag:      "chan",
+
+	// Values
+	-falseTag:    "false",
+	-trueTag:     "true",
+	-int64Tag:    "int64",
+	-floatTag:    "float",
+	-fractionTag: "fraction",
+	-complexTag:  "complex",
+	-stringTag:   "string",
+	-unknownTag:  "unknown",
+
+	// Type aliases
+	-aliasTag: "alias",
+}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
new file mode 100644
index 0000000000000000000000000000000000000000..b31eacfc0fc9540045cc0035717424c0b3d3d20c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
@@ -0,0 +1,1028 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go.
+
+package gcimporter
+
+import (
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+type importer struct {
+	imports    map[string]*types.Package
+	data       []byte
+	importpath string
+	buf        []byte // for reading strings
+	version    int    // export format version
+
+	// object lists
+	strList       []string           // in order of appearance
+	pathList      []string           // in order of appearance
+	pkgList       []*types.Package   // in order of appearance
+	typList       []types.Type       // in order of appearance
+	interfaceList []*types.Interface // for delayed completion only
+	trackAllTypes bool
+
+	// position encoding
+	posInfoFormat bool
+	prevFile      string
+	prevLine      int
+	fake          fakeFileSet
+
+	// debugging support
+	debugFormat bool
+	read        int // bytes read
+}
+
+// BImportData imports a package from the serialized package data
+// and returns the number of bytes consumed and a reference to the package.
+// If the export data version is not recognized or the format is otherwise
+// compromised, an error is returned.
+func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
+	// catch panics and return them as errors
+	const currentVersion = 6
+	version := -1 // unknown version
+	defer func() {
+		if e := recover(); e != nil {
+			// Return a (possibly nil or incomplete) package unchanged (see #16088).
+			if version > currentVersion {
+				err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
+			} else {
+				err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
+			}
+		}
+	}()
+
+	p := importer{
+		imports:    imports,
+		data:       data,
+		importpath: path,
+		version:    version,
+		strList:    []string{""}, // empty string is mapped to 0
+		pathList:   []string{""}, // empty string is mapped to 0
+		fake: fakeFileSet{
+			fset:  fset,
+			files: make(map[string]*token.File),
+		},
+	}
+
+	// read version info
+	var versionstr string
+	if b := p.rawByte(); b == 'c' || b == 'd' {
+		// Go1.7 encoding; first byte encodes low-level
+		// encoding format (compact vs debug).
+		// For backward-compatibility only (avoid problems with
+		// old installed packages). Newly compiled packages use
+		// the extensible format string.
+		// TODO(gri) Remove this support eventually; after Go1.8.
+		if b == 'd' {
+			p.debugFormat = true
+		}
+		p.trackAllTypes = p.rawByte() == 'a'
+		p.posInfoFormat = p.int() != 0
+		versionstr = p.string()
+		if versionstr == "v1" {
+			version = 0
+		}
+	} else {
+		// Go1.8 extensible encoding
+		// read version string and extract version number (ignore anything after the version number)
+		versionstr = p.rawStringln(b)
+		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
+			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
+				version = v
+			}
+		}
+	}
+	p.version = version
+
+	// read version specific flags - extend as necessary
+	switch p.version {
+	// case currentVersion:
+	// 	...
+	//	fallthrough
+	case currentVersion, 5, 4, 3, 2, 1:
+		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
+		p.trackAllTypes = p.int() != 0
+		p.posInfoFormat = p.int() != 0
+	case 0:
+		// Go1.7 encoding format - nothing to do here
+	default:
+		errorf("unknown bexport format version %d (%q)", p.version, versionstr)
+	}
+
+	// --- generic export data ---
+
+	// populate typList with predeclared "known" types
+	p.typList = append(p.typList, predeclared...)
+
+	// read package data
+	pkg = p.pkg()
+
+	// read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go)
+	objcount := 0
+	for {
+		tag := p.tagOrIndex()
+		if tag == endTag {
+			break
+		}
+		p.obj(tag)
+		objcount++
+	}
+
+	// self-verification
+	if count := p.int(); count != objcount {
+		errorf("got %d objects; want %d", objcount, count)
+	}
+
+	// ignore compiler-specific import data
+
+	// complete interfaces
+	// TODO(gri) re-investigate if we still need to do this in a delayed fashion
+	for _, typ := range p.interfaceList {
+		typ.Complete()
+	}
+
+	// record all referenced packages as imports
+	list := append(([]*types.Package)(nil), p.pkgList[1:]...)
+	sort.Sort(byPath(list))
+	pkg.SetImports(list)
+
+	// package was imported completely and without errors
+	pkg.MarkComplete()
+
+	return p.read, pkg, nil
+}
+
+func errorf(format string, args ...interface{}) {
+	panic(fmt.Sprintf(format, args...))
+}
+
+func (p *importer) pkg() *types.Package {
+	// if the package was seen before, i is its index (>= 0)
+	i := p.tagOrIndex()
+	if i >= 0 {
+		return p.pkgList[i]
+	}
+
+	// otherwise, i is the package tag (< 0)
+	if i != packageTag {
+		errorf("unexpected package tag %d version %d", i, p.version)
+	}
+
+	// read package data
+	name := p.string()
+	var path string
+	if p.version >= 5 {
+		path = p.path()
+	} else {
+		path = p.string()
+	}
+	if p.version >= 6 {
+		p.int() // package height; unused by go/types
+	}
+
+	// we should never see an empty package name
+	if name == "" {
+		errorf("empty package name in import")
+	}
+
+	// an empty path denotes the package we are currently importing;
+	// it must be the first package we see
+	if (path == "") != (len(p.pkgList) == 0) {
+		errorf("package path %q for pkg index %d", path, len(p.pkgList))
+	}
+
+	// if the package was imported before, use that one; otherwise create a new one
+	if path == "" {
+		path = p.importpath
+	}
+	pkg := p.imports[path]
+	if pkg == nil {
+		pkg = types.NewPackage(path, name)
+		p.imports[path] = pkg
+	} else if pkg.Name() != name {
+		errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path)
+	}
+	p.pkgList = append(p.pkgList, pkg)
+
+	return pkg
+}
+
+// objTag returns the tag value for each object kind.
+func objTag(obj types.Object) int {
+	switch obj.(type) {
+	case *types.Const:
+		return constTag
+	case *types.TypeName:
+		return typeTag
+	case *types.Var:
+		return varTag
+	case *types.Func:
+		return funcTag
+	default:
+		errorf("unexpected object: %v (%T)", obj, obj) // panics
+		panic("unreachable")
+	}
+}
+
+func sameObj(a, b types.Object) bool {
+	// Because unnamed types are not canonicalized, we cannot simply compare types for
+	// (pointer) identity.
+	// Ideally we'd check equality of constant values as well, but this is good enough.
+	return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
+}
+
+func (p *importer) declare(obj types.Object) {
+	pkg := obj.Pkg()
+	if alt := pkg.Scope().Insert(obj); alt != nil {
+		// This can only trigger if we import a (non-type) object a second time.
+		// Excluding type aliases, this cannot happen because 1) we only import a package
+		// once; and b) we ignore compiler-specific export data which may contain
+		// functions whose inlined function bodies refer to other functions that
+		// were already imported.
+		// However, type aliases require reexporting the original type, so we need
+		// to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
+		// method importer.obj, switch case importing functions).
+		// TODO(gri) review/update this comment once the gc compiler handles type aliases.
+		if !sameObj(obj, alt) {
+			errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt)
+		}
+	}
+}
+
+func (p *importer) obj(tag int) {
+	switch tag {
+	case constTag:
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		typ := p.typ(nil, nil)
+		val := p.value()
+		p.declare(types.NewConst(pos, pkg, name, typ, val))
+
+	case aliasTag:
+		// TODO(gri) verify type alias hookup is correct
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		typ := p.typ(nil, nil)
+		p.declare(types.NewTypeName(pos, pkg, name, typ))
+
+	case typeTag:
+		p.typ(nil, nil)
+
+	case varTag:
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		typ := p.typ(nil, nil)
+		p.declare(types.NewVar(pos, pkg, name, typ))
+
+	case funcTag:
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		params, isddd := p.paramList()
+		result, _ := p.paramList()
+		sig := types.NewSignature(nil, params, result, isddd)
+		p.declare(types.NewFunc(pos, pkg, name, sig))
+
+	default:
+		errorf("unexpected object tag %d", tag)
+	}
+}
+
+const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
+
+func (p *importer) pos() token.Pos {
+	if !p.posInfoFormat {
+		return token.NoPos
+	}
+
+	file := p.prevFile
+	line := p.prevLine
+	delta := p.int()
+	line += delta
+	if p.version >= 5 {
+		if delta == deltaNewFile {
+			if n := p.int(); n >= 0 {
+				// file changed
+				file = p.path()
+				line = n
+			}
+		}
+	} else {
+		if delta == 0 {
+			if n := p.int(); n >= 0 {
+				// file changed
+				file = p.prevFile[:n] + p.string()
+				line = p.int()
+			}
+		}
+	}
+	p.prevFile = file
+	p.prevLine = line
+
+	return p.fake.pos(file, line)
+}
+
+// Synthesize a token.Pos
+type fakeFileSet struct {
+	fset  *token.FileSet
+	files map[string]*token.File
+}
+
+func (s *fakeFileSet) pos(file string, line int) token.Pos {
+	// Since we don't know the set of needed file positions, we
+	// reserve maxlines positions per file.
+	const maxlines = 64 * 1024
+	f := s.files[file]
+	if f == nil {
+		f = s.fset.AddFile(file, -1, maxlines)
+		s.files[file] = f
+		// Allocate the fake linebreak indices on first use.
+		// TODO(adonovan): opt: save ~512KB using a more complex scheme?
+		fakeLinesOnce.Do(func() {
+			fakeLines = make([]int, maxlines)
+			for i := range fakeLines {
+				fakeLines[i] = i
+			}
+		})
+		f.SetLines(fakeLines)
+	}
+
+	if line > maxlines {
+		line = 1
+	}
+
+	// Treat the file as if it contained only newlines
+	// and column=1: use the line number as the offset.
+	return f.Pos(line - 1)
+}
+
+var (
+	fakeLines     []int
+	fakeLinesOnce sync.Once
+)
+
+func (p *importer) qualifiedName() (pkg *types.Package, name string) {
+	name = p.string()
+	pkg = p.pkg()
+	return
+}
+
+func (p *importer) record(t types.Type) {
+	p.typList = append(p.typList, t)
+}
+
+// A dddSlice is a types.Type representing ...T parameters.
+// It only appears for parameter types and does not escape
+// the importer.
+type dddSlice struct {
+	elem types.Type
+}
+
+func (t *dddSlice) Underlying() types.Type { return t }
+func (t *dddSlice) String() string         { return "..." + t.elem.String() }
+
+// parent is the package which declared the type; parent == nil means
+// the package currently imported. The parent package is needed for
+// exported struct fields and interface methods which don't contain
+// explicit package information in the export data.
+//
+// A non-nil tname is used as the "owner" of the result type; i.e.,
+// the result type is the underlying type of tname. tname is used
+// to give interface methods a named receiver type where possible.
+func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type {
+	// if the type was seen before, i is its index (>= 0)
+	i := p.tagOrIndex()
+	if i >= 0 {
+		return p.typList[i]
+	}
+
+	// otherwise, i is the type tag (< 0)
+	switch i {
+	case namedTag:
+		// read type object
+		pos := p.pos()
+		parent, name := p.qualifiedName()
+		scope := parent.Scope()
+		obj := scope.Lookup(name)
+
+		// if the object doesn't exist yet, create and insert it
+		if obj == nil {
+			obj = types.NewTypeName(pos, parent, name, nil)
+			scope.Insert(obj)
+		}
+
+		if _, ok := obj.(*types.TypeName); !ok {
+			errorf("pkg = %s, name = %s => %s", parent, name, obj)
+		}
+
+		// associate new named type with obj if it doesn't exist yet
+		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
+
+		// but record the existing type, if any
+		tname := obj.Type().(*types.Named) // tname is either t0 or the existing type
+		p.record(tname)
+
+		// read underlying type
+		t0.SetUnderlying(p.typ(parent, t0))
+
+		// interfaces don't have associated methods
+		if types.IsInterface(t0) {
+			return tname
+		}
+
+		// read associated methods
+		for i := p.int(); i > 0; i-- {
+			// TODO(gri) replace this with something closer to fieldName
+			pos := p.pos()
+			name := p.string()
+			if !exported(name) {
+				p.pkg()
+			}
+
+			recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
+			params, isddd := p.paramList()
+			result, _ := p.paramList()
+			p.int() // go:nointerface pragma - discarded
+
+			sig := types.NewSignature(recv.At(0), params, result, isddd)
+			t0.AddMethod(types.NewFunc(pos, parent, name, sig))
+		}
+
+		return tname
+
+	case arrayTag:
+		t := new(types.Array)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		n := p.int64()
+		*t = *types.NewArray(p.typ(parent, nil), n)
+		return t
+
+	case sliceTag:
+		t := new(types.Slice)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		*t = *types.NewSlice(p.typ(parent, nil))
+		return t
+
+	case dddTag:
+		t := new(dddSlice)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		t.elem = p.typ(parent, nil)
+		return t
+
+	case structTag:
+		t := new(types.Struct)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		*t = *types.NewStruct(p.fieldList(parent))
+		return t
+
+	case pointerTag:
+		t := new(types.Pointer)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		*t = *types.NewPointer(p.typ(parent, nil))
+		return t
+
+	case signatureTag:
+		t := new(types.Signature)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		params, isddd := p.paramList()
+		result, _ := p.paramList()
+		*t = *types.NewSignature(nil, params, result, isddd)
+		return t
+
+	case interfaceTag:
+		// Create a dummy entry in the type list. This is safe because we
+		// cannot expect the interface type to appear in a cycle, as any
+		// such cycle must contain a named type which would have been
+		// first defined earlier.
+		// TODO(gri) Is this still true now that we have type aliases?
+		// See issue #23225.
+		n := len(p.typList)
+		if p.trackAllTypes {
+			p.record(nil)
+		}
+
+		var embeddeds []types.Type
+		for n := p.int(); n > 0; n-- {
+			p.pos()
+			embeddeds = append(embeddeds, p.typ(parent, nil))
+		}
+
+		t := newInterface(p.methodList(parent, tname), embeddeds)
+		p.interfaceList = append(p.interfaceList, t)
+		if p.trackAllTypes {
+			p.typList[n] = t
+		}
+		return t
+
+	case mapTag:
+		t := new(types.Map)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		key := p.typ(parent, nil)
+		val := p.typ(parent, nil)
+		*t = *types.NewMap(key, val)
+		return t
+
+	case chanTag:
+		t := new(types.Chan)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		dir := chanDir(p.int())
+		val := p.typ(parent, nil)
+		*t = *types.NewChan(dir, val)
+		return t
+
+	default:
+		errorf("unexpected type tag %d", i) // panics
+		panic("unreachable")
+	}
+}
+
+func chanDir(d int) types.ChanDir {
+	// tag values must match the constants in cmd/compile/internal/gc/go.go
+	switch d {
+	case 1 /* Crecv */ :
+		return types.RecvOnly
+	case 2 /* Csend */ :
+		return types.SendOnly
+	case 3 /* Cboth */ :
+		return types.SendRecv
+	default:
+		errorf("unexpected channel dir %d", d)
+		return 0
+	}
+}
+
+func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
+	if n := p.int(); n > 0 {
+		fields = make([]*types.Var, n)
+		tags = make([]string, n)
+		for i := range fields {
+			fields[i], tags[i] = p.field(parent)
+		}
+	}
+	return
+}
+
+func (p *importer) field(parent *types.Package) (*types.Var, string) {
+	pos := p.pos()
+	pkg, name, alias := p.fieldName(parent)
+	typ := p.typ(parent, nil)
+	tag := p.string()
+
+	anonymous := false
+	if name == "" {
+		// anonymous field - typ must be T or *T and T must be a type name
+		switch typ := deref(typ).(type) {
+		case *types.Basic: // basic types are named types
+			pkg = nil // // objects defined in Universe scope have no package
+			name = typ.Name()
+		case *types.Named:
+			name = typ.Obj().Name()
+		default:
+			errorf("named base type expected")
+		}
+		anonymous = true
+	} else if alias {
+		// anonymous field: we have an explicit name because it's an alias
+		anonymous = true
+	}
+
+	return types.NewField(pos, pkg, name, typ, anonymous), tag
+}
+
+func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) {
+	if n := p.int(); n > 0 {
+		methods = make([]*types.Func, n)
+		for i := range methods {
+			methods[i] = p.method(parent, baseType)
+		}
+	}
+	return
+}
+
+func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func {
+	pos := p.pos()
+	pkg, name, _ := p.fieldName(parent)
+	// If we don't have a baseType, use a nil receiver.
+	// A receiver using the actual interface type (which
+	// we don't know yet) will be filled in when we call
+	// types.Interface.Complete.
+	var recv *types.Var
+	if baseType != nil {
+		recv = types.NewVar(token.NoPos, parent, "", baseType)
+	}
+	params, isddd := p.paramList()
+	result, _ := p.paramList()
+	sig := types.NewSignature(recv, params, result, isddd)
+	return types.NewFunc(pos, pkg, name, sig)
+}
+
+func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) {
+	name = p.string()
+	pkg = parent
+	if pkg == nil {
+		// use the imported package instead
+		pkg = p.pkgList[0]
+	}
+	if p.version == 0 && name == "_" {
+		// version 0 didn't export a package for _ fields
+		return
+	}
+	switch name {
+	case "":
+		// 1) field name matches base type name and is exported: nothing to do
+	case "?":
+		// 2) field name matches base type name and is not exported: need package
+		name = ""
+		pkg = p.pkg()
+	case "@":
+		// 3) field name doesn't match type name (alias)
+		name = p.string()
+		alias = true
+		fallthrough
+	default:
+		if !exported(name) {
+			pkg = p.pkg()
+		}
+	}
+	return
+}
+
+func (p *importer) paramList() (*types.Tuple, bool) {
+	n := p.int()
+	if n == 0 {
+		return nil, false
+	}
+	// negative length indicates unnamed parameters
+	named := true
+	if n < 0 {
+		n = -n
+		named = false
+	}
+	// n > 0
+	params := make([]*types.Var, n)
+	isddd := false
+	for i := range params {
+		params[i], isddd = p.param(named)
+	}
+	return types.NewTuple(params...), isddd
+}
+
+func (p *importer) param(named bool) (*types.Var, bool) {
+	t := p.typ(nil, nil)
+	td, isddd := t.(*dddSlice)
+	if isddd {
+		t = types.NewSlice(td.elem)
+	}
+
+	var pkg *types.Package
+	var name string
+	if named {
+		name = p.string()
+		if name == "" {
+			errorf("expected named parameter")
+		}
+		if name != "_" {
+			pkg = p.pkg()
+		}
+		if i := strings.Index(name, "·"); i > 0 {
+			name = name[:i] // cut off gc-specific parameter numbering
+		}
+	}
+
+	// read and discard compiler-specific info
+	p.string()
+
+	return types.NewVar(token.NoPos, pkg, name, t), isddd
+}
+
+func exported(name string) bool {
+	ch, _ := utf8.DecodeRuneInString(name)
+	return unicode.IsUpper(ch)
+}
+
+func (p *importer) value() constant.Value {
+	switch tag := p.tagOrIndex(); tag {
+	case falseTag:
+		return constant.MakeBool(false)
+	case trueTag:
+		return constant.MakeBool(true)
+	case int64Tag:
+		return constant.MakeInt64(p.int64())
+	case floatTag:
+		return p.float()
+	case complexTag:
+		re := p.float()
+		im := p.float()
+		return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+	case stringTag:
+		return constant.MakeString(p.string())
+	case unknownTag:
+		return constant.MakeUnknown()
+	default:
+		errorf("unexpected value tag %d", tag) // panics
+		panic("unreachable")
+	}
+}
+
+func (p *importer) float() constant.Value {
+	sign := p.int()
+	if sign == 0 {
+		return constant.MakeInt64(0)
+	}
+
+	exp := p.int()
+	mant := []byte(p.string()) // big endian
+
+	// remove leading 0's if any
+	for len(mant) > 0 && mant[0] == 0 {
+		mant = mant[1:]
+	}
+
+	// convert to little endian
+	// TODO(gri) go/constant should have a more direct conversion function
+	//           (e.g., once it supports a big.Float based implementation)
+	for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
+		mant[i], mant[j] = mant[j], mant[i]
+	}
+
+	// adjust exponent (constant.MakeFromBytes creates an integer value,
+	// but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
+	exp -= len(mant) << 3
+	if len(mant) > 0 {
+		for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
+			exp++
+		}
+	}
+
+	x := constant.MakeFromBytes(mant)
+	switch {
+	case exp < 0:
+		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
+		x = constant.BinaryOp(x, token.QUO, d)
+	case exp > 0:
+		x = constant.Shift(x, token.SHL, uint(exp))
+	}
+
+	if sign < 0 {
+		x = constant.UnaryOp(token.SUB, x, 0)
+	}
+	return x
+}
+
+// ----------------------------------------------------------------------------
+// Low-level decoders
+
+func (p *importer) tagOrIndex() int {
+	if p.debugFormat {
+		p.marker('t')
+	}
+
+	return int(p.rawInt64())
+}
+
+func (p *importer) int() int {
+	x := p.int64()
+	if int64(int(x)) != x {
+		errorf("exported integer too large")
+	}
+	return int(x)
+}
+
+func (p *importer) int64() int64 {
+	if p.debugFormat {
+		p.marker('i')
+	}
+
+	return p.rawInt64()
+}
+
+func (p *importer) path() string {
+	if p.debugFormat {
+		p.marker('p')
+	}
+	// if the path was seen before, i is its index (>= 0)
+	// (the empty string is at index 0)
+	i := p.rawInt64()
+	if i >= 0 {
+		return p.pathList[i]
+	}
+	// otherwise, i is the negative path length (< 0)
+	a := make([]string, -i)
+	for n := range a {
+		a[n] = p.string()
+	}
+	s := strings.Join(a, "/")
+	p.pathList = append(p.pathList, s)
+	return s
+}
+
+func (p *importer) string() string {
+	if p.debugFormat {
+		p.marker('s')
+	}
+	// if the string was seen before, i is its index (>= 0)
+	// (the empty string is at index 0)
+	i := p.rawInt64()
+	if i >= 0 {
+		return p.strList[i]
+	}
+	// otherwise, i is the negative string length (< 0)
+	if n := int(-i); n <= cap(p.buf) {
+		p.buf = p.buf[:n]
+	} else {
+		p.buf = make([]byte, n)
+	}
+	for i := range p.buf {
+		p.buf[i] = p.rawByte()
+	}
+	s := string(p.buf)
+	p.strList = append(p.strList, s)
+	return s
+}
+
+func (p *importer) marker(want byte) {
+	if got := p.rawByte(); got != want {
+		errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
+	}
+
+	pos := p.read
+	if n := int(p.rawInt64()); n != pos {
+		errorf("incorrect position: got %d; want %d", n, pos)
+	}
+}
+
+// rawInt64 should only be used by low-level decoders.
+func (p *importer) rawInt64() int64 {
+	i, err := binary.ReadVarint(p)
+	if err != nil {
+		errorf("read error: %v", err)
+	}
+	return i
+}
+
+// rawStringln should only be used to read the initial version string.
+func (p *importer) rawStringln(b byte) string {
+	p.buf = p.buf[:0]
+	for b != '\n' {
+		p.buf = append(p.buf, b)
+		b = p.rawByte()
+	}
+	return string(p.buf)
+}
+
+// needed for binary.ReadVarint in rawInt64
+func (p *importer) ReadByte() (byte, error) {
+	return p.rawByte(), nil
+}
+
+// byte is the bottleneck interface for reading p.data.
+// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
+// rawByte should only be used by low-level decoders.
+func (p *importer) rawByte() byte {
+	b := p.data[0]
+	r := 1
+	if b == '|' {
+		b = p.data[1]
+		r = 2
+		switch b {
+		case 'S':
+			b = '$'
+		case '|':
+			// nothing to do
+		default:
+			errorf("unexpected escape sequence in export data")
+		}
+	}
+	p.data = p.data[r:]
+	p.read += r
+	return b
+
+}
+
+// ----------------------------------------------------------------------------
+// Export format
+
+// Tags. Must be < 0.
+const (
+	// Objects
+	packageTag = -(iota + 1)
+	constTag
+	typeTag
+	varTag
+	funcTag
+	endTag
+
+	// Types
+	namedTag
+	arrayTag
+	sliceTag
+	dddTag
+	structTag
+	pointerTag
+	signatureTag
+	interfaceTag
+	mapTag
+	chanTag
+
+	// Values
+	falseTag
+	trueTag
+	int64Tag
+	floatTag
+	fractionTag // not used by gc
+	complexTag
+	stringTag
+	nilTag     // only used by gc (appears in exported inlined function bodies)
+	unknownTag // not used by gc (only appears in packages with errors)
+
+	// Type aliases
+	aliasTag
+)
+
+var predeclared = []types.Type{
+	// basic types
+	types.Typ[types.Bool],
+	types.Typ[types.Int],
+	types.Typ[types.Int8],
+	types.Typ[types.Int16],
+	types.Typ[types.Int32],
+	types.Typ[types.Int64],
+	types.Typ[types.Uint],
+	types.Typ[types.Uint8],
+	types.Typ[types.Uint16],
+	types.Typ[types.Uint32],
+	types.Typ[types.Uint64],
+	types.Typ[types.Uintptr],
+	types.Typ[types.Float32],
+	types.Typ[types.Float64],
+	types.Typ[types.Complex64],
+	types.Typ[types.Complex128],
+	types.Typ[types.String],
+
+	// basic type aliases
+	types.Universe.Lookup("byte").Type(),
+	types.Universe.Lookup("rune").Type(),
+
+	// error
+	types.Universe.Lookup("error").Type(),
+
+	// untyped types
+	types.Typ[types.UntypedBool],
+	types.Typ[types.UntypedInt],
+	types.Typ[types.UntypedRune],
+	types.Typ[types.UntypedFloat],
+	types.Typ[types.UntypedComplex],
+	types.Typ[types.UntypedString],
+	types.Typ[types.UntypedNil],
+
+	// package unsafe
+	types.Typ[types.UnsafePointer],
+
+	// invalid type
+	types.Typ[types.Invalid], // only appears in packages with errors
+
+	// used internally by gc; never used by this package or in .a files
+	anyType{},
+}
+
+type anyType struct{}
+
+func (t anyType) Underlying() types.Type { return t }
+func (t anyType) String() string         { return "any" }
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
new file mode 100644
index 0000000000000000000000000000000000000000..f33dc5613e712eb0dc9454864f772d1edcf8f425
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
@@ -0,0 +1,93 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go.
+
+// This file implements FindExportData.
+
+package gcimporter
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+)
+
+func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
+	// See $GOROOT/include/ar.h.
+	hdr := make([]byte, 16+12+6+6+8+10+2)
+	_, err = io.ReadFull(r, hdr)
+	if err != nil {
+		return
+	}
+	// leave for debugging
+	if false {
+		fmt.Printf("header: %s", hdr)
+	}
+	s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
+	size, err = strconv.Atoi(s)
+	if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
+		err = fmt.Errorf("invalid archive header")
+		return
+	}
+	name = strings.TrimSpace(string(hdr[:16]))
+	return
+}
+
+// FindExportData positions the reader r at the beginning of the
+// export data section of an underlying GC-created object/archive
+// file by reading from it. The reader must be positioned at the
+// start of the file before calling this function. The hdr result
+// is the string before the export data, either "$$" or "$$B".
+//
+func FindExportData(r *bufio.Reader) (hdr string, err error) {
+	// Read first line to make sure this is an object file.
+	line, err := r.ReadSlice('\n')
+	if err != nil {
+		err = fmt.Errorf("can't find export data (%v)", err)
+		return
+	}
+
+	if string(line) == "!<arch>\n" {
+		// Archive file. Scan to __.PKGDEF.
+		var name string
+		if name, _, err = readGopackHeader(r); err != nil {
+			return
+		}
+
+		// First entry should be __.PKGDEF.
+		if name != "__.PKGDEF" {
+			err = fmt.Errorf("go archive is missing __.PKGDEF")
+			return
+		}
+
+		// Read first line of __.PKGDEF data, so that line
+		// is once again the first line of the input.
+		if line, err = r.ReadSlice('\n'); err != nil {
+			err = fmt.Errorf("can't find export data (%v)", err)
+			return
+		}
+	}
+
+	// Now at __.PKGDEF in archive or still at beginning of file.
+	// Either way, line should begin with "go object ".
+	if !strings.HasPrefix(string(line), "go object ") {
+		err = fmt.Errorf("not a Go object file")
+		return
+	}
+
+	// Skip over object header to export data.
+	// Begins after first line starting with $$.
+	for line[0] != '$' {
+		if line, err = r.ReadSlice('\n'); err != nil {
+			err = fmt.Errorf("can't find export data (%v)", err)
+			return
+		}
+	}
+	hdr = string(line)
+
+	return
+}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
new file mode 100644
index 0000000000000000000000000000000000000000..9cf186605f6ebb90ab870d9130efcbf1d73b3e60
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
@@ -0,0 +1,1078 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a modified copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go,
+// but it also contains the original source-based importer code for Go1.6.
+// Once we stop supporting 1.6, we can remove that code.
+
+// Package gcimporter provides various functions for reading
+// gc-generated object files that can be used to implement the
+// Importer interface defined by the Go 1.5 standard library package.
+package gcimporter // import "golang.org/x/tools/go/internal/gcimporter"
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"go/build"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"sort"
+	"strconv"
+	"strings"
+	"text/scanner"
+)
+
+// debugging/development support
+const debug = false
+
+var pkgExts = [...]string{".a", ".o"}
+
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context). A relative srcDir is interpreted
+// relative to the current working directory.
+// If no file was found, an empty filename is returned.
+//
+func FindPkg(path, srcDir string) (filename, id string) {
+	if path == "" {
+		return
+	}
+
+	var noext string
+	switch {
+	default:
+		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
+		// Don't require the source files to be present.
+		if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
+			srcDir = abs
+		}
+		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
+		if bp.PkgObj == "" {
+			id = path // make sure we have an id to print in error message
+			return
+		}
+		noext = strings.TrimSuffix(bp.PkgObj, ".a")
+		id = bp.ImportPath
+
+	case build.IsLocalImport(path):
+		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
+		noext = filepath.Join(srcDir, path)
+		id = noext
+
+	case filepath.IsAbs(path):
+		// for completeness only - go/build.Import
+		// does not support absolute imports
+		// "/x" -> "/x.ext", "/x"
+		noext = path
+		id = path
+	}
+
+	if false { // for debugging
+		if path != id {
+			fmt.Printf("%s -> %s\n", path, id)
+		}
+	}
+
+	// try extensions
+	for _, ext := range pkgExts {
+		filename = noext + ext
+		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+			return
+		}
+	}
+
+	filename = "" // not found
+	return
+}
+
+// ImportData imports a package by reading the gc-generated export data,
+// adds the corresponding package object to the packages map indexed by id,
+// and returns the object.
+//
+// The packages map must contains all packages already imported. The data
+// reader position must be the beginning of the export data section. The
+// filename is only used in error messages.
+//
+// If packages[id] contains the completely imported package, that package
+// can be used directly, and there is no need to call this function (but
+// there is also no harm but for extra time used).
+//
+func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
+	// support for parser error handling
+	defer func() {
+		switch r := recover().(type) {
+		case nil:
+			// nothing to do
+		case importError:
+			err = r
+		default:
+			panic(r) // internal error
+		}
+	}()
+
+	var p parser
+	p.init(filename, id, data, packages)
+	pkg = p.parseExport()
+
+	return
+}
+
+// Import imports a gc-generated package given its import path and srcDir, adds
+// the corresponding package object to the packages map, and returns the object.
+// The packages map must contain all packages already imported.
+//
+func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
+	var rc io.ReadCloser
+	var filename, id string
+	if lookup != nil {
+		// With custom lookup specified, assume that caller has
+		// converted path to a canonical import path for use in the map.
+		if path == "unsafe" {
+			return types.Unsafe, nil
+		}
+		id = path
+
+		// No need to re-import if the package was imported completely before.
+		if pkg = packages[id]; pkg != nil && pkg.Complete() {
+			return
+		}
+		f, err := lookup(path)
+		if err != nil {
+			return nil, err
+		}
+		rc = f
+	} else {
+		filename, id = FindPkg(path, srcDir)
+		if filename == "" {
+			if path == "unsafe" {
+				return types.Unsafe, nil
+			}
+			return nil, fmt.Errorf("can't find import: %q", id)
+		}
+
+		// no need to re-import if the package was imported completely before
+		if pkg = packages[id]; pkg != nil && pkg.Complete() {
+			return
+		}
+
+		// open file
+		f, err := os.Open(filename)
+		if err != nil {
+			return nil, err
+		}
+		defer func() {
+			if err != nil {
+				// add file name to error
+				err = fmt.Errorf("%s: %v", filename, err)
+			}
+		}()
+		rc = f
+	}
+	defer rc.Close()
+
+	var hdr string
+	buf := bufio.NewReader(rc)
+	if hdr, err = FindExportData(buf); err != nil {
+		return
+	}
+
+	switch hdr {
+	case "$$\n":
+		// Work-around if we don't have a filename; happens only if lookup != nil.
+		// Either way, the filename is only needed for importer error messages, so
+		// this is fine.
+		if filename == "" {
+			filename = path
+		}
+		return ImportData(packages, filename, id, buf)
+
+	case "$$B\n":
+		var data []byte
+		data, err = ioutil.ReadAll(buf)
+		if err != nil {
+			break
+		}
+
+		// TODO(gri): allow clients of go/importer to provide a FileSet.
+		// Or, define a new standard go/types/gcexportdata package.
+		fset := token.NewFileSet()
+
+		// The indexed export format starts with an 'i'; the older
+		// binary export format starts with a 'c', 'd', or 'v'
+		// (from "version"). Select appropriate importer.
+		if len(data) > 0 && data[0] == 'i' {
+			_, pkg, err = IImportData(fset, packages, data[1:], id)
+		} else {
+			_, pkg, err = BImportData(fset, packages, data, id)
+		}
+
+	default:
+		err = fmt.Errorf("unknown export data header: %q", hdr)
+	}
+
+	return
+}
+
+// ----------------------------------------------------------------------------
+// Parser
+
+// TODO(gri) Imported objects don't have position information.
+//           Ideally use the debug table line info; alternatively
+//           create some fake position (or the position of the
+//           import). That way error messages referring to imported
+//           objects can print meaningful information.
+
+// parser parses the exports inside a gc compiler-produced
+// object/archive file and populates its scope with the results.
+type parser struct {
+	scanner    scanner.Scanner
+	tok        rune                      // current token
+	lit        string                    // literal string; only valid for Ident, Int, String tokens
+	id         string                    // package id of imported package
+	sharedPkgs map[string]*types.Package // package id -> package object (across importer)
+	localPkgs  map[string]*types.Package // package id -> package object (just this package)
+}
+
+func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) {
+	p.scanner.Init(src)
+	p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
+	p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
+	p.scanner.Whitespace = 1<<'\t' | 1<<' '
+	p.scanner.Filename = filename // for good error messages
+	p.next()
+	p.id = id
+	p.sharedPkgs = packages
+	if debug {
+		// check consistency of packages map
+		for _, pkg := range packages {
+			if pkg.Name() == "" {
+				fmt.Printf("no package name for %s\n", pkg.Path())
+			}
+		}
+	}
+}
+
+func (p *parser) next() {
+	p.tok = p.scanner.Scan()
+	switch p.tok {
+	case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·':
+		p.lit = p.scanner.TokenText()
+	default:
+		p.lit = ""
+	}
+	if debug {
+		fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
+	}
+}
+
+func declTypeName(pkg *types.Package, name string) *types.TypeName {
+	scope := pkg.Scope()
+	if obj := scope.Lookup(name); obj != nil {
+		return obj.(*types.TypeName)
+	}
+	obj := types.NewTypeName(token.NoPos, pkg, name, nil)
+	// a named type may be referred to before the underlying type
+	// is known - set it up
+	types.NewNamed(obj, nil, nil)
+	scope.Insert(obj)
+	return obj
+}
+
+// ----------------------------------------------------------------------------
+// Error handling
+
+// Internal errors are boxed as importErrors.
+type importError struct {
+	pos scanner.Position
+	err error
+}
+
+func (e importError) Error() string {
+	return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
+}
+
+func (p *parser) error(err interface{}) {
+	if s, ok := err.(string); ok {
+		err = errors.New(s)
+	}
+	// panic with a runtime.Error if err is not an error
+	panic(importError{p.scanner.Pos(), err.(error)})
+}
+
+func (p *parser) errorf(format string, args ...interface{}) {
+	p.error(fmt.Sprintf(format, args...))
+}
+
+func (p *parser) expect(tok rune) string {
+	lit := p.lit
+	if p.tok != tok {
+		p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
+	}
+	p.next()
+	return lit
+}
+
+func (p *parser) expectSpecial(tok string) {
+	sep := 'x' // not white space
+	i := 0
+	for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
+		sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
+		p.next()
+		i++
+	}
+	if i < len(tok) {
+		p.errorf("expected %q, got %q", tok, tok[0:i])
+	}
+}
+
+func (p *parser) expectKeyword(keyword string) {
+	lit := p.expect(scanner.Ident)
+	if lit != keyword {
+		p.errorf("expected keyword %s, got %q", keyword, lit)
+	}
+}
+
+// ----------------------------------------------------------------------------
+// Qualified and unqualified names
+
+// PackageId = string_lit .
+//
+func (p *parser) parsePackageId() string {
+	id, err := strconv.Unquote(p.expect(scanner.String))
+	if err != nil {
+		p.error(err)
+	}
+	// id == "" stands for the imported package id
+	// (only known at time of package installation)
+	if id == "" {
+		id = p.id
+	}
+	return id
+}
+
+// PackageName = ident .
+//
+func (p *parser) parsePackageName() string {
+	return p.expect(scanner.Ident)
+}
+
+// dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
+func (p *parser) parseDotIdent() string {
+	ident := ""
+	if p.tok != scanner.Int {
+		sep := 'x' // not white space
+		for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
+			ident += p.lit
+			sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
+			p.next()
+		}
+	}
+	if ident == "" {
+		p.expect(scanner.Ident) // use expect() for error handling
+	}
+	return ident
+}
+
+// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) .
+//
+func (p *parser) parseQualifiedName() (id, name string) {
+	p.expect('@')
+	id = p.parsePackageId()
+	p.expect('.')
+	// Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields.
+	if p.tok == '?' {
+		p.next()
+	} else {
+		name = p.parseDotIdent()
+	}
+	return
+}
+
+// getPkg returns the package for a given id. If the package is
+// not found, create the package and add it to the p.localPkgs
+// and p.sharedPkgs maps. name is the (expected) name of the
+// package. If name == "", the package name is expected to be
+// set later via an import clause in the export data.
+//
+// id identifies a package, usually by a canonical package path like
+// "encoding/json" but possibly by a non-canonical import path like
+// "./json".
+//
+func (p *parser) getPkg(id, name string) *types.Package {
+	// package unsafe is not in the packages maps - handle explicitly
+	if id == "unsafe" {
+		return types.Unsafe
+	}
+
+	pkg := p.localPkgs[id]
+	if pkg == nil {
+		// first import of id from this package
+		pkg = p.sharedPkgs[id]
+		if pkg == nil {
+			// first import of id by this importer;
+			// add (possibly unnamed) pkg to shared packages
+			pkg = types.NewPackage(id, name)
+			p.sharedPkgs[id] = pkg
+		}
+		// add (possibly unnamed) pkg to local packages
+		if p.localPkgs == nil {
+			p.localPkgs = make(map[string]*types.Package)
+		}
+		p.localPkgs[id] = pkg
+	} else if name != "" {
+		// package exists already and we have an expected package name;
+		// make sure names match or set package name if necessary
+		if pname := pkg.Name(); pname == "" {
+			pkg.SetName(name)
+		} else if pname != name {
+			p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name)
+		}
+	}
+	return pkg
+}
+
+// parseExportedName is like parseQualifiedName, but
+// the package id is resolved to an imported *types.Package.
+//
+func (p *parser) parseExportedName() (pkg *types.Package, name string) {
+	id, name := p.parseQualifiedName()
+	pkg = p.getPkg(id, "")
+	return
+}
+
+// ----------------------------------------------------------------------------
+// Types
+
+// BasicType = identifier .
+//
+func (p *parser) parseBasicType() types.Type {
+	id := p.expect(scanner.Ident)
+	obj := types.Universe.Lookup(id)
+	if obj, ok := obj.(*types.TypeName); ok {
+		return obj.Type()
+	}
+	p.errorf("not a basic type: %s", id)
+	return nil
+}
+
+// ArrayType = "[" int_lit "]" Type .
+//
+func (p *parser) parseArrayType(parent *types.Package) types.Type {
+	// "[" already consumed and lookahead known not to be "]"
+	lit := p.expect(scanner.Int)
+	p.expect(']')
+	elem := p.parseType(parent)
+	n, err := strconv.ParseInt(lit, 10, 64)
+	if err != nil {
+		p.error(err)
+	}
+	return types.NewArray(elem, n)
+}
+
+// MapType = "map" "[" Type "]" Type .
+//
+func (p *parser) parseMapType(parent *types.Package) types.Type {
+	p.expectKeyword("map")
+	p.expect('[')
+	key := p.parseType(parent)
+	p.expect(']')
+	elem := p.parseType(parent)
+	return types.NewMap(key, elem)
+}
+
+// Name = identifier | "?" | QualifiedName .
+//
+// For unqualified and anonymous names, the returned package is the parent
+// package unless parent == nil, in which case the returned package is the
+// package being imported. (The parent package is not nil if the the name
+// is an unqualified struct field or interface method name belonging to a
+// type declared in another package.)
+//
+// For qualified names, the returned package is nil (and not created if
+// it doesn't exist yet) unless materializePkg is set (which creates an
+// unnamed package with valid package path). In the latter case, a
+// subsequent import clause is expected to provide a name for the package.
+//
+func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) {
+	pkg = parent
+	if pkg == nil {
+		pkg = p.sharedPkgs[p.id]
+	}
+	switch p.tok {
+	case scanner.Ident:
+		name = p.lit
+		p.next()
+	case '?':
+		// anonymous
+		p.next()
+	case '@':
+		// exported name prefixed with package path
+		pkg = nil
+		var id string
+		id, name = p.parseQualifiedName()
+		if materializePkg {
+			pkg = p.getPkg(id, "")
+		}
+	default:
+		p.error("name expected")
+	}
+	return
+}
+
+func deref(typ types.Type) types.Type {
+	if p, _ := typ.(*types.Pointer); p != nil {
+		return p.Elem()
+	}
+	return typ
+}
+
+// Field = Name Type [ string_lit ] .
+//
+func (p *parser) parseField(parent *types.Package) (*types.Var, string) {
+	pkg, name := p.parseName(parent, true)
+
+	if name == "_" {
+		// Blank fields should be package-qualified because they
+		// are unexported identifiers, but gc does not qualify them.
+		// Assuming that the ident belongs to the current package
+		// causes types to change during re-exporting, leading
+		// to spurious "can't assign A to B" errors from go/types.
+		// As a workaround, pretend all blank fields belong
+		// to the same unique dummy package.
+		const blankpkg = "<_>"
+		pkg = p.getPkg(blankpkg, blankpkg)
+	}
+
+	typ := p.parseType(parent)
+	anonymous := false
+	if name == "" {
+		// anonymous field - typ must be T or *T and T must be a type name
+		switch typ := deref(typ).(type) {
+		case *types.Basic: // basic types are named types
+			pkg = nil // objects defined in Universe scope have no package
+			name = typ.Name()
+		case *types.Named:
+			name = typ.Obj().Name()
+		default:
+			p.errorf("anonymous field expected")
+		}
+		anonymous = true
+	}
+	tag := ""
+	if p.tok == scanner.String {
+		s := p.expect(scanner.String)
+		var err error
+		tag, err = strconv.Unquote(s)
+		if err != nil {
+			p.errorf("invalid struct tag %s: %s", s, err)
+		}
+	}
+	return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag
+}
+
+// StructType = "struct" "{" [ FieldList ] "}" .
+// FieldList  = Field { ";" Field } .
+//
+func (p *parser) parseStructType(parent *types.Package) types.Type {
+	var fields []*types.Var
+	var tags []string
+
+	p.expectKeyword("struct")
+	p.expect('{')
+	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
+		if i > 0 {
+			p.expect(';')
+		}
+		fld, tag := p.parseField(parent)
+		if tag != "" && tags == nil {
+			tags = make([]string, i)
+		}
+		if tags != nil {
+			tags = append(tags, tag)
+		}
+		fields = append(fields, fld)
+	}
+	p.expect('}')
+
+	return types.NewStruct(fields, tags)
+}
+
+// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
+//
+func (p *parser) parseParameter() (par *types.Var, isVariadic bool) {
+	_, name := p.parseName(nil, false)
+	// remove gc-specific parameter numbering
+	if i := strings.Index(name, "·"); i >= 0 {
+		name = name[:i]
+	}
+	if p.tok == '.' {
+		p.expectSpecial("...")
+		isVariadic = true
+	}
+	typ := p.parseType(nil)
+	if isVariadic {
+		typ = types.NewSlice(typ)
+	}
+	// ignore argument tag (e.g. "noescape")
+	if p.tok == scanner.String {
+		p.next()
+	}
+	// TODO(gri) should we provide a package?
+	par = types.NewVar(token.NoPos, nil, name, typ)
+	return
+}
+
+// Parameters    = "(" [ ParameterList ] ")" .
+// ParameterList = { Parameter "," } Parameter .
+//
+func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) {
+	p.expect('(')
+	for p.tok != ')' && p.tok != scanner.EOF {
+		if len(list) > 0 {
+			p.expect(',')
+		}
+		par, variadic := p.parseParameter()
+		list = append(list, par)
+		if variadic {
+			if isVariadic {
+				p.error("... not on final argument")
+			}
+			isVariadic = true
+		}
+	}
+	p.expect(')')
+
+	return
+}
+
+// Signature = Parameters [ Result ] .
+// Result    = Type | Parameters .
+//
+func (p *parser) parseSignature(recv *types.Var) *types.Signature {
+	params, isVariadic := p.parseParameters()
+
+	// optional result type
+	var results []*types.Var
+	if p.tok == '(' {
+		var variadic bool
+		results, variadic = p.parseParameters()
+		if variadic {
+			p.error("... not permitted on result type")
+		}
+	}
+
+	return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic)
+}
+
+// InterfaceType = "interface" "{" [ MethodList ] "}" .
+// MethodList    = Method { ";" Method } .
+// Method        = Name Signature .
+//
+// The methods of embedded interfaces are always "inlined"
+// by the compiler and thus embedded interfaces are never
+// visible in the export data.
+//
+func (p *parser) parseInterfaceType(parent *types.Package) types.Type {
+	var methods []*types.Func
+
+	p.expectKeyword("interface")
+	p.expect('{')
+	for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
+		if i > 0 {
+			p.expect(';')
+		}
+		pkg, name := p.parseName(parent, true)
+		sig := p.parseSignature(nil)
+		methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig))
+	}
+	p.expect('}')
+
+	// Complete requires the type's embedded interfaces to be fully defined,
+	// but we do not define any
+	return types.NewInterface(methods, nil).Complete()
+}
+
+// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
+//
+func (p *parser) parseChanType(parent *types.Package) types.Type {
+	dir := types.SendRecv
+	if p.tok == scanner.Ident {
+		p.expectKeyword("chan")
+		if p.tok == '<' {
+			p.expectSpecial("<-")
+			dir = types.SendOnly
+		}
+	} else {
+		p.expectSpecial("<-")
+		p.expectKeyword("chan")
+		dir = types.RecvOnly
+	}
+	elem := p.parseType(parent)
+	return types.NewChan(dir, elem)
+}
+
+// Type =
+//	BasicType | TypeName | ArrayType | SliceType | StructType |
+//      PointerType | FuncType | InterfaceType | MapType | ChanType |
+//      "(" Type ")" .
+//
+// BasicType   = ident .
+// TypeName    = ExportedName .
+// SliceType   = "[" "]" Type .
+// PointerType = "*" Type .
+// FuncType    = "func" Signature .
+//
+func (p *parser) parseType(parent *types.Package) types.Type {
+	switch p.tok {
+	case scanner.Ident:
+		switch p.lit {
+		default:
+			return p.parseBasicType()
+		case "struct":
+			return p.parseStructType(parent)
+		case "func":
+			// FuncType
+			p.next()
+			return p.parseSignature(nil)
+		case "interface":
+			return p.parseInterfaceType(parent)
+		case "map":
+			return p.parseMapType(parent)
+		case "chan":
+			return p.parseChanType(parent)
+		}
+	case '@':
+		// TypeName
+		pkg, name := p.parseExportedName()
+		return declTypeName(pkg, name).Type()
+	case '[':
+		p.next() // look ahead
+		if p.tok == ']' {
+			// SliceType
+			p.next()
+			return types.NewSlice(p.parseType(parent))
+		}
+		return p.parseArrayType(parent)
+	case '*':
+		// PointerType
+		p.next()
+		return types.NewPointer(p.parseType(parent))
+	case '<':
+		return p.parseChanType(parent)
+	case '(':
+		// "(" Type ")"
+		p.next()
+		typ := p.parseType(parent)
+		p.expect(')')
+		return typ
+	}
+	p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
+	return nil
+}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+// ImportDecl = "import" PackageName PackageId .
+//
+func (p *parser) parseImportDecl() {
+	p.expectKeyword("import")
+	name := p.parsePackageName()
+	p.getPkg(p.parsePackageId(), name)
+}
+
+// int_lit = [ "+" | "-" ] { "0" ... "9" } .
+//
+func (p *parser) parseInt() string {
+	s := ""
+	switch p.tok {
+	case '-':
+		s = "-"
+		p.next()
+	case '+':
+		p.next()
+	}
+	return s + p.expect(scanner.Int)
+}
+
+// number = int_lit [ "p" int_lit ] .
+//
+func (p *parser) parseNumber() (typ *types.Basic, val constant.Value) {
+	// mantissa
+	mant := constant.MakeFromLiteral(p.parseInt(), token.INT, 0)
+	if mant == nil {
+		panic("invalid mantissa")
+	}
+
+	if p.lit == "p" {
+		// exponent (base 2)
+		p.next()
+		exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
+		if err != nil {
+			p.error(err)
+		}
+		if exp < 0 {
+			denom := constant.MakeInt64(1)
+			denom = constant.Shift(denom, token.SHL, uint(-exp))
+			typ = types.Typ[types.UntypedFloat]
+			val = constant.BinaryOp(mant, token.QUO, denom)
+			return
+		}
+		if exp > 0 {
+			mant = constant.Shift(mant, token.SHL, uint(exp))
+		}
+		typ = types.Typ[types.UntypedFloat]
+		val = mant
+		return
+	}
+
+	typ = types.Typ[types.UntypedInt]
+	val = mant
+	return
+}
+
+// ConstDecl   = "const" ExportedName [ Type ] "=" Literal .
+// Literal     = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit .
+// bool_lit    = "true" | "false" .
+// complex_lit = "(" float_lit "+" float_lit "i" ")" .
+// rune_lit    = "(" int_lit "+" int_lit ")" .
+// string_lit  = `"` { unicode_char } `"` .
+//
+func (p *parser) parseConstDecl() {
+	p.expectKeyword("const")
+	pkg, name := p.parseExportedName()
+
+	var typ0 types.Type
+	if p.tok != '=' {
+		// constant types are never structured - no need for parent type
+		typ0 = p.parseType(nil)
+	}
+
+	p.expect('=')
+	var typ types.Type
+	var val constant.Value
+	switch p.tok {
+	case scanner.Ident:
+		// bool_lit
+		if p.lit != "true" && p.lit != "false" {
+			p.error("expected true or false")
+		}
+		typ = types.Typ[types.UntypedBool]
+		val = constant.MakeBool(p.lit == "true")
+		p.next()
+
+	case '-', scanner.Int:
+		// int_lit
+		typ, val = p.parseNumber()
+
+	case '(':
+		// complex_lit or rune_lit
+		p.next()
+		if p.tok == scanner.Char {
+			p.next()
+			p.expect('+')
+			typ = types.Typ[types.UntypedRune]
+			_, val = p.parseNumber()
+			p.expect(')')
+			break
+		}
+		_, re := p.parseNumber()
+		p.expect('+')
+		_, im := p.parseNumber()
+		p.expectKeyword("i")
+		p.expect(')')
+		typ = types.Typ[types.UntypedComplex]
+		val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+
+	case scanner.Char:
+		// rune_lit
+		typ = types.Typ[types.UntypedRune]
+		val = constant.MakeFromLiteral(p.lit, token.CHAR, 0)
+		p.next()
+
+	case scanner.String:
+		// string_lit
+		typ = types.Typ[types.UntypedString]
+		val = constant.MakeFromLiteral(p.lit, token.STRING, 0)
+		p.next()
+
+	default:
+		p.errorf("expected literal got %s", scanner.TokenString(p.tok))
+	}
+
+	if typ0 == nil {
+		typ0 = typ
+	}
+
+	pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val))
+}
+
+// TypeDecl = "type" ExportedName Type .
+//
+func (p *parser) parseTypeDecl() {
+	p.expectKeyword("type")
+	pkg, name := p.parseExportedName()
+	obj := declTypeName(pkg, name)
+
+	// The type object may have been imported before and thus already
+	// have a type associated with it. We still need to parse the type
+	// structure, but throw it away if the object already has a type.
+	// This ensures that all imports refer to the same type object for
+	// a given type declaration.
+	typ := p.parseType(pkg)
+
+	if name := obj.Type().(*types.Named); name.Underlying() == nil {
+		name.SetUnderlying(typ)
+	}
+}
+
+// VarDecl = "var" ExportedName Type .
+//
+func (p *parser) parseVarDecl() {
+	p.expectKeyword("var")
+	pkg, name := p.parseExportedName()
+	typ := p.parseType(pkg)
+	pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ))
+}
+
+// Func = Signature [ Body ] .
+// Body = "{" ... "}" .
+//
+func (p *parser) parseFunc(recv *types.Var) *types.Signature {
+	sig := p.parseSignature(recv)
+	if p.tok == '{' {
+		p.next()
+		for i := 1; i > 0; p.next() {
+			switch p.tok {
+			case '{':
+				i++
+			case '}':
+				i--
+			}
+		}
+	}
+	return sig
+}
+
+// MethodDecl = "func" Receiver Name Func .
+// Receiver   = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" .
+//
+func (p *parser) parseMethodDecl() {
+	// "func" already consumed
+	p.expect('(')
+	recv, _ := p.parseParameter() // receiver
+	p.expect(')')
+
+	// determine receiver base type object
+	base := deref(recv.Type()).(*types.Named)
+
+	// parse method name, signature, and possibly inlined body
+	_, name := p.parseName(nil, false)
+	sig := p.parseFunc(recv)
+
+	// methods always belong to the same package as the base type object
+	pkg := base.Obj().Pkg()
+
+	// add method to type unless type was imported before
+	// and method exists already
+	// TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small.
+	base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
+}
+
+// FuncDecl = "func" ExportedName Func .
+//
+func (p *parser) parseFuncDecl() {
+	// "func" already consumed
+	pkg, name := p.parseExportedName()
+	typ := p.parseFunc(nil)
+	pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ))
+}
+
+// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
+//
+func (p *parser) parseDecl() {
+	if p.tok == scanner.Ident {
+		switch p.lit {
+		case "import":
+			p.parseImportDecl()
+		case "const":
+			p.parseConstDecl()
+		case "type":
+			p.parseTypeDecl()
+		case "var":
+			p.parseVarDecl()
+		case "func":
+			p.next() // look ahead
+			if p.tok == '(' {
+				p.parseMethodDecl()
+			} else {
+				p.parseFuncDecl()
+			}
+		}
+	}
+	p.expect('\n')
+}
+
+// ----------------------------------------------------------------------------
+// Export
+
+// Export        = "PackageClause { Decl } "$$" .
+// PackageClause = "package" PackageName [ "safe" ] "\n" .
+//
+func (p *parser) parseExport() *types.Package {
+	p.expectKeyword("package")
+	name := p.parsePackageName()
+	if p.tok == scanner.Ident && p.lit == "safe" {
+		// package was compiled with -u option - ignore
+		p.next()
+	}
+	p.expect('\n')
+
+	pkg := p.getPkg(p.id, name)
+
+	for p.tok != '$' && p.tok != scanner.EOF {
+		p.parseDecl()
+	}
+
+	if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
+		// don't call next()/expect() since reading past the
+		// export data may cause scanner errors (e.g. NUL chars)
+		p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
+	}
+
+	if n := p.scanner.ErrorCount; n != 0 {
+		p.errorf("expected no scanner errors, got %d", n)
+	}
+
+	// Record all locally referenced packages as imports.
+	var imports []*types.Package
+	for id, pkg2 := range p.localPkgs {
+		if pkg2.Name() == "" {
+			p.errorf("%s package has no name", id)
+		}
+		if id == p.id {
+			continue // avoid self-edge
+		}
+		imports = append(imports, pkg2)
+	}
+	sort.Sort(byPath(imports))
+	pkg.SetImports(imports)
+
+	// package was imported completely and without errors
+	pkg.MarkComplete()
+
+	return pkg
+}
+
+type byPath []*types.Package
+
+func (a byPath) Len() int           { return len(a) }
+func (a byPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
new file mode 100644
index 0000000000000000000000000000000000000000..0fd22bb038453d1dbc162c217e4fc1f734120b98
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
@@ -0,0 +1,598 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Indexed package import.
+// See cmd/compile/internal/gc/iexport.go for the export data format.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
+
+package gcimporter
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"io"
+	"sort"
+)
+
+type intReader struct {
+	*bytes.Reader
+	path string
+}
+
+func (r *intReader) int64() int64 {
+	i, err := binary.ReadVarint(r.Reader)
+	if err != nil {
+		errorf("import %q: read varint error: %v", r.path, err)
+	}
+	return i
+}
+
+func (r *intReader) uint64() uint64 {
+	i, err := binary.ReadUvarint(r.Reader)
+	if err != nil {
+		errorf("import %q: read varint error: %v", r.path, err)
+	}
+	return i
+}
+
+const predeclReserved = 32
+
+type itag uint64
+
+const (
+	// Types
+	definedType itag = iota
+	pointerType
+	sliceType
+	arrayType
+	chanType
+	mapType
+	signatureType
+	structType
+	interfaceType
+)
+
+// IImportData imports a package from the serialized package data
+// and returns the number of bytes consumed and a reference to the package.
+// If the export data version is not recognized or the format is otherwise
+// compromised, an error is returned.
+func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
+	const currentVersion = 0
+	version := -1
+	defer func() {
+		if e := recover(); e != nil {
+			if version > currentVersion {
+				err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
+			} else {
+				err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
+			}
+		}
+	}()
+
+	r := &intReader{bytes.NewReader(data), path}
+
+	version = int(r.uint64())
+	switch version {
+	case currentVersion:
+	default:
+		errorf("unknown iexport format version %d", version)
+	}
+
+	sLen := int64(r.uint64())
+	dLen := int64(r.uint64())
+
+	whence, _ := r.Seek(0, io.SeekCurrent)
+	stringData := data[whence : whence+sLen]
+	declData := data[whence+sLen : whence+sLen+dLen]
+	r.Seek(sLen+dLen, io.SeekCurrent)
+
+	p := iimporter{
+		ipath: path,
+
+		stringData:  stringData,
+		stringCache: make(map[uint64]string),
+		pkgCache:    make(map[uint64]*types.Package),
+
+		declData: declData,
+		pkgIndex: make(map[*types.Package]map[string]uint64),
+		typCache: make(map[uint64]types.Type),
+
+		fake: fakeFileSet{
+			fset:  fset,
+			files: make(map[string]*token.File),
+		},
+	}
+
+	for i, pt := range predeclared {
+		p.typCache[uint64(i)] = pt
+	}
+
+	pkgList := make([]*types.Package, r.uint64())
+	for i := range pkgList {
+		pkgPathOff := r.uint64()
+		pkgPath := p.stringAt(pkgPathOff)
+		pkgName := p.stringAt(r.uint64())
+		_ = r.uint64() // package height; unused by go/types
+
+		if pkgPath == "" {
+			pkgPath = path
+		}
+		pkg := imports[pkgPath]
+		if pkg == nil {
+			pkg = types.NewPackage(pkgPath, pkgName)
+			imports[pkgPath] = pkg
+		} else if pkg.Name() != pkgName {
+			errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
+		}
+
+		p.pkgCache[pkgPathOff] = pkg
+
+		nameIndex := make(map[string]uint64)
+		for nSyms := r.uint64(); nSyms > 0; nSyms-- {
+			name := p.stringAt(r.uint64())
+			nameIndex[name] = r.uint64()
+		}
+
+		p.pkgIndex[pkg] = nameIndex
+		pkgList[i] = pkg
+	}
+
+	localpkg := pkgList[0]
+
+	names := make([]string, 0, len(p.pkgIndex[localpkg]))
+	for name := range p.pkgIndex[localpkg] {
+		names = append(names, name)
+	}
+	sort.Strings(names)
+	for _, name := range names {
+		p.doDecl(localpkg, name)
+	}
+
+	for _, typ := range p.interfaceList {
+		typ.Complete()
+	}
+
+	// record all referenced packages as imports
+	list := append(([]*types.Package)(nil), pkgList[1:]...)
+	sort.Sort(byPath(list))
+	localpkg.SetImports(list)
+
+	// package was imported completely and without errors
+	localpkg.MarkComplete()
+
+	consumed, _ := r.Seek(0, io.SeekCurrent)
+	return int(consumed), localpkg, nil
+}
+
+type iimporter struct {
+	ipath string
+
+	stringData  []byte
+	stringCache map[uint64]string
+	pkgCache    map[uint64]*types.Package
+
+	declData []byte
+	pkgIndex map[*types.Package]map[string]uint64
+	typCache map[uint64]types.Type
+
+	fake          fakeFileSet
+	interfaceList []*types.Interface
+}
+
+func (p *iimporter) doDecl(pkg *types.Package, name string) {
+	// See if we've already imported this declaration.
+	if obj := pkg.Scope().Lookup(name); obj != nil {
+		return
+	}
+
+	off, ok := p.pkgIndex[pkg][name]
+	if !ok {
+		errorf("%v.%v not in index", pkg, name)
+	}
+
+	r := &importReader{p: p, currPkg: pkg}
+	r.declReader.Reset(p.declData[off:])
+
+	r.obj(name)
+}
+
+func (p *iimporter) stringAt(off uint64) string {
+	if s, ok := p.stringCache[off]; ok {
+		return s
+	}
+
+	slen, n := binary.Uvarint(p.stringData[off:])
+	if n <= 0 {
+		errorf("varint failed")
+	}
+	spos := off + uint64(n)
+	s := string(p.stringData[spos : spos+slen])
+	p.stringCache[off] = s
+	return s
+}
+
+func (p *iimporter) pkgAt(off uint64) *types.Package {
+	if pkg, ok := p.pkgCache[off]; ok {
+		return pkg
+	}
+	path := p.stringAt(off)
+	errorf("missing package %q in %q", path, p.ipath)
+	return nil
+}
+
+func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
+	if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
+		return t
+	}
+
+	if off < predeclReserved {
+		errorf("predeclared type missing from cache: %v", off)
+	}
+
+	r := &importReader{p: p}
+	r.declReader.Reset(p.declData[off-predeclReserved:])
+	t := r.doType(base)
+
+	if base == nil || !isInterface(t) {
+		p.typCache[off] = t
+	}
+	return t
+}
+
+type importReader struct {
+	p          *iimporter
+	declReader bytes.Reader
+	currPkg    *types.Package
+	prevFile   string
+	prevLine   int64
+}
+
+func (r *importReader) obj(name string) {
+	tag := r.byte()
+	pos := r.pos()
+
+	switch tag {
+	case 'A':
+		typ := r.typ()
+
+		r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
+
+	case 'C':
+		typ, val := r.value()
+
+		r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
+
+	case 'F':
+		sig := r.signature(nil)
+
+		r.declare(types.NewFunc(pos, r.currPkg, name, sig))
+
+	case 'T':
+		// Types can be recursive. We need to setup a stub
+		// declaration before recursing.
+		obj := types.NewTypeName(pos, r.currPkg, name, nil)
+		named := types.NewNamed(obj, nil, nil)
+		r.declare(obj)
+
+		underlying := r.p.typAt(r.uint64(), named).Underlying()
+		named.SetUnderlying(underlying)
+
+		if !isInterface(underlying) {
+			for n := r.uint64(); n > 0; n-- {
+				mpos := r.pos()
+				mname := r.ident()
+				recv := r.param()
+				msig := r.signature(recv)
+
+				named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
+			}
+		}
+
+	case 'V':
+		typ := r.typ()
+
+		r.declare(types.NewVar(pos, r.currPkg, name, typ))
+
+	default:
+		errorf("unexpected tag: %v", tag)
+	}
+}
+
+func (r *importReader) declare(obj types.Object) {
+	obj.Pkg().Scope().Insert(obj)
+}
+
+func (r *importReader) value() (typ types.Type, val constant.Value) {
+	typ = r.typ()
+
+	switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
+	case types.IsBoolean:
+		val = constant.MakeBool(r.bool())
+
+	case types.IsString:
+		val = constant.MakeString(r.string())
+
+	case types.IsInteger:
+		val = r.mpint(b)
+
+	case types.IsFloat:
+		val = r.mpfloat(b)
+
+	case types.IsComplex:
+		re := r.mpfloat(b)
+		im := r.mpfloat(b)
+		val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+
+	default:
+		errorf("unexpected type %v", typ) // panics
+		panic("unreachable")
+	}
+
+	return
+}
+
+func intSize(b *types.Basic) (signed bool, maxBytes uint) {
+	if (b.Info() & types.IsUntyped) != 0 {
+		return true, 64
+	}
+
+	switch b.Kind() {
+	case types.Float32, types.Complex64:
+		return true, 3
+	case types.Float64, types.Complex128:
+		return true, 7
+	}
+
+	signed = (b.Info() & types.IsUnsigned) == 0
+	switch b.Kind() {
+	case types.Int8, types.Uint8:
+		maxBytes = 1
+	case types.Int16, types.Uint16:
+		maxBytes = 2
+	case types.Int32, types.Uint32:
+		maxBytes = 4
+	default:
+		maxBytes = 8
+	}
+
+	return
+}
+
+func (r *importReader) mpint(b *types.Basic) constant.Value {
+	signed, maxBytes := intSize(b)
+
+	maxSmall := 256 - maxBytes
+	if signed {
+		maxSmall = 256 - 2*maxBytes
+	}
+	if maxBytes == 1 {
+		maxSmall = 256
+	}
+
+	n, _ := r.declReader.ReadByte()
+	if uint(n) < maxSmall {
+		v := int64(n)
+		if signed {
+			v >>= 1
+			if n&1 != 0 {
+				v = ^v
+			}
+		}
+		return constant.MakeInt64(v)
+	}
+
+	v := -n
+	if signed {
+		v = -(n &^ 1) >> 1
+	}
+	if v < 1 || uint(v) > maxBytes {
+		errorf("weird decoding: %v, %v => %v", n, signed, v)
+	}
+
+	buf := make([]byte, v)
+	io.ReadFull(&r.declReader, buf)
+
+	// convert to little endian
+	// TODO(gri) go/constant should have a more direct conversion function
+	//           (e.g., once it supports a big.Float based implementation)
+	for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
+		buf[i], buf[j] = buf[j], buf[i]
+	}
+
+	x := constant.MakeFromBytes(buf)
+	if signed && n&1 != 0 {
+		x = constant.UnaryOp(token.SUB, x, 0)
+	}
+	return x
+}
+
+func (r *importReader) mpfloat(b *types.Basic) constant.Value {
+	x := r.mpint(b)
+	if constant.Sign(x) == 0 {
+		return x
+	}
+
+	exp := r.int64()
+	switch {
+	case exp > 0:
+		x = constant.Shift(x, token.SHL, uint(exp))
+	case exp < 0:
+		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
+		x = constant.BinaryOp(x, token.QUO, d)
+	}
+	return x
+}
+
+func (r *importReader) ident() string {
+	return r.string()
+}
+
+func (r *importReader) qualifiedIdent() (*types.Package, string) {
+	name := r.string()
+	pkg := r.pkg()
+	return pkg, name
+}
+
+func (r *importReader) pos() token.Pos {
+	delta := r.int64()
+	if delta != deltaNewFile {
+		r.prevLine += delta
+	} else if l := r.int64(); l == -1 {
+		r.prevLine += deltaNewFile
+	} else {
+		r.prevFile = r.string()
+		r.prevLine = l
+	}
+
+	if r.prevFile == "" && r.prevLine == 0 {
+		return token.NoPos
+	}
+
+	return r.p.fake.pos(r.prevFile, int(r.prevLine))
+}
+
+func (r *importReader) typ() types.Type {
+	return r.p.typAt(r.uint64(), nil)
+}
+
+func isInterface(t types.Type) bool {
+	_, ok := t.(*types.Interface)
+	return ok
+}
+
+func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
+func (r *importReader) string() string      { return r.p.stringAt(r.uint64()) }
+
+func (r *importReader) doType(base *types.Named) types.Type {
+	switch k := r.kind(); k {
+	default:
+		errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
+		return nil
+
+	case definedType:
+		pkg, name := r.qualifiedIdent()
+		r.p.doDecl(pkg, name)
+		return pkg.Scope().Lookup(name).(*types.TypeName).Type()
+	case pointerType:
+		return types.NewPointer(r.typ())
+	case sliceType:
+		return types.NewSlice(r.typ())
+	case arrayType:
+		n := r.uint64()
+		return types.NewArray(r.typ(), int64(n))
+	case chanType:
+		dir := chanDir(int(r.uint64()))
+		return types.NewChan(dir, r.typ())
+	case mapType:
+		return types.NewMap(r.typ(), r.typ())
+	case signatureType:
+		r.currPkg = r.pkg()
+		return r.signature(nil)
+
+	case structType:
+		r.currPkg = r.pkg()
+
+		fields := make([]*types.Var, r.uint64())
+		tags := make([]string, len(fields))
+		for i := range fields {
+			fpos := r.pos()
+			fname := r.ident()
+			ftyp := r.typ()
+			emb := r.bool()
+			tag := r.string()
+
+			fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
+			tags[i] = tag
+		}
+		return types.NewStruct(fields, tags)
+
+	case interfaceType:
+		r.currPkg = r.pkg()
+
+		embeddeds := make([]types.Type, r.uint64())
+		for i := range embeddeds {
+			_ = r.pos()
+			embeddeds[i] = r.typ()
+		}
+
+		methods := make([]*types.Func, r.uint64())
+		for i := range methods {
+			mpos := r.pos()
+			mname := r.ident()
+
+			// TODO(mdempsky): Matches bimport.go, but I
+			// don't agree with this.
+			var recv *types.Var
+			if base != nil {
+				recv = types.NewVar(token.NoPos, r.currPkg, "", base)
+			}
+
+			msig := r.signature(recv)
+			methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
+		}
+
+		typ := newInterface(methods, embeddeds)
+		r.p.interfaceList = append(r.p.interfaceList, typ)
+		return typ
+	}
+}
+
+func (r *importReader) kind() itag {
+	return itag(r.uint64())
+}
+
+func (r *importReader) signature(recv *types.Var) *types.Signature {
+	params := r.paramList()
+	results := r.paramList()
+	variadic := params.Len() > 0 && r.bool()
+	return types.NewSignature(recv, params, results, variadic)
+}
+
+func (r *importReader) paramList() *types.Tuple {
+	xs := make([]*types.Var, r.uint64())
+	for i := range xs {
+		xs[i] = r.param()
+	}
+	return types.NewTuple(xs...)
+}
+
+func (r *importReader) param() *types.Var {
+	pos := r.pos()
+	name := r.ident()
+	typ := r.typ()
+	return types.NewParam(pos, r.currPkg, name, typ)
+}
+
+func (r *importReader) bool() bool {
+	return r.uint64() != 0
+}
+
+func (r *importReader) int64() int64 {
+	n, err := binary.ReadVarint(&r.declReader)
+	if err != nil {
+		errorf("readVarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) uint64() uint64 {
+	n, err := binary.ReadUvarint(&r.declReader)
+	if err != nil {
+		errorf("readUvarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) byte() byte {
+	x, err := r.declReader.ReadByte()
+	if err != nil {
+		errorf("declReader.ReadByte: %v", err)
+	}
+	return x
+}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go
new file mode 100644
index 0000000000000000000000000000000000000000..463f2522714638323cb37cd9523a6be99d3bdac8
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go
@@ -0,0 +1,21 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.11
+
+package gcimporter
+
+import "go/types"
+
+func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
+	named := make([]*types.Named, len(embeddeds))
+	for i, e := range embeddeds {
+		var ok bool
+		named[i], ok = e.(*types.Named)
+		if !ok {
+			panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
+		}
+	}
+	return types.NewInterface(methods, named)
+}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go
new file mode 100644
index 0000000000000000000000000000000000000000..ab28b95cbb84f5dd327ab613498d261d6364c917
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go
@@ -0,0 +1,13 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.11
+
+package gcimporter
+
+import "go/types"
+
+func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
+	return types.NewInterfaceType(methods, embeddeds)
+}