diff --git a/cmd/golangorg/godoc/analysis/README b/cmd/golangorg/godoc/analysis/README
deleted file mode 100644
index d3e732e..0000000
--- a/cmd/golangorg/godoc/analysis/README
+++ /dev/null
@@ -1,111 +0,0 @@
-
-Type and Pointer Analysis to-do list
-====================================
-
-Alan Donovan <adonovan@google.com>
-
-
-Overall design
---------------
-
-We should re-run the type and pointer analyses periodically,
-as we do with the indexer.
-
-Version skew: how to mitigate the bad effects of stale URLs in old pages?
-We could record the file's length/CRC32/mtime in the go/loader, and
-refuse to decorate it with links unless they match at serving time.
-
-Use the VFS mechanism when (a) enumerating packages and (b) loading
-them.  (Requires planned changes to go/loader.)
-
-Future work: shard this using map/reduce for larger corpora.
-
-Testing: how does one test that a web page "looks right"?
-
-
-Bugs
-----
-
-(*ssa.Program).Create requires transitively error-free packages.  We
-can make this more robust by making the requirement transitively free
-of "hard" errors; soft errors are fine.
-
-Markup of compiler errors is slightly buggy because they overlap with
-other selections (e.g. Idents).  Fix.
-
-
-User Interface
---------------
-
-CALLGRAPH:
-- Add a search box: given a search node, expand path from each entry
-  point to it.
-- Cause hovering over a given node to highlight that node, and all
-  nodes that are logically identical to it.
-- Initially expand the callgraph trees (but not their toggle divs).
-
-CALLEES:
-- The '(' links are not very discoverable.  Highlight them?
-
-Type info:
-- In the source viewer's lower pane, use a toggle div around the
-  IMPLEMENTS and METHODSETS lists, like we do in the package view.
-  Only expand them initially if short.
-- Include IMPLEMENTS and METHOD SETS information in search index.
-- URLs in IMPLEMENTS/METHOD SETS always link to source, even from the
-  package docs view.  This makes sense for links to non-exported
-  types, but links to exported types and funcs should probably go to
-  other package docs.
-- Suppress toggle divs for empty method sets.
-
-Misc:
-- The [X] button in the lower pane is subject to scrolling.
-- Should the lower pane be floating?  An iframe?
-  When we change document.location by clicking on a link, it will go away.
-  How do we prevent that (a la Gmail's chat windows)?
-- Progress/status: for each file, display its analysis status, one of:
-   - not in analysis scope
-   - type analysis running...
-   - type analysis complete
-     (+ optionally: there were type errors in this file)
-   And if PTA requested:
-   - type analysis complete; PTA not attempted due to type errors
-   - PTA running...
-   - PTA complete
-- Scroll the selection into view, e.g. the vertical center, or better
-  still, under the pointer (assuming we have a mouse).
-
-
-More features
--------------
-
-Display the REFERRERS relation?  (Useful but potentially large.)
-
-Display the INSTANTIATIONS relation? i.e. given a type T, show the set of
-syntactic constructs that can instantiate it:
-    var x T
-    x := T{...}
-    x = new(T)
-    x = make([]T, n)
-    etc
-    + all INSTANTIATIONS of all S defined as struct{t T} or [n]T
-(Potentially a lot of information.)
-(Add this to guru too.)
-
-
-Optimisations
--------------
-
-Each call to addLink takes a (per-file) lock.  The locking is
-fine-grained so server latency isn't terrible, but overall it makes
-the link computation quite slow.  Batch update might be better.
-
-Memory usage is now about 1.5GB for GOROOT + go.tools.  It used to be 700MB.
-
-Optimize for time and space.  The main slowdown is the network I/O
-time caused by an increase in page size of about 3x: about 2x from
-HTML, and 0.7--2.1x from JSON (unindented vs indented).  The JSON
-contains a lot of filenames (e.g. 820 copies of 16 distinct
-filenames).  20% of the HTML is L%d spans (now disabled).  The HTML
-also contains lots of tooltips for long struct/interface types.
-De-dup or just abbreviate?  The actual formatting is very fast.
diff --git a/cmd/golangorg/godoc/analysis/analysis.go b/cmd/golangorg/godoc/analysis/analysis.go
deleted file mode 100644
index e393004..0000000
--- a/cmd/golangorg/godoc/analysis/analysis.go
+++ /dev/null
@@ -1,613 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package analysis performs type and pointer analysis
-// and generates mark-up for the Go source view.
-//
-// The Run method populates a Result object by running type and
-// (optionally) pointer analysis.  The Result object is thread-safe
-// and at all times may be accessed by a serving thread, even as it is
-// progressively populated as analysis facts are derived.
-//
-// The Result is a mapping from each godoc file URL
-// (e.g. /src/fmt/print.go) to information about that file.  The
-// information is a list of HTML markup links and a JSON array of
-// structured data values.  Some of the links call client-side
-// JavaScript functions that index this array.
-//
-// The analysis computes mark-up for the following relations:
-//
-// IMPORTS: for each ast.ImportSpec, the package that it denotes.
-//
-// RESOLUTION: for each ast.Ident, its kind and type, and the location
-// of its definition.
-//
-// METHOD SETS, IMPLEMENTS: for each ast.Ident defining a named type,
-// its method-set, the set of interfaces it implements or is
-// implemented by, and its size/align values.
-//
-// CALLERS, CALLEES: for each function declaration ('func' token), its
-// callers, and for each call-site ('(' token), its callees.
-//
-// CALLGRAPH: the package docs include an interactive viewer for the
-// intra-package call graph of "fmt".
-//
-// CHANNEL PEERS: for each channel operation make/<-/close, the set of
-// other channel ops that alias the same channel(s).
-//
-// ERRORS: for each locus of a frontend (scanner/parser/type) error, the
-// location is highlighted in red and hover text provides the compiler
-// error message.
-//
-package analysis // import "golang.org/x/website/cmd/golangorg/godoc/analysis"
-
-import (
-	"fmt"
-	"go/build"
-	"go/scanner"
-	"go/token"
-	"go/types"
-	"html"
-	"io"
-	"log"
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-	"sync"
-
-	"golang.org/x/tools/go/loader"
-	"golang.org/x/tools/go/pointer"
-	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/ssa/ssautil"
-)
-
-// -- links ------------------------------------------------------------
-
-// A Link is an HTML decoration of the bytes [Start, End) of a file.
-// Write is called before/after those bytes to emit the mark-up.
-type Link interface {
-	Start() int
-	End() int
-	Write(w io.Writer, _ int, start bool) // the godoc.LinkWriter signature
-}
-
-// An <a> element.
-type aLink struct {
-	start, end int    // =godoc.Segment
-	title      string // hover text
-	onclick    string // JS code (NB: trusted)
-	href       string // URL     (NB: trusted)
-}
-
-func (a aLink) Start() int { return a.start }
-func (a aLink) End() int   { return a.end }
-func (a aLink) Write(w io.Writer, _ int, start bool) {
-	if start {
-		fmt.Fprintf(w, `<a title='%s'`, html.EscapeString(a.title))
-		if a.onclick != "" {
-			fmt.Fprintf(w, ` onclick='%s'`, html.EscapeString(a.onclick))
-		}
-		if a.href != "" {
-			// TODO(adonovan): I think that in principle, a.href must first be
-			// url.QueryEscape'd, but if I do that, a leading slash becomes "%2F",
-			// which causes the browser to treat the path as relative, not absolute.
-			// WTF?
-			fmt.Fprintf(w, ` href='%s'`, html.EscapeString(a.href))
-		}
-		fmt.Fprintf(w, ">")
-	} else {
-		fmt.Fprintf(w, "</a>")
-	}
-}
-
-// An <a class='error'> element.
-type errorLink struct {
-	start int
-	msg   string
-}
-
-func (e errorLink) Start() int { return e.start }
-func (e errorLink) End() int   { return e.start + 1 }
-
-func (e errorLink) Write(w io.Writer, _ int, start bool) {
-	// <span> causes havoc, not sure why, so use <a>.
-	if start {
-		fmt.Fprintf(w, `<a class='error' title='%s'>`, html.EscapeString(e.msg))
-	} else {
-		fmt.Fprintf(w, "</a>")
-	}
-}
-
-// -- fileInfo ---------------------------------------------------------
-
-// FileInfo holds analysis information for the source file view.
-// Clients must not mutate it.
-type FileInfo struct {
-	Data  []interface{} // JSON serializable values
-	Links []Link        // HTML link markup
-}
-
-// A fileInfo is the server's store of hyperlinks and JSON data for a
-// particular file.
-type fileInfo struct {
-	mu        sync.Mutex
-	data      []interface{} // JSON objects
-	links     []Link
-	sorted    bool
-	hasErrors bool // TODO(adonovan): surface this in the UI
-}
-
-// addLink adds a link to the Go source file fi.
-func (fi *fileInfo) addLink(link Link) {
-	fi.mu.Lock()
-	fi.links = append(fi.links, link)
-	fi.sorted = false
-	if _, ok := link.(errorLink); ok {
-		fi.hasErrors = true
-	}
-	fi.mu.Unlock()
-}
-
-// addData adds the structured value x to the JSON data for the Go
-// source file fi.  Its index is returned.
-func (fi *fileInfo) addData(x interface{}) int {
-	fi.mu.Lock()
-	index := len(fi.data)
-	fi.data = append(fi.data, x)
-	fi.mu.Unlock()
-	return index
-}
-
-// get returns the file info in external form.
-// Callers must not mutate its fields.
-func (fi *fileInfo) get() FileInfo {
-	var r FileInfo
-	// Copy slices, to avoid races.
-	fi.mu.Lock()
-	r.Data = append(r.Data, fi.data...)
-	if !fi.sorted {
-		sort.Sort(linksByStart(fi.links))
-		fi.sorted = true
-	}
-	r.Links = append(r.Links, fi.links...)
-	fi.mu.Unlock()
-	return r
-}
-
-// PackageInfo holds analysis information for the package view.
-// Clients must not mutate it.
-type PackageInfo struct {
-	CallGraph      []*PCGNodeJSON
-	CallGraphIndex map[string]int
-	Types          []*TypeInfoJSON
-}
-
-type pkgInfo struct {
-	mu             sync.Mutex
-	callGraph      []*PCGNodeJSON
-	callGraphIndex map[string]int  // keys are (*ssa.Function).RelString()
-	types          []*TypeInfoJSON // type info for exported types
-}
-
-func (pi *pkgInfo) setCallGraph(callGraph []*PCGNodeJSON, callGraphIndex map[string]int) {
-	pi.mu.Lock()
-	pi.callGraph = callGraph
-	pi.callGraphIndex = callGraphIndex
-	pi.mu.Unlock()
-}
-
-func (pi *pkgInfo) addType(t *TypeInfoJSON) {
-	pi.mu.Lock()
-	pi.types = append(pi.types, t)
-	pi.mu.Unlock()
-}
-
-// get returns the package info in external form.
-// Callers must not mutate its fields.
-func (pi *pkgInfo) get() PackageInfo {
-	var r PackageInfo
-	// Copy slices, to avoid races.
-	pi.mu.Lock()
-	r.CallGraph = append(r.CallGraph, pi.callGraph...)
-	r.CallGraphIndex = pi.callGraphIndex
-	r.Types = append(r.Types, pi.types...)
-	pi.mu.Unlock()
-	return r
-}
-
-// -- Result -----------------------------------------------------------
-
-// Result contains the results of analysis.
-// The result contains a mapping from filenames to a set of HTML links
-// and JavaScript data referenced by the links.
-type Result struct {
-	mu        sync.Mutex           // guards maps (but not their contents)
-	status    string               // global analysis status
-	fileInfos map[string]*fileInfo // keys are godoc file URLs
-	pkgInfos  map[string]*pkgInfo  // keys are import paths
-}
-
-// fileInfo returns the fileInfo for the specified godoc file URL,
-// constructing it as needed.  Thread-safe.
-func (res *Result) fileInfo(url string) *fileInfo {
-	res.mu.Lock()
-	fi, ok := res.fileInfos[url]
-	if !ok {
-		if res.fileInfos == nil {
-			res.fileInfos = make(map[string]*fileInfo)
-		}
-		fi = new(fileInfo)
-		res.fileInfos[url] = fi
-	}
-	res.mu.Unlock()
-	return fi
-}
-
-// Status returns a human-readable description of the current analysis status.
-func (res *Result) Status() string {
-	res.mu.Lock()
-	defer res.mu.Unlock()
-	return res.status
-}
-
-func (res *Result) setStatusf(format string, args ...interface{}) {
-	res.mu.Lock()
-	res.status = fmt.Sprintf(format, args...)
-	log.Printf(format, args...)
-	res.mu.Unlock()
-}
-
-// FileInfo returns new slices containing opaque JSON values and the
-// HTML link markup for the specified godoc file URL.  Thread-safe.
-// Callers must not mutate the elements.
-// It returns "zero" if no data is available.
-//
-func (res *Result) FileInfo(url string) (fi FileInfo) {
-	return res.fileInfo(url).get()
-}
-
-// pkgInfo returns the pkgInfo for the specified import path,
-// constructing it as needed.  Thread-safe.
-func (res *Result) pkgInfo(importPath string) *pkgInfo {
-	res.mu.Lock()
-	pi, ok := res.pkgInfos[importPath]
-	if !ok {
-		if res.pkgInfos == nil {
-			res.pkgInfos = make(map[string]*pkgInfo)
-		}
-		pi = new(pkgInfo)
-		res.pkgInfos[importPath] = pi
-	}
-	res.mu.Unlock()
-	return pi
-}
-
-// PackageInfo returns new slices of JSON values for the callgraph and
-// type info for the specified package.  Thread-safe.
-// Callers must not mutate its fields.
-// PackageInfo returns "zero" if no data is available.
-//
-func (res *Result) PackageInfo(importPath string) PackageInfo {
-	return res.pkgInfo(importPath).get()
-}
-
-// -- analysis ---------------------------------------------------------
-
-type analysis struct {
-	result    *Result
-	prog      *ssa.Program
-	ops       []chanOp       // all channel ops in program
-	allNamed  []*types.Named // all "defined" (formerly "named") types in the program
-	ptaConfig pointer.Config
-	path2url  map[string]string // maps openable path to godoc file URL (/src/fmt/print.go)
-	pcgs      map[*ssa.Package]*packageCallGraph
-}
-
-// fileAndOffset returns the file and offset for a given pos.
-func (a *analysis) fileAndOffset(pos token.Pos) (fi *fileInfo, offset int) {
-	return a.fileAndOffsetPosn(a.prog.Fset.Position(pos))
-}
-
-// fileAndOffsetPosn returns the file and offset for a given position.
-func (a *analysis) fileAndOffsetPosn(posn token.Position) (fi *fileInfo, offset int) {
-	url := a.path2url[posn.Filename]
-	return a.result.fileInfo(url), posn.Offset
-}
-
-// posURL returns the URL of the source extent [pos, pos+len).
-func (a *analysis) posURL(pos token.Pos, len int) string {
-	if pos == token.NoPos {
-		return ""
-	}
-	posn := a.prog.Fset.Position(pos)
-	url := a.path2url[posn.Filename]
-	return fmt.Sprintf("%s?s=%d:%d#L%d",
-		url, posn.Offset, posn.Offset+len, posn.Line)
-}
-
-// ----------------------------------------------------------------------
-
-// Run runs program analysis and computes the resulting markup,
-// populating *result in a thread-safe manner, first with type
-// information then later with pointer analysis information if
-// enabled by the pta flag.
-//
-func Run(pta bool, result *Result) {
-	conf := loader.Config{
-		AllowErrors: true,
-	}
-
-	// Silence the default error handler.
-	// Don't print all errors; we'll report just
-	// one per errant package later.
-	conf.TypeChecker.Error = func(e error) {}
-
-	var roots, args []string // roots[i] ends with os.PathSeparator
-
-	// Enumerate packages in $GOROOT.
-	root := filepath.Join(build.Default.GOROOT, "src") + string(os.PathSeparator)
-	roots = append(roots, root)
-	args = allPackages(root)
-	log.Printf("GOROOT=%s: %s\n", root, args)
-
-	// Enumerate packages in $GOPATH.
-	for i, dir := range filepath.SplitList(build.Default.GOPATH) {
-		root := filepath.Join(dir, "src") + string(os.PathSeparator)
-		roots = append(roots, root)
-		pkgs := allPackages(root)
-		log.Printf("GOPATH[%d]=%s: %s\n", i, root, pkgs)
-		args = append(args, pkgs...)
-	}
-
-	// Uncomment to make startup quicker during debugging.
-	//args = []string{"golang.org/x/website/cmd/golangorg"}
-	//args = []string{"fmt"}
-
-	if _, err := conf.FromArgs(args, true); err != nil {
-		// TODO(adonovan): degrade gracefully, not fail totally.
-		// (The crippling case is a parse error in an external test file.)
-		result.setStatusf("Analysis failed: %s.", err) // import error
-		return
-	}
-
-	result.setStatusf("Loading and type-checking packages...")
-	iprog, err := conf.Load()
-	if iprog != nil {
-		// Report only the first error of each package.
-		for _, info := range iprog.AllPackages {
-			for _, err := range info.Errors {
-				fmt.Fprintln(os.Stderr, err)
-				break
-			}
-		}
-		log.Printf("Loaded %d packages.", len(iprog.AllPackages))
-	}
-	if err != nil {
-		result.setStatusf("Loading failed: %s.\n", err)
-		return
-	}
-
-	// Create SSA-form program representation.
-	// Only the transitively error-free packages are used.
-	prog := ssautil.CreateProgram(iprog, ssa.GlobalDebug)
-
-	// Create a "testmain" package for each package with tests.
-	for _, pkg := range prog.AllPackages() {
-		if testmain := prog.CreateTestMainPackage(pkg); testmain != nil {
-			log.Printf("Adding tests for %s", pkg.Pkg.Path())
-		}
-	}
-
-	// Build SSA code for bodies of all functions in the whole program.
-	result.setStatusf("Constructing SSA form...")
-	prog.Build()
-	log.Print("SSA construction complete")
-
-	a := analysis{
-		result: result,
-		prog:   prog,
-		pcgs:   make(map[*ssa.Package]*packageCallGraph),
-	}
-
-	// Build a mapping from openable filenames to godoc file URLs,
-	// i.e. "/src/" plus path relative to GOROOT/src or GOPATH[i]/src.
-	a.path2url = make(map[string]string)
-	for _, info := range iprog.AllPackages {
-	nextfile:
-		for _, f := range info.Files {
-			if f.Pos() == 0 {
-				continue // e.g. files generated by cgo
-			}
-			abs := iprog.Fset.File(f.Pos()).Name()
-			// Find the root to which this file belongs.
-			for _, root := range roots {
-				rel := strings.TrimPrefix(abs, root)
-				if len(rel) < len(abs) {
-					a.path2url[abs] = "/src/" + filepath.ToSlash(rel)
-					continue nextfile
-				}
-			}
-
-			log.Printf("Can't locate file %s (package %q) beneath any root",
-				abs, info.Pkg.Path())
-		}
-	}
-
-	// Add links for scanner, parser, type-checker errors.
-	// TODO(adonovan): fix: these links can overlap with
-	// identifier markup, causing the renderer to emit some
-	// characters twice.
-	errors := make(map[token.Position][]string)
-	for _, info := range iprog.AllPackages {
-		for _, err := range info.Errors {
-			switch err := err.(type) {
-			case types.Error:
-				posn := a.prog.Fset.Position(err.Pos)
-				errors[posn] = append(errors[posn], err.Msg)
-			case scanner.ErrorList:
-				for _, e := range err {
-					errors[e.Pos] = append(errors[e.Pos], e.Msg)
-				}
-			default:
-				log.Printf("Package %q has error (%T) without position: %v\n",
-					info.Pkg.Path(), err, err)
-			}
-		}
-	}
-	for posn, errs := range errors {
-		fi, offset := a.fileAndOffsetPosn(posn)
-		fi.addLink(errorLink{
-			start: offset,
-			msg:   strings.Join(errs, "\n"),
-		})
-	}
-
-	// ---------- type-based analyses ----------
-
-	// Compute the all-pairs IMPLEMENTS relation.
-	// Collect all named types, even local types
-	// (which can have methods via promotion)
-	// and the built-in "error".
-	errorType := types.Universe.Lookup("error").Type().(*types.Named)
-	a.allNamed = append(a.allNamed, errorType)
-	for _, info := range iprog.AllPackages {
-		for _, obj := range info.Defs {
-			if obj, ok := obj.(*types.TypeName); ok {
-				if named, ok := obj.Type().(*types.Named); ok {
-					a.allNamed = append(a.allNamed, named)
-				}
-			}
-		}
-	}
-	log.Print("Computing implements relation...")
-	facts := computeImplements(&a.prog.MethodSets, a.allNamed)
-
-	// Add the type-based analysis results.
-	log.Print("Extracting type info...")
-	for _, info := range iprog.AllPackages {
-		a.doTypeInfo(info, facts)
-	}
-
-	a.visitInstrs(pta)
-
-	result.setStatusf("Type analysis complete.")
-
-	if pta {
-		mainPkgs := ssautil.MainPackages(prog.AllPackages())
-		log.Print("Transitively error-free main packages: ", mainPkgs)
-		a.pointer(mainPkgs)
-	}
-}
-
-// visitInstrs visits all SSA instructions in the program.
-func (a *analysis) visitInstrs(pta bool) {
-	log.Print("Visit instructions...")
-	for fn := range ssautil.AllFunctions(a.prog) {
-		for _, b := range fn.Blocks {
-			for _, instr := range b.Instrs {
-				// CALLEES (static)
-				// (Dynamic calls require pointer analysis.)
-				//
-				// We use the SSA representation to find the static callee,
-				// since in many cases it does better than the
-				// types.Info.{Refs,Selection} information.  For example:
-				//
-				//   defer func(){}()      // static call to anon function
-				//   f := func(){}; f()    // static call to anon function
-				//   f := fmt.Println; f() // static call to named function
-				//
-				// The downside is that we get no static callee information
-				// for packages that (transitively) contain errors.
-				if site, ok := instr.(ssa.CallInstruction); ok {
-					if callee := site.Common().StaticCallee(); callee != nil {
-						// TODO(adonovan): callgraph: elide wrappers.
-						// (Do static calls ever go to wrappers?)
-						if site.Common().Pos() != token.NoPos {
-							a.addCallees(site, []*ssa.Function{callee})
-						}
-					}
-				}
-
-				if !pta {
-					continue
-				}
-
-				// CHANNEL PEERS
-				// Collect send/receive/close instructions in the whole ssa.Program.
-				for _, op := range chanOps(instr) {
-					a.ops = append(a.ops, op)
-					a.ptaConfig.AddQuery(op.ch) // add channel ssa.Value to PTA query
-				}
-			}
-		}
-	}
-	log.Print("Visit instructions complete")
-}
-
-// pointer runs the pointer analysis.
-func (a *analysis) pointer(mainPkgs []*ssa.Package) {
-	// Run the pointer analysis and build the complete callgraph.
-	a.ptaConfig.Mains = mainPkgs
-	a.ptaConfig.BuildCallGraph = true
-	a.ptaConfig.Reflection = false // (for now)
-
-	a.result.setStatusf("Pointer analysis running...")
-
-	ptares, err := pointer.Analyze(&a.ptaConfig)
-	if err != nil {
-		// If this happens, it indicates a bug.
-		a.result.setStatusf("Pointer analysis failed: %s.", err)
-		return
-	}
-	log.Print("Pointer analysis complete.")
-
-	// Add the results of pointer analysis.
-
-	a.result.setStatusf("Computing channel peers...")
-	a.doChannelPeers(ptares.Queries)
-	a.result.setStatusf("Computing dynamic call graph edges...")
-	a.doCallgraph(ptares.CallGraph)
-
-	a.result.setStatusf("Analysis complete.")
-}
-
-type linksByStart []Link
-
-func (a linksByStart) Less(i, j int) bool { return a[i].Start() < a[j].Start() }
-func (a linksByStart) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-func (a linksByStart) Len() int           { return len(a) }
-
-// allPackages returns a new sorted slice of all packages beneath the
-// specified package root directory, e.g. $GOROOT/src or $GOPATH/src.
-// Derived from from go/ssa/stdlib_test.go
-// root must end with os.PathSeparator.
-//
-// TODO(adonovan): use buildutil.AllPackages when the tree thaws.
-func allPackages(root string) []string {
-	var pkgs []string
-	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
-		if info == nil {
-			return nil // non-existent root directory?
-		}
-		if !info.IsDir() {
-			return nil // not a directory
-		}
-		// Prune the search if we encounter any of these names:
-		base := filepath.Base(path)
-		if base == "testdata" || strings.HasPrefix(base, ".") {
-			return filepath.SkipDir
-		}
-		pkg := filepath.ToSlash(strings.TrimPrefix(path, root))
-		switch pkg {
-		case "builtin":
-			return filepath.SkipDir
-		case "":
-			return nil // ignore root of tree
-		}
-		pkgs = append(pkgs, pkg)
-		return nil
-	})
-	return pkgs
-}
diff --git a/cmd/golangorg/godoc/analysis/callgraph.go b/cmd/golangorg/godoc/analysis/callgraph.go
deleted file mode 100644
index 492022d..0000000
--- a/cmd/golangorg/godoc/analysis/callgraph.go
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package analysis
-
-// This file computes the CALLERS and CALLEES relations from the call
-// graph.  CALLERS/CALLEES information is displayed in the lower pane
-// when a "func" token or ast.CallExpr.Lparen is clicked, respectively.
-
-import (
-	"fmt"
-	"go/ast"
-	"go/token"
-	"go/types"
-	"log"
-	"math/big"
-	"sort"
-
-	"golang.org/x/tools/go/callgraph"
-	"golang.org/x/tools/go/ssa"
-)
-
-// doCallgraph computes the CALLEES and CALLERS relations.
-func (a *analysis) doCallgraph(cg *callgraph.Graph) {
-	log.Print("Deleting synthetic nodes...")
-	// TODO(adonovan): opt: DeleteSyntheticNodes is asymptotically
-	// inefficient and can be (unpredictably) slow.
-	cg.DeleteSyntheticNodes()
-	log.Print("Synthetic nodes deleted")
-
-	// Populate nodes of package call graphs (PCGs).
-	for _, n := range cg.Nodes {
-		a.pcgAddNode(n.Func)
-	}
-	// Within each PCG, sort funcs by name.
-	for _, pcg := range a.pcgs {
-		pcg.sortNodes()
-	}
-
-	calledFuncs := make(map[ssa.CallInstruction]map[*ssa.Function]bool)
-	callingSites := make(map[*ssa.Function]map[ssa.CallInstruction]bool)
-	for _, n := range cg.Nodes {
-		for _, e := range n.Out {
-			if e.Site == nil {
-				continue // a call from a synthetic node such as <root>
-			}
-
-			// Add (site pos, callee) to calledFuncs.
-			// (Dynamic calls only.)
-			callee := e.Callee.Func
-
-			a.pcgAddEdge(n.Func, callee)
-
-			if callee.Synthetic != "" {
-				continue // call of a package initializer
-			}
-
-			if e.Site.Common().StaticCallee() == nil {
-				// dynamic call
-				// (CALLEES information for static calls
-				// is computed using SSA information.)
-				lparen := e.Site.Common().Pos()
-				if lparen != token.NoPos {
-					fns := calledFuncs[e.Site]
-					if fns == nil {
-						fns = make(map[*ssa.Function]bool)
-						calledFuncs[e.Site] = fns
-					}
-					fns[callee] = true
-				}
-			}
-
-			// Add (callee, site) to callingSites.
-			fns := callingSites[callee]
-			if fns == nil {
-				fns = make(map[ssa.CallInstruction]bool)
-				callingSites[callee] = fns
-			}
-			fns[e.Site] = true
-		}
-	}
-
-	// CALLEES.
-	log.Print("Callees...")
-	for site, fns := range calledFuncs {
-		var funcs funcsByPos
-		for fn := range fns {
-			funcs = append(funcs, fn)
-		}
-		sort.Sort(funcs)
-
-		a.addCallees(site, funcs)
-	}
-
-	// CALLERS
-	log.Print("Callers...")
-	for callee, sites := range callingSites {
-		pos := funcToken(callee)
-		if pos == token.NoPos {
-			log.Printf("CALLERS: skipping %s: no pos", callee)
-			continue
-		}
-
-		var this *types.Package // for relativizing names
-		if callee.Pkg != nil {
-			this = callee.Pkg.Pkg
-		}
-
-		// Compute sites grouped by parent, with text and URLs.
-		sitesByParent := make(map[*ssa.Function]sitesByPos)
-		for site := range sites {
-			fn := site.Parent()
-			sitesByParent[fn] = append(sitesByParent[fn], site)
-		}
-		var funcs funcsByPos
-		for fn := range sitesByParent {
-			funcs = append(funcs, fn)
-		}
-		sort.Sort(funcs)
-
-		v := callersJSON{
-			Callee:  callee.String(),
-			Callers: []callerJSON{}, // (JS wants non-nil)
-		}
-		for _, fn := range funcs {
-			caller := callerJSON{
-				Func:  prettyFunc(this, fn),
-				Sites: []anchorJSON{}, // (JS wants non-nil)
-			}
-			sites := sitesByParent[fn]
-			sort.Sort(sites)
-			for _, site := range sites {
-				pos := site.Common().Pos()
-				if pos != token.NoPos {
-					caller.Sites = append(caller.Sites, anchorJSON{
-						Text: fmt.Sprintf("%d", a.prog.Fset.Position(pos).Line),
-						Href: a.posURL(pos, len("(")),
-					})
-				}
-			}
-			v.Callers = append(v.Callers, caller)
-		}
-
-		fi, offset := a.fileAndOffset(pos)
-		fi.addLink(aLink{
-			start:   offset,
-			end:     offset + len("func"),
-			title:   fmt.Sprintf("%d callers", len(sites)),
-			onclick: fmt.Sprintf("onClickCallers(%d)", fi.addData(v)),
-		})
-	}
-
-	// PACKAGE CALLGRAPH
-	log.Print("Package call graph...")
-	for pkg, pcg := range a.pcgs {
-		// Maps (*ssa.Function).RelString() to index in JSON CALLGRAPH array.
-		index := make(map[string]int)
-
-		// Treat exported functions (and exported methods of
-		// exported named types) as roots even if they aren't
-		// actually called from outside the package.
-		for i, n := range pcg.nodes {
-			if i == 0 || n.fn.Object() == nil || !n.fn.Object().Exported() {
-				continue
-			}
-			recv := n.fn.Signature.Recv()
-			if recv == nil || deref(recv.Type()).(*types.Named).Obj().Exported() {
-				roots := &pcg.nodes[0].edges
-				roots.SetBit(roots, i, 1)
-			}
-			index[n.fn.RelString(pkg.Pkg)] = i
-		}
-
-		json := a.pcgJSON(pcg)
-
-		// TODO(adonovan): pkg.Path() is not unique!
-		// It is possible to declare a non-test package called x_test.
-		a.result.pkgInfo(pkg.Pkg.Path()).setCallGraph(json, index)
-	}
-}
-
-// addCallees adds client data and links for the facts that site calls fns.
-func (a *analysis) addCallees(site ssa.CallInstruction, fns []*ssa.Function) {
-	v := calleesJSON{
-		Descr:   site.Common().Description(),
-		Callees: []anchorJSON{}, // (JS wants non-nil)
-	}
-	var this *types.Package // for relativizing names
-	if p := site.Parent().Package(); p != nil {
-		this = p.Pkg
-	}
-
-	for _, fn := range fns {
-		v.Callees = append(v.Callees, anchorJSON{
-			Text: prettyFunc(this, fn),
-			Href: a.posURL(funcToken(fn), len("func")),
-		})
-	}
-
-	fi, offset := a.fileAndOffset(site.Common().Pos())
-	fi.addLink(aLink{
-		start:   offset,
-		end:     offset + len("("),
-		title:   fmt.Sprintf("%d callees", len(v.Callees)),
-		onclick: fmt.Sprintf("onClickCallees(%d)", fi.addData(v)),
-	})
-}
-
-// -- utilities --------------------------------------------------------
-
-// stable order within packages but undefined across packages.
-type funcsByPos []*ssa.Function
-
-func (a funcsByPos) Less(i, j int) bool { return a[i].Pos() < a[j].Pos() }
-func (a funcsByPos) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-func (a funcsByPos) Len() int           { return len(a) }
-
-type sitesByPos []ssa.CallInstruction
-
-func (a sitesByPos) Less(i, j int) bool { return a[i].Common().Pos() < a[j].Common().Pos() }
-func (a sitesByPos) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-func (a sitesByPos) Len() int           { return len(a) }
-
-func funcToken(fn *ssa.Function) token.Pos {
-	switch syntax := fn.Syntax().(type) {
-	case *ast.FuncLit:
-		return syntax.Type.Func
-	case *ast.FuncDecl:
-		return syntax.Type.Func
-	}
-	return token.NoPos
-}
-
-// prettyFunc pretty-prints fn for the user interface.
-// TODO(adonovan): return HTML so we have more markup freedom.
-func prettyFunc(this *types.Package, fn *ssa.Function) string {
-	if fn.Parent() != nil {
-		return fmt.Sprintf("%s in %s",
-			types.TypeString(fn.Signature, types.RelativeTo(this)),
-			prettyFunc(this, fn.Parent()))
-	}
-	if fn.Synthetic != "" && fn.Name() == "init" {
-		// (This is the actual initializer, not a declared 'func init').
-		if fn.Pkg.Pkg == this {
-			return "package initializer"
-		}
-		return fmt.Sprintf("%q package initializer", fn.Pkg.Pkg.Path())
-	}
-	return fn.RelString(this)
-}
-
-// -- intra-package callgraph ------------------------------------------
-
-// pcgNode represents a node in the package call graph (PCG).
-type pcgNode struct {
-	fn     *ssa.Function
-	pretty string  // cache of prettyFunc(fn)
-	edges  big.Int // set of callee func indices
-}
-
-// A packageCallGraph represents the intra-package edges of the global call graph.
-// The zeroth node indicates "all external functions".
-type packageCallGraph struct {
-	nodeIndex map[*ssa.Function]int // maps func to node index (a small int)
-	nodes     []*pcgNode            // maps node index to node
-}
-
-// sortNodes populates pcg.nodes in name order and updates the nodeIndex.
-func (pcg *packageCallGraph) sortNodes() {
-	nodes := make([]*pcgNode, 0, len(pcg.nodeIndex))
-	nodes = append(nodes, &pcgNode{fn: nil, pretty: "<external>"})
-	for fn := range pcg.nodeIndex {
-		nodes = append(nodes, &pcgNode{
-			fn:     fn,
-			pretty: prettyFunc(fn.Pkg.Pkg, fn),
-		})
-	}
-	sort.Sort(pcgNodesByPretty(nodes[1:]))
-	for i, n := range nodes {
-		pcg.nodeIndex[n.fn] = i
-	}
-	pcg.nodes = nodes
-}
-
-func (pcg *packageCallGraph) addEdge(caller, callee *ssa.Function) {
-	var callerIndex int
-	if caller.Pkg == callee.Pkg {
-		// intra-package edge
-		callerIndex = pcg.nodeIndex[caller]
-		if callerIndex < 1 {
-			panic(caller)
-		}
-	}
-	edges := &pcg.nodes[callerIndex].edges
-	edges.SetBit(edges, pcg.nodeIndex[callee], 1)
-}
-
-func (a *analysis) pcgAddNode(fn *ssa.Function) {
-	if fn.Pkg == nil {
-		return
-	}
-	pcg, ok := a.pcgs[fn.Pkg]
-	if !ok {
-		pcg = &packageCallGraph{nodeIndex: make(map[*ssa.Function]int)}
-		a.pcgs[fn.Pkg] = pcg
-	}
-	pcg.nodeIndex[fn] = -1
-}
-
-func (a *analysis) pcgAddEdge(caller, callee *ssa.Function) {
-	if callee.Pkg != nil {
-		a.pcgs[callee.Pkg].addEdge(caller, callee)
-	}
-}
-
-// pcgJSON returns a new slice of callgraph JSON values.
-func (a *analysis) pcgJSON(pcg *packageCallGraph) []*PCGNodeJSON {
-	var nodes []*PCGNodeJSON
-	for _, n := range pcg.nodes {
-
-		// TODO(adonovan): why is there no good way to iterate
-		// over the set bits of a big.Int?
-		var callees []int
-		nbits := n.edges.BitLen()
-		for j := 0; j < nbits; j++ {
-			if n.edges.Bit(j) == 1 {
-				callees = append(callees, j)
-			}
-		}
-
-		var pos token.Pos
-		if n.fn != nil {
-			pos = funcToken(n.fn)
-		}
-		nodes = append(nodes, &PCGNodeJSON{
-			Func: anchorJSON{
-				Text: n.pretty,
-				Href: a.posURL(pos, len("func")),
-			},
-			Callees: callees,
-		})
-	}
-	return nodes
-}
-
-type pcgNodesByPretty []*pcgNode
-
-func (a pcgNodesByPretty) Less(i, j int) bool { return a[i].pretty < a[j].pretty }
-func (a pcgNodesByPretty) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-func (a pcgNodesByPretty) Len() int           { return len(a) }
diff --git a/cmd/golangorg/godoc/analysis/implements.go b/cmd/golangorg/godoc/analysis/implements.go
deleted file mode 100644
index 5a29579..0000000
--- a/cmd/golangorg/godoc/analysis/implements.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package analysis
-
-// This file computes the "implements" relation over all pairs of
-// named types in the program.  (The mark-up is done by typeinfo.go.)
-
-// TODO(adonovan): do we want to report implements(C, I) where C and I
-// belong to different packages and at least one is not exported?
-
-import (
-	"go/types"
-	"sort"
-
-	"golang.org/x/tools/go/types/typeutil"
-)
-
-// computeImplements computes the "implements" relation over all pairs
-// of named types in allNamed.
-func computeImplements(cache *typeutil.MethodSetCache, allNamed []*types.Named) map[*types.Named]implementsFacts {
-	// Information about a single type's method set.
-	type msetInfo struct {
-		typ          types.Type
-		mset         *types.MethodSet
-		mask1, mask2 uint64
-	}
-
-	initMsetInfo := func(info *msetInfo, typ types.Type) {
-		info.typ = typ
-		info.mset = cache.MethodSet(typ)
-		for i := 0; i < info.mset.Len(); i++ {
-			name := info.mset.At(i).Obj().Name()
-			info.mask1 |= 1 << methodBit(name[0])
-			info.mask2 |= 1 << methodBit(name[len(name)-1])
-		}
-	}
-
-	// satisfies(T, U) reports whether type T satisfies type U.
-	// U must be an interface.
-	//
-	// Since there are thousands of types (and thus millions of
-	// pairs of types) and types.Assignable(T, U) is relatively
-	// expensive, we compute assignability directly from the
-	// method sets.  (At least one of T and U must be an
-	// interface.)
-	//
-	// We use a trick (thanks gri!) related to a Bloom filter to
-	// quickly reject most tests, which are false.  For each
-	// method set, we precompute a mask, a set of bits, one per
-	// distinct initial byte of each method name.  Thus the mask
-	// for io.ReadWriter would be {'R','W'}.  AssignableTo(T, U)
-	// cannot be true unless mask(T)&mask(U)==mask(U).
-	//
-	// As with a Bloom filter, we can improve precision by testing
-	// additional hashes, e.g. using the last letter of each
-	// method name, so long as the subset mask property holds.
-	//
-	// When analyzing the standard library, there are about 1e6
-	// calls to satisfies(), of which 0.6% return true.  With a
-	// 1-hash filter, 95% of calls avoid the expensive check; with
-	// a 2-hash filter, this grows to 98.2%.
-	satisfies := func(T, U *msetInfo) bool {
-		return T.mask1&U.mask1 == U.mask1 &&
-			T.mask2&U.mask2 == U.mask2 &&
-			containsAllIdsOf(T.mset, U.mset)
-	}
-
-	// Information about a named type N, and perhaps also *N.
-	type namedInfo struct {
-		isInterface bool
-		base        msetInfo // N
-		ptr         msetInfo // *N, iff N !isInterface
-	}
-
-	var infos []namedInfo
-
-	// Precompute the method sets and their masks.
-	for _, N := range allNamed {
-		var info namedInfo
-		initMsetInfo(&info.base, N)
-		_, info.isInterface = N.Underlying().(*types.Interface)
-		if !info.isInterface {
-			initMsetInfo(&info.ptr, types.NewPointer(N))
-		}
-
-		if info.base.mask1|info.ptr.mask1 == 0 {
-			continue // neither N nor *N has methods
-		}
-
-		infos = append(infos, info)
-	}
-
-	facts := make(map[*types.Named]implementsFacts)
-
-	// Test all pairs of distinct named types (T, U).
-	// TODO(adonovan): opt: compute (U, T) at the same time.
-	for t := range infos {
-		T := &infos[t]
-		var to, from, fromPtr []types.Type
-		for u := range infos {
-			if t == u {
-				continue
-			}
-			U := &infos[u]
-			switch {
-			case T.isInterface && U.isInterface:
-				if satisfies(&U.base, &T.base) {
-					to = append(to, U.base.typ)
-				}
-				if satisfies(&T.base, &U.base) {
-					from = append(from, U.base.typ)
-				}
-			case T.isInterface: // U concrete
-				if satisfies(&U.base, &T.base) {
-					to = append(to, U.base.typ)
-				} else if satisfies(&U.ptr, &T.base) {
-					to = append(to, U.ptr.typ)
-				}
-			case U.isInterface: // T concrete
-				if satisfies(&T.base, &U.base) {
-					from = append(from, U.base.typ)
-				} else if satisfies(&T.ptr, &U.base) {
-					fromPtr = append(fromPtr, U.base.typ)
-				}
-			}
-		}
-
-		// Sort types (arbitrarily) to avoid nondeterminism.
-		sort.Sort(typesByString(to))
-		sort.Sort(typesByString(from))
-		sort.Sort(typesByString(fromPtr))
-
-		facts[T.base.typ.(*types.Named)] = implementsFacts{to, from, fromPtr}
-	}
-
-	return facts
-}
-
-type implementsFacts struct {
-	to      []types.Type // named or ptr-to-named types assignable to interface T
-	from    []types.Type // named interfaces assignable from T
-	fromPtr []types.Type // named interfaces assignable only from *T
-}
-
-type typesByString []types.Type
-
-func (p typesByString) Len() int           { return len(p) }
-func (p typesByString) Less(i, j int) bool { return p[i].String() < p[j].String() }
-func (p typesByString) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// methodBit returns the index of x in [a-zA-Z], or 52 if not found.
-func methodBit(x byte) uint64 {
-	switch {
-	case 'a' <= x && x <= 'z':
-		return uint64(x - 'a')
-	case 'A' <= x && x <= 'Z':
-		return uint64(26 + x - 'A')
-	}
-	return 52 // all other bytes
-}
-
-// containsAllIdsOf reports whether the method identifiers of T are a
-// superset of those in U.  If U belongs to an interface type, the
-// result is equal to types.Assignable(T, U), but is cheaper to compute.
-//
-// TODO(gri): make this a method of *types.MethodSet.
-//
-func containsAllIdsOf(T, U *types.MethodSet) bool {
-	t, tlen := 0, T.Len()
-	u, ulen := 0, U.Len()
-	for t < tlen && u < ulen {
-		tMeth := T.At(t).Obj()
-		uMeth := U.At(u).Obj()
-		tId := tMeth.Id()
-		uId := uMeth.Id()
-		if tId > uId {
-			// U has a method T lacks: fail.
-			return false
-		}
-		if tId < uId {
-			// T has a method U lacks: ignore it.
-			t++
-			continue
-		}
-		// U and T both have a method of this Id.  Check types.
-		if !types.Identical(tMeth.Type(), uMeth.Type()) {
-			return false // type mismatch
-		}
-		u++
-		t++
-	}
-	return u == ulen
-}
diff --git a/cmd/golangorg/godoc/analysis/json.go b/cmd/golangorg/godoc/analysis/json.go
deleted file mode 100644
index f897618..0000000
--- a/cmd/golangorg/godoc/analysis/json.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package analysis
-
-// This file defines types used by client-side JavaScript.
-
-type anchorJSON struct {
-	Text string // HTML
-	Href string // URL
-}
-
-type commOpJSON struct {
-	Op anchorJSON
-	Fn string
-}
-
-// JavaScript's onClickComm() expects a commJSON.
-type commJSON struct {
-	Ops []commOpJSON
-}
-
-// Indicates one of these forms of fact about a type T:
-// T "is implemented by <ByKind> type <Other>"  (ByKind != "", e.g. "array")
-// T "implements <Other>"                       (ByKind == "")
-type implFactJSON struct {
-	ByKind string `json:",omitempty"`
-	Other  anchorJSON
-}
-
-// Implements facts are grouped by form, for ease of reading.
-type implGroupJSON struct {
-	Descr string
-	Facts []implFactJSON
-}
-
-// JavaScript's onClickIdent() expects a TypeInfoJSON.
-type TypeInfoJSON struct {
-	Name        string // type name
-	Size, Align int64
-	Methods     []anchorJSON
-	ImplGroups  []implGroupJSON
-}
-
-// JavaScript's onClickCallees() expects a calleesJSON.
-type calleesJSON struct {
-	Descr   string
-	Callees []anchorJSON // markup for called function
-}
-
-type callerJSON struct {
-	Func  string
-	Sites []anchorJSON
-}
-
-// JavaScript's onClickCallers() expects a callersJSON.
-type callersJSON struct {
-	Callee  string
-	Callers []callerJSON
-}
-
-// JavaScript's cgAddChild requires a global array of PCGNodeJSON
-// called CALLGRAPH, representing the intra-package call graph.
-// The first element is special and represents "all external callers".
-type PCGNodeJSON struct {
-	Func    anchorJSON
-	Callees []int // indices within CALLGRAPH of nodes called by this one
-}
diff --git a/cmd/golangorg/godoc/analysis/peers.go b/cmd/golangorg/godoc/analysis/peers.go
deleted file mode 100644
index a742f06..0000000
--- a/cmd/golangorg/godoc/analysis/peers.go
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package analysis
-
-// This file computes the channel "peers" relation over all pairs of
-// channel operations in the program.  The peers are displayed in the
-// lower pane when a channel operation (make, <-, close) is clicked.
-
-// TODO(adonovan): handle calls to reflect.{Select,Recv,Send,Close} too,
-// then enable reflection in PTA.
-
-import (
-	"fmt"
-	"go/token"
-	"go/types"
-
-	"golang.org/x/tools/go/pointer"
-	"golang.org/x/tools/go/ssa"
-)
-
-func (a *analysis) doChannelPeers(ptsets map[ssa.Value]pointer.Pointer) {
-	addSendRecv := func(j *commJSON, op chanOp) {
-		j.Ops = append(j.Ops, commOpJSON{
-			Op: anchorJSON{
-				Text: op.mode,
-				Href: a.posURL(op.pos, op.len),
-			},
-			Fn: prettyFunc(nil, op.fn),
-		})
-	}
-
-	// Build an undirected bipartite multigraph (binary relation)
-	// of MakeChan ops and send/recv/close ops.
-	//
-	// TODO(adonovan): opt: use channel element types to partition
-	// the O(n^2) problem into subproblems.
-	aliasedOps := make(map[*ssa.MakeChan][]chanOp)
-	opToMakes := make(map[chanOp][]*ssa.MakeChan)
-	for _, op := range a.ops {
-		// Combine the PT sets from all contexts.
-		var makes []*ssa.MakeChan // aliased ops
-		ptr, ok := ptsets[op.ch]
-		if !ok {
-			continue // e.g. channel op in dead code
-		}
-		for _, label := range ptr.PointsTo().Labels() {
-			makechan, ok := label.Value().(*ssa.MakeChan)
-			if !ok {
-				continue // skip intrinsically-created channels for now
-			}
-			if makechan.Pos() == token.NoPos {
-				continue // not possible?
-			}
-			makes = append(makes, makechan)
-			aliasedOps[makechan] = append(aliasedOps[makechan], op)
-		}
-		opToMakes[op] = makes
-	}
-
-	// Now that complete relation is built, build links for ops.
-	for _, op := range a.ops {
-		v := commJSON{
-			Ops: []commOpJSON{}, // (JS wants non-nil)
-		}
-		ops := make(map[chanOp]bool)
-		for _, makechan := range opToMakes[op] {
-			v.Ops = append(v.Ops, commOpJSON{
-				Op: anchorJSON{
-					Text: "made",
-					Href: a.posURL(makechan.Pos()-token.Pos(len("make")),
-						len("make")),
-				},
-				Fn: makechan.Parent().RelString(op.fn.Package().Pkg),
-			})
-			for _, op := range aliasedOps[makechan] {
-				ops[op] = true
-			}
-		}
-		for op := range ops {
-			addSendRecv(&v, op)
-		}
-
-		// Add links for each aliased op.
-		fi, offset := a.fileAndOffset(op.pos)
-		fi.addLink(aLink{
-			start:   offset,
-			end:     offset + op.len,
-			title:   "show channel ops",
-			onclick: fmt.Sprintf("onClickComm(%d)", fi.addData(v)),
-		})
-	}
-	// Add links for makechan ops themselves.
-	for makechan, ops := range aliasedOps {
-		v := commJSON{
-			Ops: []commOpJSON{}, // (JS wants non-nil)
-		}
-		for _, op := range ops {
-			addSendRecv(&v, op)
-		}
-
-		fi, offset := a.fileAndOffset(makechan.Pos())
-		fi.addLink(aLink{
-			start:   offset - len("make"),
-			end:     offset,
-			title:   "show channel ops",
-			onclick: fmt.Sprintf("onClickComm(%d)", fi.addData(v)),
-		})
-	}
-}
-
-// -- utilities --------------------------------------------------------
-
-// chanOp abstracts an ssa.Send, ssa.Unop(ARROW), close(), or a SelectState.
-// Derived from cmd/guru/peers.go.
-type chanOp struct {
-	ch   ssa.Value
-	mode string // sent|received|closed
-	pos  token.Pos
-	len  int
-	fn   *ssa.Function
-}
-
-// chanOps returns a slice of all the channel operations in the instruction.
-// Derived from cmd/guru/peers.go.
-func chanOps(instr ssa.Instruction) []chanOp {
-	fn := instr.Parent()
-	var ops []chanOp
-	switch instr := instr.(type) {
-	case *ssa.UnOp:
-		if instr.Op == token.ARROW {
-			// TODO(adonovan): don't assume <-ch; could be 'range ch'.
-			ops = append(ops, chanOp{instr.X, "received", instr.Pos(), len("<-"), fn})
-		}
-	case *ssa.Send:
-		ops = append(ops, chanOp{instr.Chan, "sent", instr.Pos(), len("<-"), fn})
-	case *ssa.Select:
-		for _, st := range instr.States {
-			mode := "received"
-			if st.Dir == types.SendOnly {
-				mode = "sent"
-			}
-			ops = append(ops, chanOp{st.Chan, mode, st.Pos, len("<-"), fn})
-		}
-	case ssa.CallInstruction:
-		call := instr.Common()
-		if blt, ok := call.Value.(*ssa.Builtin); ok && blt.Name() == "close" {
-			pos := instr.Common().Pos()
-			ops = append(ops, chanOp{call.Args[0], "closed", pos - token.Pos(len("close")), len("close("), fn})
-		}
-	}
-	return ops
-}
diff --git a/cmd/golangorg/godoc/analysis/typeinfo.go b/cmd/golangorg/godoc/analysis/typeinfo.go
deleted file mode 100644
index e57683f..0000000
--- a/cmd/golangorg/godoc/analysis/typeinfo.go
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package analysis
-
-// This file computes the markup for information from go/types:
-// IMPORTS, identifier RESOLUTION, METHOD SETS, size/alignment, and
-// the IMPLEMENTS relation.
-//
-// IMPORTS links connect import specs to the documentation for the
-// imported package.
-//
-// RESOLUTION links referring identifiers to their defining
-// identifier, and adds tooltips for kind and type.
-//
-// METHOD SETS, size/alignment, and the IMPLEMENTS relation are
-// displayed in the lower pane when a type's defining identifier is
-// clicked.
-
-import (
-	"fmt"
-	"go/types"
-	"reflect"
-	"strconv"
-	"strings"
-
-	"golang.org/x/tools/go/loader"
-	"golang.org/x/tools/go/types/typeutil"
-)
-
-// TODO(adonovan): audit to make sure it's safe on ill-typed packages.
-
-// TODO(adonovan): use same Sizes as loader.Config.
-var sizes = types.StdSizes{WordSize: 8, MaxAlign: 8}
-
-func (a *analysis) doTypeInfo(info *loader.PackageInfo, implements map[*types.Named]implementsFacts) {
-	// We must not assume the corresponding SSA packages were
-	// created (i.e. were transitively error-free).
-
-	// IMPORTS
-	for _, f := range info.Files {
-		// Package decl.
-		fi, offset := a.fileAndOffset(f.Name.Pos())
-		fi.addLink(aLink{
-			start: offset,
-			end:   offset + len(f.Name.Name),
-			title: "Package docs for " + info.Pkg.Path(),
-			// TODO(adonovan): fix: we're putting the untrusted Path()
-			// into a trusted field.  What's the appropriate sanitizer?
-			href: "/pkg/" + info.Pkg.Path(),
-		})
-
-		// Import specs.
-		for _, imp := range f.Imports {
-			// Remove quotes.
-			L := int(imp.End()-imp.Path.Pos()) - len(`""`)
-			path, _ := strconv.Unquote(imp.Path.Value)
-			fi, offset := a.fileAndOffset(imp.Path.Pos())
-			fi.addLink(aLink{
-				start: offset + 1,
-				end:   offset + 1 + L,
-				title: "Package docs for " + path,
-				// TODO(adonovan): fix: we're putting the untrusted path
-				// into a trusted field.  What's the appropriate sanitizer?
-				href: "/pkg/" + path,
-			})
-		}
-	}
-
-	// RESOLUTION
-	qualifier := types.RelativeTo(info.Pkg)
-	for id, obj := range info.Uses {
-		// Position of the object definition.
-		pos := obj.Pos()
-		Len := len(obj.Name())
-
-		// Correct the position for non-renaming import specs.
-		//  import "sync/atomic"
-		//          ^^^^^^^^^^^
-		if obj, ok := obj.(*types.PkgName); ok && id.Name == obj.Imported().Name() {
-			// Assume this is a non-renaming import.
-			// NB: not true for degenerate renamings: `import foo "foo"`.
-			pos++
-			Len = len(obj.Imported().Path())
-		}
-
-		if obj.Pkg() == nil {
-			continue // don't mark up built-ins.
-		}
-
-		fi, offset := a.fileAndOffset(id.NamePos)
-		fi.addLink(aLink{
-			start: offset,
-			end:   offset + len(id.Name),
-			title: types.ObjectString(obj, qualifier),
-			href:  a.posURL(pos, Len),
-		})
-	}
-
-	// IMPLEMENTS & METHOD SETS
-	for _, obj := range info.Defs {
-		if obj, ok := obj.(*types.TypeName); ok {
-			if named, ok := obj.Type().(*types.Named); ok {
-				a.namedType(named, implements)
-			}
-		}
-	}
-}
-
-func (a *analysis) namedType(T *types.Named, implements map[*types.Named]implementsFacts) {
-	obj := T.Obj()
-	qualifier := types.RelativeTo(obj.Pkg())
-	v := &TypeInfoJSON{
-		Name:    obj.Name(),
-		Size:    sizes.Sizeof(T),
-		Align:   sizes.Alignof(T),
-		Methods: []anchorJSON{}, // (JS wants non-nil)
-	}
-
-	// addFact adds the fact "is implemented by T" (by) or
-	// "implements T" (!by) to group.
-	addFact := func(group *implGroupJSON, T types.Type, by bool) {
-		Tobj := deref(T).(*types.Named).Obj()
-		var byKind string
-		if by {
-			// Show underlying kind of implementing type,
-			// e.g. "slice", "array", "struct".
-			s := reflect.TypeOf(T.Underlying()).String()
-			byKind = strings.ToLower(strings.TrimPrefix(s, "*types."))
-		}
-		group.Facts = append(group.Facts, implFactJSON{
-			ByKind: byKind,
-			Other: anchorJSON{
-				Href: a.posURL(Tobj.Pos(), len(Tobj.Name())),
-				Text: types.TypeString(T, qualifier),
-			},
-		})
-	}
-
-	// IMPLEMENTS
-	if r, ok := implements[T]; ok {
-		if isInterface(T) {
-			// "T is implemented by <conc>" ...
-			// "T is implemented by <iface>"...
-			// "T implements        <iface>"...
-			group := implGroupJSON{
-				Descr: types.TypeString(T, qualifier),
-			}
-			// Show concrete types first; use two passes.
-			for _, sub := range r.to {
-				if !isInterface(sub) {
-					addFact(&group, sub, true)
-				}
-			}
-			for _, sub := range r.to {
-				if isInterface(sub) {
-					addFact(&group, sub, true)
-				}
-			}
-			for _, super := range r.from {
-				addFact(&group, super, false)
-			}
-			v.ImplGroups = append(v.ImplGroups, group)
-		} else {
-			// T is concrete.
-			if r.from != nil {
-				// "T implements <iface>"...
-				group := implGroupJSON{
-					Descr: types.TypeString(T, qualifier),
-				}
-				for _, super := range r.from {
-					addFact(&group, super, false)
-				}
-				v.ImplGroups = append(v.ImplGroups, group)
-			}
-			if r.fromPtr != nil {
-				// "*C implements <iface>"...
-				group := implGroupJSON{
-					Descr: "*" + types.TypeString(T, qualifier),
-				}
-				for _, psuper := range r.fromPtr {
-					addFact(&group, psuper, false)
-				}
-				v.ImplGroups = append(v.ImplGroups, group)
-			}
-		}
-	}
-
-	// METHOD SETS
-	for _, sel := range typeutil.IntuitiveMethodSet(T, &a.prog.MethodSets) {
-		meth := sel.Obj().(*types.Func)
-		pos := meth.Pos() // may be 0 for error.Error
-		v.Methods = append(v.Methods, anchorJSON{
-			Href: a.posURL(pos, len(meth.Name())),
-			Text: types.SelectionString(sel, qualifier),
-		})
-	}
-
-	// Since there can be many specs per decl, we
-	// can't attach the link to the keyword 'type'
-	// (as we do with 'func'); we use the Ident.
-	fi, offset := a.fileAndOffset(obj.Pos())
-	fi.addLink(aLink{
-		start:   offset,
-		end:     offset + len(obj.Name()),
-		title:   fmt.Sprintf("type info for %s", obj.Name()),
-		onclick: fmt.Sprintf("onClickTypeInfo(%d)", fi.addData(v)),
-	})
-
-	// Add info for exported package-level types to the package info.
-	if obj.Exported() && isPackageLevel(obj) {
-		// TODO(adonovan): Path is not unique!
-		// It is possible to declare a non-test package called x_test.
-		a.result.pkgInfo(obj.Pkg().Path()).addType(v)
-	}
-}
-
-// -- utilities --------------------------------------------------------
-
-func isInterface(T types.Type) bool { return types.IsInterface(T) }
-
-// deref returns a pointer's element type; otherwise it returns typ.
-func deref(typ types.Type) types.Type {
-	if p, ok := typ.Underlying().(*types.Pointer); ok {
-		return p.Elem()
-	}
-	return typ
-}
-
-// isPackageLevel reports whether obj is a package-level object.
-func isPackageLevel(obj types.Object) bool {
-	return obj.Pkg().Scope().Lookup(obj.Name()) == obj
-}
diff --git a/cmd/golangorg/godoc/corpus.go b/cmd/golangorg/godoc/corpus.go
deleted file mode 100644
index 38e39db..0000000
--- a/cmd/golangorg/godoc/corpus.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"errors"
-	pathpkg "path"
-	"sync"
-	"time"
-
-	"golang.org/x/website/cmd/golangorg/godoc/analysis"
-	"golang.org/x/website/cmd/golangorg/godoc/util"
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// A Corpus holds all the state related to serving and indexing a
-// collection of Go code.
-//
-// Construct a new Corpus with NewCorpus, then modify options,
-// then call its Init method.
-type Corpus struct {
-	fs vfs.FileSystem
-
-	// Verbose logging.
-	Verbose bool
-
-	// IndexEnabled controls whether indexing is enabled.
-	IndexEnabled bool
-
-	// IndexFiles specifies a glob pattern specifying index files.
-	// If not empty, the index is read from these files in sorted
-	// order.
-	IndexFiles string
-
-	// IndexThrottle specifies the indexing throttle value
-	// between 0.0 and 1.0. At 0.0, the indexer always sleeps.
-	// At 1.0, the indexer never sleeps. Because 0.0 is useless
-	// and redundant with setting IndexEnabled to false, the
-	// zero value for IndexThrottle means 0.9.
-	IndexThrottle float64
-
-	// IndexInterval specifies the time to sleep between reindexing
-	// all the sources.
-	// If zero, a default is used. If negative, the index is only
-	// built once.
-	IndexInterval time.Duration
-
-	// IndexDocs enables indexing of Go documentation.
-	// This will produce search results for exported types, functions,
-	// methods, variables, and constants, and will link to the godoc
-	// documentation for those identifiers.
-	IndexDocs bool
-
-	// IndexGoCode enables indexing of Go source code.
-	// This will produce search results for internal and external identifiers
-	// and will link to both declarations and uses of those identifiers in
-	// source code.
-	IndexGoCode bool
-
-	// IndexFullText enables full-text indexing.
-	// This will provide search results for any matching text in any file that
-	// is indexed, including non-Go files (see whitelisted in index.go).
-	// Regexp searching is supported via full-text indexing.
-	IndexFullText bool
-
-	// MaxResults optionally specifies the maximum results for indexing.
-	MaxResults int
-
-	// SummarizePackage optionally specifies a function to
-	// summarize a package. It exists as an optimization to
-	// avoid reading files to parse package comments.
-	//
-	// If SummarizePackage returns false for ok, the caller
-	// ignores all return values and parses the files in the package
-	// as if SummarizePackage were nil.
-	//
-	// If showList is false, the package is hidden from the
-	// package listing.
-	SummarizePackage func(pkg string) (summary string, showList, ok bool)
-
-	// IndexDirectory optionally specifies a function to determine
-	// whether the provided directory should be indexed.  The dir
-	// will be of the form "/src/cmd/6a", "/doc/play",
-	// "/src/io", etc.
-	// If nil, all directories are indexed if indexing is enabled.
-	IndexDirectory func(dir string) bool
-
-	testDir string // TODO(bradfitz,adg): migrate old godoc flag? looks unused.
-
-	// Send a value on this channel to trigger a metadata refresh.
-	// It is buffered so that if a signal is not lost if sent
-	// during a refresh.
-	refreshMetadataSignal chan bool
-
-	// file system information
-	fsTree      util.RWValue // *Directory tree of packages, updated with each sync (but sync code is removed now)
-	fsModified  util.RWValue // timestamp of last call to invalidateIndex
-	docMetadata util.RWValue // mapping from paths to *Metadata
-
-	// SearchIndex is the search index in use.
-	searchIndex util.RWValue
-
-	// Analysis is the result of type and pointer analysis.
-	Analysis analysis.Result
-
-	// flag to check whether a corpus is initialized or not
-	initMu   sync.RWMutex
-	initDone bool
-
-	// pkgAPIInfo contains the information about which package API
-	// features were added in which version of Go.
-	pkgAPIInfo apiVersions
-}
-
-// NewCorpus returns a new Corpus from a filesystem.
-// The returned corpus has all indexing enabled and MaxResults set to 1000.
-// Change or set any options on Corpus before calling the Corpus.Init method.
-func NewCorpus(fs vfs.FileSystem) *Corpus {
-	c := &Corpus{
-		fs:                    fs,
-		refreshMetadataSignal: make(chan bool, 1),
-
-		MaxResults:    1000,
-		IndexEnabled:  true,
-		IndexDocs:     true,
-		IndexGoCode:   true,
-		IndexFullText: true,
-	}
-	return c
-}
-
-func (c *Corpus) CurrentIndex() (*Index, time.Time) {
-	v, t := c.searchIndex.Get()
-	idx, _ := v.(*Index)
-	return idx, t
-}
-
-func (c *Corpus) FSModifiedTime() time.Time {
-	_, ts := c.fsModified.Get()
-	return ts
-}
-
-// Init initializes Corpus, once options on Corpus are set.
-// It must be called before any subsequent method calls.
-func (c *Corpus) Init() error {
-	if err := c.initFSTree(); err != nil {
-		return err
-	}
-	c.updateMetadata()
-	go c.refreshMetadataLoop()
-
-	c.initMu.Lock()
-	c.initDone = true
-	c.initMu.Unlock()
-	return nil
-}
-
-func (c *Corpus) initFSTree() error {
-	dir := c.newDirectory(pathpkg.Join("/", c.testDir), -1)
-	if dir == nil {
-		return errors.New("godoc: corpus fstree is nil")
-	}
-	c.fsTree.Set(dir)
-	c.invalidateIndex()
-	return nil
-}
diff --git a/cmd/golangorg/godoc/dirtrees.go b/cmd/golangorg/godoc/dirtrees.go
deleted file mode 100644
index 0542c98..0000000
--- a/cmd/golangorg/godoc/dirtrees.go
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains the code dealing with package directory trees.
-
-package godoc
-
-import (
-	"go/doc"
-	"go/parser"
-	"go/token"
-	"log"
-	"os"
-	pathpkg "path"
-	"runtime"
-	"sort"
-	"strings"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// Conventional name for directories containing test data.
-// Excluded from directory trees.
-//
-const testdataDirName = "testdata"
-
-type Directory struct {
-	Depth    int
-	Path     string       // directory path; includes Name
-	Name     string       // directory name
-	HasPkg   bool         // true if the directory contains at least one package
-	Synopsis string       // package documentation, if any
-	RootType vfs.RootType // root type of the filesystem containing the directory
-	Dirs     []*Directory // subdirectories
-}
-
-func isGoFile(fi os.FileInfo) bool {
-	name := fi.Name()
-	return !fi.IsDir() &&
-		len(name) > 0 && name[0] != '.' && // ignore .files
-		pathpkg.Ext(name) == ".go"
-}
-
-func isPkgFile(fi os.FileInfo) bool {
-	return isGoFile(fi) &&
-		!strings.HasSuffix(fi.Name(), "_test.go") // ignore test files
-}
-
-func isPkgDir(fi os.FileInfo) bool {
-	name := fi.Name()
-	return fi.IsDir() && len(name) > 0 &&
-		name[0] != '_' && name[0] != '.' // ignore _files and .files
-}
-
-type treeBuilder struct {
-	c        *Corpus
-	maxDepth int
-}
-
-// ioGate is a semaphore controlling VFS activity (ReadDir, parseFile, etc).
-// Send before an operation and receive after.
-var ioGate = make(chan struct{}, 20)
-
-// workGate controls the number of concurrent workers. Too many concurrent
-// workers and performance degrades and the race detector gets overwhelmed. If
-// we cannot check out a concurrent worker, work is performed by the main thread
-// instead of spinning up another goroutine.
-var workGate = make(chan struct{}, runtime.NumCPU()*4)
-
-func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth int) *Directory {
-	if name == testdataDirName {
-		return nil
-	}
-
-	if depth >= b.maxDepth {
-		// return a dummy directory so that the parent directory
-		// doesn't get discarded just because we reached the max
-		// directory depth
-		return &Directory{
-			Depth: depth,
-			Path:  path,
-			Name:  name,
-		}
-	}
-
-	var synopses [3]string // prioritized package documentation (0 == highest priority)
-
-	show := true // show in package listing
-	hasPkgFiles := false
-	haveSummary := false
-
-	if hook := b.c.SummarizePackage; hook != nil {
-		if summary, show0, ok := hook(strings.TrimPrefix(path, "/src/")); ok {
-			hasPkgFiles = true
-			show = show0
-			synopses[0] = summary
-			haveSummary = true
-		}
-	}
-
-	ioGate <- struct{}{}
-	list, err := b.c.fs.ReadDir(path)
-	<-ioGate
-	if err != nil {
-		// TODO: propagate more. See golang.org/issue/14252.
-		// For now:
-		if b.c.Verbose {
-			log.Printf("newDirTree reading %s: %v", path, err)
-		}
-	}
-
-	// determine number of subdirectories and if there are package files
-	var dirchs []chan *Directory
-	var dirs []*Directory
-
-	for _, d := range list {
-		filename := pathpkg.Join(path, d.Name())
-		switch {
-		case isPkgDir(d):
-			name := d.Name()
-			select {
-			case workGate <- struct{}{}:
-				ch := make(chan *Directory, 1)
-				dirchs = append(dirchs, ch)
-				go func() {
-					ch <- b.newDirTree(fset, filename, name, depth+1)
-					<-workGate
-				}()
-			default:
-				// no free workers, do work synchronously
-				dir := b.newDirTree(fset, filename, name, depth+1)
-				if dir != nil {
-					dirs = append(dirs, dir)
-				}
-			}
-		case !haveSummary && isPkgFile(d):
-			// looks like a package file, but may just be a file ending in ".go";
-			// don't just count it yet (otherwise we may end up with hasPkgFiles even
-			// though the directory doesn't contain any real package files - was bug)
-			// no "optimal" package synopsis yet; continue to collect synopses
-			ioGate <- struct{}{}
-			const flags = parser.ParseComments | parser.PackageClauseOnly
-			file, err := b.c.parseFile(fset, filename, flags)
-			<-ioGate
-			if err != nil {
-				if b.c.Verbose {
-					log.Printf("Error parsing %v: %v", filename, err)
-				}
-				break
-			}
-
-			hasPkgFiles = true
-			if file.Doc != nil {
-				// prioritize documentation
-				i := -1
-				switch file.Name.Name {
-				case name:
-					i = 0 // normal case: directory name matches package name
-				case "main":
-					i = 1 // directory contains a main package
-				default:
-					i = 2 // none of the above
-				}
-				if 0 <= i && i < len(synopses) && synopses[i] == "" {
-					synopses[i] = doc.Synopsis(file.Doc.Text())
-				}
-			}
-			haveSummary = synopses[0] != ""
-		}
-	}
-
-	// create subdirectory tree
-	for _, ch := range dirchs {
-		if d := <-ch; d != nil {
-			dirs = append(dirs, d)
-		}
-	}
-
-	// We need to sort the dirs slice because
-	// it is appended again after reading from dirchs.
-	sort.Slice(dirs, func(i, j int) bool {
-		return dirs[i].Name < dirs[j].Name
-	})
-
-	// if there are no package files and no subdirectories
-	// containing package files, ignore the directory
-	if !hasPkgFiles && len(dirs) == 0 {
-		return nil
-	}
-
-	// select the highest-priority synopsis for the directory entry, if any
-	synopsis := ""
-	for _, synopsis = range synopses {
-		if synopsis != "" {
-			break
-		}
-	}
-
-	return &Directory{
-		Depth:    depth,
-		Path:     path,
-		Name:     name,
-		HasPkg:   hasPkgFiles && show, // TODO(bradfitz): add proper Hide field?
-		Synopsis: synopsis,
-		RootType: b.c.fs.RootType(path),
-		Dirs:     dirs,
-	}
-}
-
-// newDirectory creates a new package directory tree with at most maxDepth
-// levels, anchored at root. The result tree is pruned such that it only
-// contains directories that contain package files or that contain
-// subdirectories containing package files (transitively). If a non-nil
-// pathFilter is provided, directory paths additionally must be accepted
-// by the filter (i.e., pathFilter(path) must be true). If a value >= 0 is
-// provided for maxDepth, nodes at larger depths are pruned as well; they
-// are assumed to contain package files even if their contents are not known
-// (i.e., in this case the tree may contain directories w/o any package files).
-//
-func (c *Corpus) newDirectory(root string, maxDepth int) *Directory {
-	// The root could be a symbolic link so use Stat not Lstat.
-	d, err := c.fs.Stat(root)
-	// If we fail here, report detailed error messages; otherwise
-	// is is hard to see why a directory tree was not built.
-	switch {
-	case err != nil:
-		log.Printf("newDirectory(%s): %s", root, err)
-		return nil
-	case root != "/" && !isPkgDir(d):
-		log.Printf("newDirectory(%s): not a package directory", root)
-		return nil
-	case root == "/" && !d.IsDir():
-		log.Printf("newDirectory(%s): not a directory", root)
-		return nil
-	}
-	if maxDepth < 0 {
-		maxDepth = 1e6 // "infinity"
-	}
-	b := treeBuilder{c, maxDepth}
-	// the file set provided is only for local parsing, no position
-	// information escapes and thus we don't need to save the set
-	return b.newDirTree(token.NewFileSet(), root, d.Name(), 0)
-}
-
-func (dir *Directory) walk(c chan<- *Directory, skipRoot bool) {
-	if dir != nil {
-		if !skipRoot {
-			c <- dir
-		}
-		for _, d := range dir.Dirs {
-			d.walk(c, false)
-		}
-	}
-}
-
-func (dir *Directory) iter(skipRoot bool) <-chan *Directory {
-	c := make(chan *Directory)
-	go func() {
-		dir.walk(c, skipRoot)
-		close(c)
-	}()
-	return c
-}
-
-func (dir *Directory) lookupLocal(name string) *Directory {
-	for _, d := range dir.Dirs {
-		if d.Name == name {
-			return d
-		}
-	}
-	return nil
-}
-
-func splitPath(p string) []string {
-	p = strings.TrimPrefix(p, "/")
-	if p == "" {
-		return nil
-	}
-	return strings.Split(p, "/")
-}
-
-// lookup looks for the *Directory for a given path, relative to dir.
-func (dir *Directory) lookup(path string) *Directory {
-	d := splitPath(dir.Path)
-	p := splitPath(path)
-	i := 0
-	for i < len(d) {
-		if i >= len(p) || d[i] != p[i] {
-			return nil
-		}
-		i++
-	}
-	for dir != nil && i < len(p) {
-		dir = dir.lookupLocal(p[i])
-		i++
-	}
-	return dir
-}
-
-// DirEntry describes a directory entry. The Depth and Height values
-// are useful for presenting an entry in an indented fashion.
-//
-type DirEntry struct {
-	Depth    int          // >= 0
-	Height   int          // = DirList.MaxHeight - Depth, > 0
-	Path     string       // directory path; includes Name, relative to DirList root
-	Name     string       // directory name
-	HasPkg   bool         // true if the directory contains at least one package
-	Synopsis string       // package documentation, if any
-	RootType vfs.RootType // root type of the filesystem containing the direntry
-}
-
-type DirList struct {
-	MaxHeight int // directory tree height, > 0
-	List      []DirEntry
-}
-
-// hasThirdParty checks whether a list of directory entries has packages outside
-// the standard library or not.
-func hasThirdParty(list []DirEntry) bool {
-	for _, entry := range list {
-		if entry.RootType == vfs.RootTypeGoPath {
-			return true
-		}
-	}
-	return false
-}
-
-// listing creates a (linear) directory listing from a directory tree.
-// If skipRoot is set, the root directory itself is excluded from the list.
-// If filter is set, only the directory entries whose paths match the filter
-// are included.
-//
-func (root *Directory) listing(skipRoot bool, filter func(string) bool) *DirList {
-	if root == nil {
-		return nil
-	}
-
-	// determine number of entries n and maximum height
-	n := 0
-	minDepth := 1 << 30 // infinity
-	maxDepth := 0
-	for d := range root.iter(skipRoot) {
-		n++
-		if minDepth > d.Depth {
-			minDepth = d.Depth
-		}
-		if maxDepth < d.Depth {
-			maxDepth = d.Depth
-		}
-	}
-	maxHeight := maxDepth - minDepth + 1
-
-	if n == 0 {
-		return nil
-	}
-
-	// create list
-	list := make([]DirEntry, 0, n)
-	for d := range root.iter(skipRoot) {
-		if filter != nil && !filter(d.Path) {
-			continue
-		}
-		var p DirEntry
-		p.Depth = d.Depth - minDepth
-		p.Height = maxHeight - p.Depth
-		// the path is relative to root.Path - remove the root.Path
-		// prefix (the prefix should always be present but avoid
-		// crashes and check)
-		path := strings.TrimPrefix(d.Path, root.Path)
-		// remove leading separator if any - path must be relative
-		path = strings.TrimPrefix(path, "/")
-		p.Path = path
-		p.Name = d.Name
-		p.HasPkg = d.HasPkg
-		p.Synopsis = d.Synopsis
-		p.RootType = d.RootType
-		list = append(list, p)
-	}
-
-	return &DirList{maxHeight, list}
-}
diff --git a/cmd/golangorg/godoc/dirtrees_test.go b/cmd/golangorg/godoc/dirtrees_test.go
deleted file mode 100644
index ac5f2a9..0000000
--- a/cmd/golangorg/godoc/dirtrees_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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.
-
-package godoc
-
-import (
-	"go/build"
-	"path/filepath"
-	"runtime"
-	"sort"
-	"testing"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-	"golang.org/x/website/cmd/golangorg/godoc/vfs/gatefs"
-)
-
-func TestNewDirTree(t *testing.T) {
-	fsGate := make(chan bool, 20)
-	rootfs := gatefs.New(vfs.OS(runtime.GOROOT()), fsGate)
-	fs := vfs.NameSpace{}
-	fs.Bind("/", rootfs, "/", vfs.BindReplace)
-
-	c := NewCorpus(fs)
-	// 3 levels deep is enough for testing
-	dir := c.newDirectory("/", 3)
-
-	processDir(t, dir)
-}
-
-func processDir(t *testing.T, dir *Directory) {
-	var list []string
-	for _, d := range dir.Dirs {
-		list = append(list, d.Name)
-		// recursively process the lower level
-		processDir(t, d)
-	}
-
-	if sort.StringsAreSorted(list) == false {
-		t.Errorf("list: %v is not sorted\n", list)
-	}
-}
-
-func BenchmarkNewDirectory(b *testing.B) {
-	if testing.Short() {
-		b.Skip("not running tests requiring large file scan in short mode")
-	}
-
-	fsGate := make(chan bool, 20)
-
-	goroot := runtime.GOROOT()
-	rootfs := gatefs.New(vfs.OS(goroot), fsGate)
-	fs := vfs.NameSpace{}
-	fs.Bind("/", rootfs, "/", vfs.BindReplace)
-	for _, p := range filepath.SplitList(build.Default.GOPATH) {
-		fs.Bind("/src/golang.org", gatefs.New(vfs.OS(p), fsGate), "/src/golang.org", vfs.BindAfter)
-	}
-	b.ResetTimer()
-	b.ReportAllocs()
-	for tries := 0; tries < b.N; tries++ {
-		corpus := NewCorpus(fs)
-		corpus.newDirectory("/", -1)
-	}
-}
diff --git a/cmd/golangorg/godoc/dl/dl.go b/cmd/golangorg/godoc/dl/dl.go
deleted file mode 100644
index 41c0f32..0000000
--- a/cmd/golangorg/godoc/dl/dl.go
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-// Package dl implements a simple downloads frontend server.
-//
-// It accepts HTTP POST requests to create a new download metadata entity, and
-// lists entities with sorting and filtering.
-// It is designed to run only on the instance of godoc that serves golang.org.
-package dl
-
-import (
-	"fmt"
-	"html/template"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-	"time"
-)
-
-const (
-	downloadBaseURL = "https://dl.google.com/go/"
-	cacheKey        = "download_list_3" // increment if listTemplateData changes
-	cacheDuration   = time.Hour
-)
-
-// File represents a file on the golang.org downloads page.
-// It should be kept in sync with the upload code in x/build/cmd/release.
-type File struct {
-	Filename       string    `json:"filename"`
-	OS             string    `json:"os"`
-	Arch           string    `json:"arch"`
-	Version        string    `json:"version"`
-	Checksum       string    `json:"-" datastore:",noindex"` // SHA1; deprecated
-	ChecksumSHA256 string    `json:"sha256" datastore:",noindex"`
-	Size           int64     `json:"size" datastore:",noindex"`
-	Kind           string    `json:"kind"` // "archive", "installer", "source"
-	Uploaded       time.Time `json:"-"`
-}
-
-func (f File) ChecksumType() string {
-	if f.ChecksumSHA256 != "" {
-		return "SHA256"
-	}
-	return "SHA1"
-}
-
-func (f File) PrettyChecksum() string {
-	if f.ChecksumSHA256 != "" {
-		return f.ChecksumSHA256
-	}
-	return f.Checksum
-}
-
-func (f File) PrettyOS() string {
-	if f.OS == "darwin" {
-		switch {
-		case strings.Contains(f.Filename, "osx10.8"):
-			return "OS X 10.8+"
-		case strings.Contains(f.Filename, "osx10.6"):
-			return "OS X 10.6+"
-		}
-	}
-	return pretty(f.OS)
-}
-
-func (f File) PrettySize() string {
-	const mb = 1 << 20
-	if f.Size == 0 {
-		return ""
-	}
-	if f.Size < mb {
-		// All Go releases are >1mb, but handle this case anyway.
-		return fmt.Sprintf("%v bytes", f.Size)
-	}
-	return fmt.Sprintf("%.0fMB", float64(f.Size)/mb)
-}
-
-var primaryPorts = map[string]bool{
-	"darwin/amd64":  true,
-	"linux/386":     true,
-	"linux/amd64":   true,
-	"linux/armv6l":  true,
-	"windows/386":   true,
-	"windows/amd64": true,
-}
-
-func (f File) PrimaryPort() bool {
-	if f.Kind == "source" {
-		return true
-	}
-	return primaryPorts[f.OS+"/"+f.Arch]
-}
-
-func (f File) Highlight() bool {
-	switch {
-	case f.Kind == "source":
-		return true
-	case f.Arch == "amd64" && f.OS == "linux":
-		return true
-	case f.Arch == "amd64" && f.Kind == "installer":
-		switch f.OS {
-		case "windows":
-			return true
-		case "darwin":
-			if !strings.Contains(f.Filename, "osx10.6") {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-func (f File) URL() string {
-	return downloadBaseURL + f.Filename
-}
-
-type Release struct {
-	Version        string `json:"version"`
-	Stable         bool   `json:"stable"`
-	Files          []File `json:"files"`
-	Visible        bool   `json:"-"` // show files on page load
-	SplitPortTable bool   `json:"-"` // whether files should be split by primary/other ports.
-}
-
-type Feature struct {
-	// The File field will be filled in by the first stable File
-	// whose name matches the given fileRE.
-	File
-	fileRE *regexp.Regexp
-
-	Platform     string // "Microsoft Windows", "Apple macOS", "Linux"
-	Requirements string // "Windows XP and above, 64-bit Intel Processor"
-}
-
-// featuredFiles lists the platforms and files to be featured
-// at the top of the downloads page.
-var featuredFiles = []Feature{
-	{
-		Platform:     "Microsoft Windows",
-		Requirements: "Windows 7 or later, Intel 64-bit processor",
-		fileRE:       regexp.MustCompile(`\.windows-amd64\.msi$`),
-	},
-	{
-		Platform:     "Apple macOS",
-		Requirements: "macOS 10.10 or later, Intel 64-bit processor",
-		fileRE:       regexp.MustCompile(`\.darwin-amd64(-osx10\.8)?\.pkg$`),
-	},
-	{
-		Platform:     "Linux",
-		Requirements: "Linux 2.6.23 or later, Intel 64-bit processor",
-		fileRE:       regexp.MustCompile(`\.linux-amd64\.tar\.gz$`),
-	},
-	{
-		Platform: "Source",
-		fileRE:   regexp.MustCompile(`\.src\.tar\.gz$`),
-	},
-}
-
-// data to send to the template; increment cacheKey if you change this.
-type listTemplateData struct {
-	Featured                  []Feature
-	Stable, Unstable, Archive []Release
-}
-
-var (
-	listTemplate  = template.Must(template.New("").Funcs(templateFuncs).Parse(templateHTML))
-	templateFuncs = template.FuncMap{"pretty": pretty}
-)
-
-func filesToFeatured(fs []File) (featured []Feature) {
-	for _, feature := range featuredFiles {
-		for _, file := range fs {
-			if feature.fileRE.MatchString(file.Filename) {
-				feature.File = file
-				featured = append(featured, feature)
-				break
-			}
-		}
-	}
-	return
-}
-
-func filesToReleases(fs []File) (stable, unstable, archive []Release) {
-	sort.Sort(fileOrder(fs))
-
-	var r *Release
-	var stableMaj, stableMin int
-	add := func() {
-		if r == nil {
-			return
-		}
-		if !r.Stable {
-			if len(unstable) != 0 {
-				// Only show one (latest) unstable version.
-				return
-			}
-			maj, min, _ := parseVersion(r.Version)
-			if maj < stableMaj || maj == stableMaj && min <= stableMin {
-				// Display unstable version only if newer than the
-				// latest stable release.
-				return
-			}
-			unstable = append(unstable, *r)
-		}
-
-		// Reports whether the release is the most recent minor version of the
-		// two most recent major versions.
-		shouldAddStable := func() bool {
-			if len(stable) >= 2 {
-				// Show up to two stable versions.
-				return false
-			}
-			if len(stable) == 0 {
-				// Most recent stable version.
-				stableMaj, stableMin, _ = parseVersion(r.Version)
-				return true
-			}
-			if maj, _, _ := parseVersion(r.Version); maj == stableMaj {
-				// Older minor version of most recent major version.
-				return false
-			}
-			// Second most recent stable version.
-			return true
-		}
-		if !shouldAddStable() {
-			archive = append(archive, *r)
-			return
-		}
-
-		// Split the file list into primary/other ports for the stable releases.
-		// NOTE(cbro): This is only done for stable releases because maintaining the historical
-		// nature of primary/other ports for older versions is infeasible.
-		// If freebsd is considered primary some time in the future, we'd not want to
-		// mark all of the older freebsd binaries as "primary".
-		// It might be better if we set that as a flag when uploading.
-		r.SplitPortTable = true
-		r.Visible = true // Toggle open all stable releases.
-		stable = append(stable, *r)
-	}
-	for _, f := range fs {
-		if r == nil || f.Version != r.Version {
-			add()
-			r = &Release{
-				Version: f.Version,
-				Stable:  isStable(f.Version),
-			}
-		}
-		r.Files = append(r.Files, f)
-	}
-	add()
-	return
-}
-
-// isStable reports whether the version string v is a stable version.
-func isStable(v string) bool {
-	return !strings.Contains(v, "beta") && !strings.Contains(v, "rc")
-}
-
-type fileOrder []File
-
-func (s fileOrder) Len() int      { return len(s) }
-func (s fileOrder) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-func (s fileOrder) Less(i, j int) bool {
-	a, b := s[i], s[j]
-	if av, bv := a.Version, b.Version; av != bv {
-		return versionLess(av, bv)
-	}
-	if a.OS != b.OS {
-		return a.OS < b.OS
-	}
-	if a.Arch != b.Arch {
-		return a.Arch < b.Arch
-	}
-	if a.Kind != b.Kind {
-		return a.Kind < b.Kind
-	}
-	return a.Filename < b.Filename
-}
-
-func versionLess(a, b string) bool {
-	// Put stable releases first.
-	if isStable(a) != isStable(b) {
-		return isStable(a)
-	}
-	maja, mina, ta := parseVersion(a)
-	majb, minb, tb := parseVersion(b)
-	if maja == majb {
-		if mina == minb {
-			return ta >= tb
-		}
-		return mina >= minb
-	}
-	return maja >= majb
-}
-
-func parseVersion(v string) (maj, min int, tail string) {
-	if i := strings.Index(v, "beta"); i > 0 {
-		tail = v[i:]
-		v = v[:i]
-	}
-	if i := strings.Index(v, "rc"); i > 0 {
-		tail = v[i:]
-		v = v[:i]
-	}
-	p := strings.Split(strings.TrimPrefix(v, "go1."), ".")
-	maj, _ = strconv.Atoi(p[0])
-	if len(p) < 2 {
-		return
-	}
-	min, _ = strconv.Atoi(p[1])
-	return
-}
-
-func validUser(user string) bool {
-	switch user {
-	case "adg", "bradfitz", "cbro", "andybons", "valsorda", "dmitshur", "katiehockman":
-		return true
-	}
-	return false
-}
-
-var (
-	fileRe  = regexp.MustCompile(`^go[0-9a-z.]+\.[0-9a-z.-]+\.(tar\.gz|pkg|msi|zip)$`)
-	goGetRe = regexp.MustCompile(`^go[0-9a-z.]+\.[0-9a-z.-]+$`)
-)
-
-// pretty returns a human-readable version of the given OS, Arch, or Kind.
-func pretty(s string) string {
-	t, ok := prettyStrings[s]
-	if !ok {
-		return s
-	}
-	return t
-}
-
-var prettyStrings = map[string]string{
-	"darwin":  "macOS",
-	"freebsd": "FreeBSD",
-	"linux":   "Linux",
-	"windows": "Windows",
-
-	"386":    "x86",
-	"amd64":  "x86-64",
-	"armv6l": "ARMv6",
-	"arm64":  "ARMv8",
-
-	"archive":   "Archive",
-	"installer": "Installer",
-	"source":    "Source",
-}
diff --git a/cmd/golangorg/godoc/dl/dl_test.go b/cmd/golangorg/godoc/dl/dl_test.go
deleted file mode 100644
index 2cdc1aa..0000000
--- a/cmd/golangorg/godoc/dl/dl_test.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-package dl
-
-import (
-	"sort"
-	"strings"
-	"testing"
-)
-
-func TestParseVersion(t *testing.T) {
-	for _, c := range []struct {
-		in       string
-		maj, min int
-		tail     string
-	}{
-		{"go1.5", 5, 0, ""},
-		{"go1.5beta1", 5, 0, "beta1"},
-		{"go1.5.1", 5, 1, ""},
-		{"go1.5.1rc1", 5, 1, "rc1"},
-	} {
-		maj, min, tail := parseVersion(c.in)
-		if maj != c.maj || min != c.min || tail != c.tail {
-			t.Errorf("parseVersion(%q) = %v, %v, %q; want %v, %v, %q",
-				c.in, maj, min, tail, c.maj, c.min, c.tail)
-		}
-	}
-}
-
-func TestFileOrder(t *testing.T) {
-	fs := []File{
-		{Filename: "go1.3.src.tar.gz", Version: "go1.3", OS: "", Arch: "", Kind: "source"},
-		{Filename: "go1.3.1.src.tar.gz", Version: "go1.3.1", OS: "", Arch: "", Kind: "source"},
-		{Filename: "go1.3.linux-amd64.tar.gz", Version: "go1.3", OS: "linux", Arch: "amd64", Kind: "archive"},
-		{Filename: "go1.3.1.linux-amd64.tar.gz", Version: "go1.3.1", OS: "linux", Arch: "amd64", Kind: "archive"},
-		{Filename: "go1.3.darwin-amd64.tar.gz", Version: "go1.3", OS: "darwin", Arch: "amd64", Kind: "archive"},
-		{Filename: "go1.3.darwin-amd64.pkg", Version: "go1.3", OS: "darwin", Arch: "amd64", Kind: "installer"},
-		{Filename: "go1.3.darwin-386.tar.gz", Version: "go1.3", OS: "darwin", Arch: "386", Kind: "archive"},
-		{Filename: "go1.3beta1.linux-amd64.tar.gz", Version: "go1.3beta1", OS: "linux", Arch: "amd64", Kind: "archive"},
-		{Filename: "go1.3beta2.linux-amd64.tar.gz", Version: "go1.3beta2", OS: "linux", Arch: "amd64", Kind: "archive"},
-		{Filename: "go1.3rc1.linux-amd64.tar.gz", Version: "go1.3rc1", OS: "linux", Arch: "amd64", Kind: "archive"},
-		{Filename: "go1.2.linux-amd64.tar.gz", Version: "go1.2", OS: "linux", Arch: "amd64", Kind: "archive"},
-		{Filename: "go1.2.2.linux-amd64.tar.gz", Version: "go1.2.2", OS: "linux", Arch: "amd64", Kind: "archive"},
-	}
-	sort.Sort(fileOrder(fs))
-	var s []string
-	for _, f := range fs {
-		s = append(s, f.Filename)
-	}
-	got := strings.Join(s, "\n")
-	want := strings.Join([]string{
-		"go1.3.1.src.tar.gz",
-		"go1.3.1.linux-amd64.tar.gz",
-		"go1.3.src.tar.gz",
-		"go1.3.darwin-386.tar.gz",
-		"go1.3.darwin-amd64.tar.gz",
-		"go1.3.darwin-amd64.pkg",
-		"go1.3.linux-amd64.tar.gz",
-		"go1.2.2.linux-amd64.tar.gz",
-		"go1.2.linux-amd64.tar.gz",
-		"go1.3rc1.linux-amd64.tar.gz",
-		"go1.3beta2.linux-amd64.tar.gz",
-		"go1.3beta1.linux-amd64.tar.gz",
-	}, "\n")
-	if got != want {
-		t.Errorf("sort order is\n%s\nwant:\n%s", got, want)
-	}
-}
-
-func TestFilesToReleases(t *testing.T) {
-	fs := []File{
-		{Version: "go1.7.4", OS: "darwin"},
-		{Version: "go1.7.4", OS: "windows"},
-		{Version: "go1.7", OS: "darwin"},
-		{Version: "go1.7", OS: "windows"},
-		{Version: "go1.6.2", OS: "darwin"},
-		{Version: "go1.6.2", OS: "windows"},
-		{Version: "go1.6", OS: "darwin"},
-		{Version: "go1.6", OS: "windows"},
-		{Version: "go1.5.2", OS: "darwin"},
-		{Version: "go1.5.2", OS: "windows"},
-		{Version: "go1.5", OS: "darwin"},
-		{Version: "go1.5", OS: "windows"},
-		{Version: "go1.5beta1", OS: "windows"},
-	}
-	stable, unstable, archive := filesToReleases(fs)
-	if got, want := len(stable), 2; want != got {
-		t.Errorf("len(stable): got %v, want %v", got, want)
-	} else {
-		if got, want := stable[0].Version, "go1.7.4"; want != got {
-			t.Errorf("stable[0].Version: got %v, want %v", got, want)
-		}
-		if got, want := stable[1].Version, "go1.6.2"; want != got {
-			t.Errorf("stable[1].Version: got %v, want %v", got, want)
-		}
-	}
-	if got, want := len(unstable), 0; want != got {
-		t.Errorf("len(unstable): got %v, want %v", got, want)
-	}
-	if got, want := len(archive), 4; want != got {
-		t.Errorf("len(archive): got %v, want %v", got, want)
-	}
-}
-
-func TestOldUnstableNotShown(t *testing.T) {
-	fs := []File{
-		{Version: "go1.7.4"},
-		{Version: "go1.7"},
-		{Version: "go1.7beta1"},
-	}
-	_, unstable, _ := filesToReleases(fs)
-	if len(unstable) != 0 {
-		t.Errorf("got unstable, want none")
-	}
-}
-
-func TestUnstableShown(t *testing.T) {
-	fs := []File{
-		{Version: "go1.8beta2"},
-		{Version: "go1.8rc1"},
-		{Version: "go1.7.4"},
-		{Version: "go1.7"},
-		{Version: "go1.7beta1"},
-	}
-	_, unstable, _ := filesToReleases(fs)
-	if got, want := len(unstable), 1; got != want {
-		t.Fatalf("len(unstable): got %v, want %v", got, want)
-	}
-	// show rcs ahead of betas.
-	if got, want := unstable[0].Version, "go1.8rc1"; got != want {
-		t.Fatalf("unstable[0].Version: got %v, want %v", got, want)
-	}
-}
diff --git a/cmd/golangorg/godoc/dl/server.go b/cmd/golangorg/godoc/dl/server.go
deleted file mode 100644
index 3dd38e9..0000000
--- a/cmd/golangorg/godoc/dl/server.go
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-// +build golangorg
-
-package dl
-
-import (
-	"context"
-	"crypto/hmac"
-	"crypto/md5"
-	"encoding/json"
-	"fmt"
-	"html"
-	"io"
-	"log"
-	"net/http"
-	"strings"
-	"sync"
-	"time"
-
-	"cloud.google.com/go/datastore"
-	"golang.org/x/website/cmd/golangorg/godoc/env"
-	"golang.org/x/website/internal/memcache"
-)
-
-type server struct {
-	datastore *datastore.Client
-	memcache  *memcache.CodecClient
-}
-
-func RegisterHandlers(mux *http.ServeMux, dc *datastore.Client, mc *memcache.Client) {
-	s := server{dc, mc.WithCodec(memcache.Gob)}
-	mux.HandleFunc("/dl", s.getHandler)
-	mux.HandleFunc("/dl/", s.getHandler) // also serves listHandler
-	mux.HandleFunc("/dl/upload", s.uploadHandler)
-
-	// NOTE(cbro): this only needs to be run once per project,
-	// and should be behind an admin login.
-	// TODO(cbro): move into a locally-run program? or remove?
-	// mux.HandleFunc("/dl/init", initHandler)
-}
-
-// rootKey is the ancestor of all File entities.
-var rootKey = datastore.NameKey("FileRoot", "root", nil)
-
-func (h server) listHandler(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "GET" {
-		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
-		return
-	}
-	ctx := r.Context()
-	var d listTemplateData
-
-	if err := h.memcache.Get(ctx, cacheKey, &d); err != nil {
-		if err != memcache.ErrCacheMiss {
-			log.Printf("ERROR cache get error: %v", err)
-			// NOTE(cbro): continue to hit datastore if the memcache is down.
-		}
-
-		var fs []File
-		q := datastore.NewQuery("File").Ancestor(rootKey)
-		if _, err := h.datastore.GetAll(ctx, q, &fs); err != nil {
-			log.Printf("ERROR error listing: %v", err)
-			http.Error(w, "Could not get download page. Try again in a few minutes.", 500)
-			return
-		}
-		d.Stable, d.Unstable, d.Archive = filesToReleases(fs)
-		if len(d.Stable) > 0 {
-			d.Featured = filesToFeatured(d.Stable[0].Files)
-		}
-
-		item := &memcache.Item{Key: cacheKey, Object: &d, Expiration: cacheDuration}
-		if err := h.memcache.Set(ctx, item); err != nil {
-			log.Printf("ERROR cache set error: %v", err)
-		}
-	}
-
-	if r.URL.Query().Get("mode") == "json" {
-		w.Header().Set("Content-Type", "application/json")
-		enc := json.NewEncoder(w)
-		enc.SetIndent("", " ")
-		if err := enc.Encode(d.Stable); err != nil {
-			log.Printf("ERROR rendering JSON for releases: %v", err)
-		}
-		return
-	}
-
-	if err := listTemplate.ExecuteTemplate(w, "root", d); err != nil {
-		log.Printf("ERROR executing template: %v", err)
-	}
-}
-
-func (h server) uploadHandler(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "POST" {
-		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
-		return
-	}
-	ctx := r.Context()
-
-	// Authenticate using a user token (same as gomote).
-	user := r.FormValue("user")
-	if !validUser(user) {
-		http.Error(w, "bad user", http.StatusForbidden)
-		return
-	}
-	if r.FormValue("key") != h.userKey(ctx, user) {
-		http.Error(w, "bad key", http.StatusForbidden)
-		return
-	}
-
-	var f File
-	defer r.Body.Close()
-	if err := json.NewDecoder(r.Body).Decode(&f); err != nil {
-		log.Printf("ERROR decoding upload JSON: %v", err)
-		http.Error(w, "Something broke", http.StatusInternalServerError)
-		return
-	}
-	if f.Filename == "" {
-		http.Error(w, "Must provide Filename", http.StatusBadRequest)
-		return
-	}
-	if f.Uploaded.IsZero() {
-		f.Uploaded = time.Now()
-	}
-	k := datastore.NameKey("File", f.Filename, rootKey)
-	if _, err := h.datastore.Put(ctx, k, &f); err != nil {
-		log.Printf("ERROR File entity: %v", err)
-		http.Error(w, "could not put File entity", http.StatusInternalServerError)
-		return
-	}
-	if err := h.memcache.Delete(ctx, cacheKey); err != nil {
-		log.Printf("ERROR delete error: %v", err)
-	}
-	io.WriteString(w, "OK")
-}
-
-func (h server) getHandler(w http.ResponseWriter, r *http.Request) {
-	isGoGet := (r.Method == "GET" || r.Method == "HEAD") && r.FormValue("go-get") == "1"
-	// For go get, we need to serve the same meta tags at /dl for cmd/go to
-	// validate against the import path.
-	if r.URL.Path == "/dl" && isGoGet {
-		w.Header().Set("Content-Type", "text/html; charset=utf-8")
-		fmt.Fprintf(w, `<!DOCTYPE html><html><head>
-<meta name="go-import" content="golang.org/dl git https://go.googlesource.com/dl">
-</head></html>`)
-		return
-	}
-	if r.URL.Path == "/dl" {
-		http.Redirect(w, r, "/dl/", http.StatusFound)
-		return
-	}
-
-	name := strings.TrimPrefix(r.URL.Path, "/dl/")
-	var redirectURL string
-	switch {
-	case name == "":
-		h.listHandler(w, r)
-		return
-	case fileRe.MatchString(name):
-		http.Redirect(w, r, downloadBaseURL+name, http.StatusFound)
-		return
-	case name == "gotip":
-		redirectURL = "https://godoc.org/golang.org/dl/gotip"
-	case goGetRe.MatchString(name):
-		redirectURL = "https://golang.org/dl/#" + name
-	default:
-		http.NotFound(w, r)
-		return
-	}
-	w.Header().Set("Content-Type", "text/html; charset=utf-8")
-	if !isGoGet {
-		w.Header().Set("Location", redirectURL)
-	}
-	fmt.Fprintf(w, `<!DOCTYPE html>
-<html>
-<head>
-<meta name="go-import" content="golang.org/dl git https://go.googlesource.com/dl">
-<meta http-equiv="refresh" content="0; url=%s">
-</head>
-<body>
-Nothing to see here; <a href="%s">move along</a>.
-</body>
-</html>
-`, html.EscapeString(redirectURL), html.EscapeString(redirectURL))
-}
-
-func (h server) initHandler(w http.ResponseWriter, r *http.Request) {
-	var fileRoot struct {
-		Root string
-	}
-	ctx := r.Context()
-	k := rootKey
-	_, err := h.datastore.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
-		err := tx.Get(k, &fileRoot)
-		if err != nil && err != datastore.ErrNoSuchEntity {
-			return err
-		}
-		_, err = tx.Put(k, &fileRoot)
-		return err
-	}, nil)
-	if err != nil {
-		http.Error(w, err.Error(), 500)
-		return
-	}
-	io.WriteString(w, "OK")
-}
-
-func (h server) userKey(c context.Context, user string) string {
-	hash := hmac.New(md5.New, []byte(h.secret(c)))
-	hash.Write([]byte("user-" + user))
-	return fmt.Sprintf("%x", hash.Sum(nil))
-}
-
-// Code below copied from x/build/app/key
-
-var theKey struct {
-	sync.RWMutex
-	builderKey
-}
-
-type builderKey struct {
-	Secret string
-}
-
-func (k *builderKey) Key() *datastore.Key {
-	return datastore.NameKey("BuilderKey", "root", nil)
-}
-
-func (h server) secret(ctx context.Context) string {
-	// check with rlock
-	theKey.RLock()
-	k := theKey.Secret
-	theKey.RUnlock()
-	if k != "" {
-		return k
-	}
-
-	// prepare to fill; check with lock and keep lock
-	theKey.Lock()
-	defer theKey.Unlock()
-	if theKey.Secret != "" {
-		return theKey.Secret
-	}
-
-	// fill
-	if err := h.datastore.Get(ctx, theKey.Key(), &theKey.builderKey); err != nil {
-		if err == datastore.ErrNoSuchEntity {
-			// If the key is not stored in datastore, write it.
-			// This only happens at the beginning of a new deployment.
-			// The code is left here for SDK use and in case a fresh
-			// deployment is ever needed.  "gophers rule" is not the
-			// real key.
-			if env.IsProd() {
-				panic("lost key from datastore")
-			}
-			theKey.Secret = "gophers rule"
-			h.datastore.Put(ctx, theKey.Key(), &theKey.builderKey)
-			return theKey.Secret
-		}
-		panic("cannot load builder key: " + err.Error())
-	}
-
-	return theKey.Secret
-}
diff --git a/cmd/golangorg/godoc/dl/tmpl.go b/cmd/golangorg/godoc/dl/tmpl.go
deleted file mode 100644
index d086b69..0000000
--- a/cmd/golangorg/godoc/dl/tmpl.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-package dl
-
-// TODO(adg): refactor this to use the tools/godoc/static template.
-
-const templateHTML = `
-{{define "root"}}
-<!DOCTYPE html>
-<html>
-<head>
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-        <title>Downloads - The Go Programming Language</title>
-        <link type="text/css" rel="stylesheet" href="/lib/godoc/style.css">
-        <script type="text/javascript">window.initFuncs = [];</script>
-	<style>
-		table.codetable {
-			margin-left: 20px; margin-right: 20px;
-			border-collapse: collapse;
-		}
-		table.codetable tr {
-			background-color: #f0f0f0;
-		}
-		table.codetable tr:nth-child(2n), table.codetable tr.first {
-			background-color: white;
-		}
-		table.codetable td, table.codetable th {
-			white-space: nowrap;
-			padding: 6px 10px;
-		}
-		table.codetable tt {
-			font-size: xx-small;
-		}
-		table.codetable tr.highlight td {
-			font-weight: bold;
-		}
-		a.downloadBox {
-			display: block;
-			color: #222;
-			border: 1px solid #375EAB;
-			border-radius: 5px;
-			background: #E0EBF5;
-			width: 280px;
-			float: left;
-			margin-left: 10px;
-			margin-bottom: 10px;
-			padding: 10px;
-		}
-		a.downloadBox:hover {
-			text-decoration: none;
-		}
-		.downloadBox .platform {
-			font-size: large;
-		}
-		.downloadBox .filename {
-			color: #375EAB;
-			font-weight: bold;
-			line-height: 1.5em;
-		}
-		a.downloadBox:hover .filename {
-			text-decoration: underline;
-		}
-		.downloadBox .size {
-			font-size: small;
-			font-weight: normal;
-		}
-		.downloadBox .reqs {
-			font-size: small;
-			font-style: italic;
-		}
-		.downloadBox .checksum {
-			font-size: 5pt;
-		}
-	</style>
-</head>
-<body>
-
-<div id="topbar"><div class="container">
-
-<div class="top-heading"><a href="/">The Go Programming Language</a></div>
-<form method="GET" action="/search">
-<div id="menu">
-<a href="/doc/">Documents</a>
-<a href="/pkg/">Packages</a>
-<a href="/project/">The Project</a>
-<a href="/help/">Help</a>
-<a href="/blog/">Blog</a>
-<span class="search-box"><input type="search" id="search" name="q" placeholder="Search" aria-label="Search" required><button type="submit"><span><!-- magnifying glass: --><svg width="24" height="24" viewBox="0 0 24 24"><title>submit search</title><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/><path d="M0 0h24v24H0z" fill="none"/></svg></span></button></span>
-</div>
-</form>
-
-</div></div>
-
-<div id="page">
-<div class="container">
-
-<h1>Downloads</h1>
-
-<p>
-After downloading a binary release suitable for your system,
-please follow the <a href="/doc/install">installation instructions</a>.
-</p>
-
-<p>
-If you are building from source,
-follow the <a href="/doc/install/source">source installation instructions</a>.
-</p>
-
-<p>
-See the <a href="/doc/devel/release.html">release history</a> for more
-information about Go releases.
-</p>
-
-{{with .Featured}}
-<h3 id="featured">Featured downloads</h3>
-{{range .}}
-{{template "download" .}}
-{{end}}
-{{end}}
-
-<div style="clear: both;"></div>
-
-{{with .Stable}}
-<h3 id="stable">Stable versions</h3>
-{{template "releases" .}}
-{{end}}
-
-{{with .Unstable}}
-<h3 id="unstable">Unstable version</h3>
-{{template "releases" .}}
-{{end}}
-
-{{with .Archive}}
-<div class="toggle" id="archive">
-  <div class="collapsed">
-    <h3 class="toggleButton" title="Click to show versions">Archived versions▹</h3>
-  </div>
-  <div class="expanded">
-    <h3 class="toggleButton" title="Click to hide versions">Archived versions▾</h3>
-    {{template "releases" .}}
-  </div>
-</div>
-{{end}}
-
-<div id="footer">
-        <p>
-        Except as
-        <a href="https://developers.google.com/site-policies#restrictions">noted</a>,
-        the content of this page is licensed under the Creative Commons
-        Attribution 3.0 License,<br>
-        and code is licensed under a <a href="http://golang.org/LICENSE">BSD license</a>.<br>
-        <a href="http://golang.org/doc/tos.html">Terms of Service</a> |
-        <a href="http://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>
-        </p>
-</div><!-- #footer -->
-
-</div><!-- .container -->
-</div><!-- #page -->
-<script>
-  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
-  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
-  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
-
-  ga('create', 'UA-11222381-2', 'auto');
-  ga('send', 'pageview');
-
-</script>
-</body>
-<script src="/lib/godoc/jquery.js"></script>
-<script src="/lib/godoc/godocs.js"></script>
-<script>
-$(document).ready(function() {
-  $('a.download').click(function(e) {
-    // Try using the link text as the file name,
-    // unless there's a child element of class 'filename'.
-    var filename = $(this).text();
-    var child = $(this).find('.filename');
-    if (child.length > 0) {
-      filename = child.text();
-    }
-
-    // This must be kept in sync with the filenameRE in godocs.js.
-    var filenameRE = /^go1\.\d+(\.\d+)?([a-z0-9]+)?\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\.[68])?\.([a-z.]+)$/;
-    var m = filenameRE.exec(filename);
-    if (!m) {
-      // Don't redirect to the download page if it won't recognize this file.
-      // (Should not happen.)
-      return;
-    }
-
-    var dest = "/doc/install";
-    if (filename.indexOf(".src.") != -1) {
-      dest += "/source";
-    }
-    dest += "?download=" + filename;
-
-    e.preventDefault();
-    e.stopPropagation();
-    window.location = dest;
-  });
-});
-</script>
-</html>
-{{end}}
-
-{{define "releases"}}
-{{range .}}
-<div class="toggle{{if .Visible}}Visible{{end}}" id="{{.Version}}">
-	<div class="collapsed">
-		<h2 class="toggleButton" title="Click to show downloads for this version">{{.Version}} ▹</h2>
-	</div>
-	<div class="expanded">
-		<h2 class="toggleButton" title="Click to hide downloads for this version">{{.Version}} ▾</h2>
-		{{if .Stable}}{{else}}
-			<p>This is an <b>unstable</b> version of Go. Use with caution.</p>
-			<p>If you already have Go installed, you can install this version by running:</p>
-<pre>
-go get golang.org/dl/{{.Version}}
-</pre>
-			<p>Then, use the <code>{{.Version}}</code> command instead of the <code>go</code> command to use {{.Version}}.</p>
-		{{end}}
-		{{template "files" .}}
-	</div>
-</div>
-{{end}}
-{{end}}
-
-{{define "files"}}
-<table class="codetable">
-<thead>
-<tr class="first">
-  <th>File name</th>
-  <th>Kind</th>
-  <th>OS</th>
-  <th>Arch</th>
-  <th>Size</th>
-  {{/* Use the checksum type of the first file for the column heading. */}}
-  <th>{{(index .Files 0).ChecksumType}} Checksum</th>
-</tr>
-</thead>
-{{if .SplitPortTable}}
-  {{range .Files}}{{if .PrimaryPort}}{{template "file" .}}{{end}}{{end}}
-
-  {{/* TODO(cbro): add a link to an explanatory doc page */}}
-  <tr class="first"><th colspan="6" class="first">Other Ports</th></tr>
-  {{range .Files}}{{if not .PrimaryPort}}{{template "file" .}}{{end}}{{end}}
-{{else}}
-  {{range .Files}}{{template "file" .}}{{end}}
-{{end}}
-</table>
-{{end}}
-
-{{define "file"}}
-<tr{{if .Highlight}} class="highlight"{{end}}>
-  <td class="filename"><a class="download" href="{{.URL}}">{{.Filename}}</a></td>
-  <td>{{pretty .Kind}}</td>
-  <td>{{.PrettyOS}}</td>
-  <td>{{pretty .Arch}}</td>
-  <td>{{.PrettySize}}</td>
-  <td><tt>{{.PrettyChecksum}}</tt></td>
-</tr>
-{{end}}
-
-{{define "download"}}
-<a class="download downloadBox" href="{{.URL}}">
-<div class="platform">{{.Platform}}</div>
-{{with .Requirements}}<div class="reqs">{{.}}</div>{{end}}
-<div>
-  <span class="filename">{{.Filename}}</span>
-  {{if .Size}}<span class="size">({{.PrettySize}})</span>{{end}}
-</div>
-</a>
-{{end}}
-`
diff --git a/cmd/golangorg/godoc/env/env.go b/cmd/golangorg/godoc/env/env.go
deleted file mode 100644
index e1f55cd..0000000
--- a/cmd/golangorg/godoc/env/env.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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.
-
-// Package env provides environment information for the godoc server running on
-// golang.org.
-package env
-
-import (
-	"log"
-	"os"
-	"strconv"
-)
-
-var (
-	isProd       = boolEnv("GODOC_PROD")
-	enforceHosts = boolEnv("GODOC_ENFORCE_HOSTS")
-)
-
-// IsProd reports whether the server is running in its production configuration
-// on golang.org.
-func IsProd() bool {
-	return isProd
-}
-
-// EnforceHosts reports whether host filtering should be enforced.
-func EnforceHosts() bool {
-	return enforceHosts
-}
-
-func boolEnv(key string) bool {
-	v := os.Getenv(key)
-	if v == "" {
-		return false
-	}
-	b, err := strconv.ParseBool(v)
-	if err != nil {
-		log.Fatalf("environment variable %s (%q) must be a boolean", key, v)
-	}
-	return b
-}
diff --git a/cmd/golangorg/godoc/format.go b/cmd/golangorg/godoc/format.go
deleted file mode 100644
index 6013238..0000000
--- a/cmd/golangorg/godoc/format.go
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements FormatSelections and FormatText.
-// FormatText is used to HTML-format Go and non-Go source
-// text with line numbers and highlighted sections. It is
-// built on top of FormatSelections, a generic formatter
-// for "selected" text.
-
-package godoc
-
-import (
-	"fmt"
-	"go/scanner"
-	"go/token"
-	"io"
-	"regexp"
-	"strconv"
-	"text/template"
-)
-
-// ----------------------------------------------------------------------------
-// Implementation of FormatSelections
-
-// A Segment describes a text segment [start, end).
-// The zero value of a Segment is a ready-to-use empty segment.
-//
-type Segment struct {
-	start, end int
-}
-
-func (seg *Segment) isEmpty() bool { return seg.start >= seg.end }
-
-// A Selection is an "iterator" function returning a text segment.
-// Repeated calls to a selection return consecutive, non-overlapping,
-// non-empty segments, followed by an infinite sequence of empty
-// segments. The first empty segment marks the end of the selection.
-//
-type Selection func() Segment
-
-// A LinkWriter writes some start or end "tag" to w for the text offset offs.
-// It is called by FormatSelections at the start or end of each link segment.
-//
-type LinkWriter func(w io.Writer, offs int, start bool)
-
-// A SegmentWriter formats a text according to selections and writes it to w.
-// The selections parameter is a bit set indicating which selections provided
-// to FormatSelections overlap with the text segment: If the n'th bit is set
-// in selections, the n'th selection provided to FormatSelections is overlapping
-// with the text.
-//
-type SegmentWriter func(w io.Writer, text []byte, selections int)
-
-// FormatSelections takes a text and writes it to w using link and segment
-// writers lw and sw as follows: lw is invoked for consecutive segment starts
-// and ends as specified through the links selection, and sw is invoked for
-// consecutive segments of text overlapped by the same selections as specified
-// by selections. The link writer lw may be nil, in which case the links
-// Selection is ignored.
-//
-func FormatSelections(w io.Writer, text []byte, lw LinkWriter, links Selection, sw SegmentWriter, selections ...Selection) {
-	// If we have a link writer, make the links
-	// selection the last entry in selections
-	if lw != nil {
-		selections = append(selections, links)
-	}
-
-	// compute the sequence of consecutive segment changes
-	changes := newMerger(selections)
-
-	// The i'th bit in bitset indicates that the text
-	// at the current offset is covered by selections[i].
-	bitset := 0
-	lastOffs := 0
-
-	// Text segments are written in a delayed fashion
-	// such that consecutive segments belonging to the
-	// same selection can be combined (peephole optimization).
-	// last describes the last segment which has not yet been written.
-	var last struct {
-		begin, end int // valid if begin < end
-		bitset     int
-	}
-
-	// flush writes the last delayed text segment
-	flush := func() {
-		if last.begin < last.end {
-			sw(w, text[last.begin:last.end], last.bitset)
-		}
-		last.begin = last.end // invalidate last
-	}
-
-	// segment runs the segment [lastOffs, end) with the selection
-	// indicated by bitset through the segment peephole optimizer.
-	segment := func(end int) {
-		if lastOffs < end { // ignore empty segments
-			if last.end != lastOffs || last.bitset != bitset {
-				// the last segment is not adjacent to or
-				// differs from the new one
-				flush()
-				// start a new segment
-				last.begin = lastOffs
-			}
-			last.end = end
-			last.bitset = bitset
-		}
-	}
-
-	for {
-		// get the next segment change
-		index, offs, start := changes.next()
-		if index < 0 || offs > len(text) {
-			// no more segment changes or the next change
-			// is past the end of the text - we're done
-			break
-		}
-		// determine the kind of segment change
-		if lw != nil && index == len(selections)-1 {
-			// we have a link segment change (see start of this function):
-			// format the previous selection segment, write the
-			// link tag and start a new selection segment
-			segment(offs)
-			flush()
-			lastOffs = offs
-			lw(w, offs, start)
-		} else {
-			// we have a selection change:
-			// format the previous selection segment, determine
-			// the new selection bitset and start a new segment
-			segment(offs)
-			lastOffs = offs
-			mask := 1 << uint(index)
-			if start {
-				bitset |= mask
-			} else {
-				bitset &^= mask
-			}
-		}
-	}
-	segment(len(text))
-	flush()
-}
-
-// A merger merges a slice of Selections and produces a sequence of
-// consecutive segment change events through repeated next() calls.
-//
-type merger struct {
-	selections []Selection
-	segments   []Segment // segments[i] is the next segment of selections[i]
-}
-
-const infinity int = 2e9
-
-func newMerger(selections []Selection) *merger {
-	segments := make([]Segment, len(selections))
-	for i, sel := range selections {
-		segments[i] = Segment{infinity, infinity}
-		if sel != nil {
-			if seg := sel(); !seg.isEmpty() {
-				segments[i] = seg
-			}
-		}
-	}
-	return &merger{selections, segments}
-}
-
-// next returns the next segment change: index specifies the Selection
-// to which the segment belongs, offs is the segment start or end offset
-// as determined by the start value. If there are no more segment changes,
-// next returns an index value < 0.
-//
-func (m *merger) next() (index, offs int, start bool) {
-	// find the next smallest offset where a segment starts or ends
-	offs = infinity
-	index = -1
-	for i, seg := range m.segments {
-		switch {
-		case seg.start < offs:
-			offs = seg.start
-			index = i
-			start = true
-		case seg.end < offs:
-			offs = seg.end
-			index = i
-			start = false
-		}
-	}
-	if index < 0 {
-		// no offset found => all selections merged
-		return
-	}
-	// offset found - it's either the start or end offset but
-	// either way it is ok to consume the start offset: set it
-	// to infinity so it won't be considered in the following
-	// next call
-	m.segments[index].start = infinity
-	if start {
-		return
-	}
-	// end offset found - consume it
-	m.segments[index].end = infinity
-	// advance to the next segment for that selection
-	seg := m.selections[index]()
-	if !seg.isEmpty() {
-		m.segments[index] = seg
-	}
-	return
-}
-
-// ----------------------------------------------------------------------------
-// Implementation of FormatText
-
-// lineSelection returns the line segments for text as a Selection.
-func lineSelection(text []byte) Selection {
-	i, j := 0, 0
-	return func() (seg Segment) {
-		// find next newline, if any
-		for j < len(text) {
-			j++
-			if text[j-1] == '\n' {
-				break
-			}
-		}
-		if i < j {
-			// text[i:j] constitutes a line
-			seg = Segment{i, j}
-			i = j
-		}
-		return
-	}
-}
-
-// tokenSelection returns, as a selection, the sequence of
-// consecutive occurrences of token sel in the Go src text.
-//
-func tokenSelection(src []byte, sel token.Token) Selection {
-	var s scanner.Scanner
-	fset := token.NewFileSet()
-	file := fset.AddFile("", fset.Base(), len(src))
-	s.Init(file, src, nil, scanner.ScanComments)
-	return func() (seg Segment) {
-		for {
-			pos, tok, lit := s.Scan()
-			if tok == token.EOF {
-				break
-			}
-			offs := file.Offset(pos)
-			if tok == sel {
-				seg = Segment{offs, offs + len(lit)}
-				break
-			}
-		}
-		return
-	}
-}
-
-// makeSelection is a helper function to make a Selection from a slice of pairs.
-// Pairs describing empty segments are ignored.
-//
-func makeSelection(matches [][]int) Selection {
-	i := 0
-	return func() Segment {
-		for i < len(matches) {
-			m := matches[i]
-			i++
-			if m[0] < m[1] {
-				// non-empty segment
-				return Segment{m[0], m[1]}
-			}
-		}
-		return Segment{}
-	}
-}
-
-// regexpSelection computes the Selection for the regular expression expr in text.
-func regexpSelection(text []byte, expr string) Selection {
-	var matches [][]int
-	if rx, err := regexp.Compile(expr); err == nil {
-		matches = rx.FindAllIndex(text, -1)
-	}
-	return makeSelection(matches)
-}
-
-var selRx = regexp.MustCompile(`^([0-9]+):([0-9]+)`)
-
-// RangeSelection computes the Selection for a text range described
-// by the argument str; the range description must match the selRx
-// regular expression.
-func RangeSelection(str string) Selection {
-	m := selRx.FindStringSubmatch(str)
-	if len(m) >= 2 {
-		from, _ := strconv.Atoi(m[1])
-		to, _ := strconv.Atoi(m[2])
-		if from < to {
-			return makeSelection([][]int{{from, to}})
-		}
-	}
-	return nil
-}
-
-// Span tags for all the possible selection combinations that may
-// be generated by FormatText. Selections are indicated by a bitset,
-// and the value of the bitset specifies the tag to be used.
-//
-// bit 0: comments
-// bit 1: highlights
-// bit 2: selections
-//
-var startTags = [][]byte{
-	/* 000 */ []byte(``),
-	/* 001 */ []byte(`<span class="comment">`),
-	/* 010 */ []byte(`<span class="highlight">`),
-	/* 011 */ []byte(`<span class="highlight-comment">`),
-	/* 100 */ []byte(`<span class="selection">`),
-	/* 101 */ []byte(`<span class="selection-comment">`),
-	/* 110 */ []byte(`<span class="selection-highlight">`),
-	/* 111 */ []byte(`<span class="selection-highlight-comment">`),
-}
-
-var endTag = []byte(`</span>`)
-
-func selectionTag(w io.Writer, text []byte, selections int) {
-	if selections < len(startTags) {
-		if tag := startTags[selections]; len(tag) > 0 {
-			w.Write(tag)
-			template.HTMLEscape(w, text)
-			w.Write(endTag)
-			return
-		}
-	}
-	template.HTMLEscape(w, text)
-}
-
-// FormatText HTML-escapes text and writes it to w.
-// Consecutive text segments are wrapped in HTML spans (with tags as
-// defined by startTags and endTag) as follows:
-//
-//	- if line >= 0, line number (ln) spans are inserted before each line,
-//	  starting with the value of line
-//	- if the text is Go source, comments get the "comment" span class
-//	- each occurrence of the regular expression pattern gets the "highlight"
-//	  span class
-//	- text segments covered by selection get the "selection" span class
-//
-// Comments, highlights, and selections may overlap arbitrarily; the respective
-// HTML span classes are specified in the startTags variable.
-//
-func FormatText(w io.Writer, text []byte, line int, goSource bool, pattern string, selection Selection) {
-	var comments, highlights Selection
-	if goSource {
-		comments = tokenSelection(text, token.COMMENT)
-	}
-	if pattern != "" {
-		highlights = regexpSelection(text, pattern)
-	}
-	if line >= 0 || comments != nil || highlights != nil || selection != nil {
-		var lineTag LinkWriter
-		if line >= 0 {
-			lineTag = func(w io.Writer, _ int, start bool) {
-				if start {
-					fmt.Fprintf(w, "<span id=\"L%d\" class=\"ln\">%6d</span>\t", line, line)
-					line++
-				}
-			}
-		}
-		FormatSelections(w, text, lineTag, lineSelection(text), selectionTag, comments, highlights, selection)
-	} else {
-		template.HTMLEscape(w, text)
-	}
-}
diff --git a/cmd/golangorg/godoc/godoc.go b/cmd/golangorg/godoc/godoc.go
deleted file mode 100644
index 6ed8b3d..0000000
--- a/cmd/golangorg/godoc/godoc.go
+++ /dev/null
@@ -1,959 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package godoc is a work-in-progress (2013-07-17) package to
-// begin splitting up the godoc binary into multiple pieces.
-//
-// This package comment will evolve over time as this package splits
-// into smaller pieces.
-package godoc // import "golang.org/x/website/cmd/golangorg/godoc"
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"go/ast"
-	"go/doc"
-	"go/format"
-	"go/printer"
-	"go/token"
-	htmltemplate "html/template"
-	"io"
-	"log"
-	"os"
-	pathpkg "path"
-	"regexp"
-	"strconv"
-	"strings"
-	"text/template"
-	"time"
-	"unicode"
-	"unicode/utf8"
-)
-
-// Fake relative package path for built-ins. Documentation for all globals
-// (not just exported ones) will be shown for packages in this directory.
-const builtinPkgPath = "builtin"
-
-// FuncMap defines template functions used in godoc templates.
-//
-// Convention: template function names ending in "_html" or "_url" produce
-//             HTML- or URL-escaped strings; all other function results may
-//             require explicit escaping in the template.
-func (p *Presentation) FuncMap() template.FuncMap {
-	p.initFuncMapOnce.Do(p.initFuncMap)
-	return p.funcMap
-}
-
-func (p *Presentation) TemplateFuncs() template.FuncMap {
-	p.initFuncMapOnce.Do(p.initFuncMap)
-	return p.templateFuncs
-}
-
-func (p *Presentation) initFuncMap() {
-	if p.Corpus == nil {
-		panic("nil Presentation.Corpus")
-	}
-	p.templateFuncs = template.FuncMap{
-		"code": p.code,
-	}
-	p.funcMap = template.FuncMap{
-		// various helpers
-		"filename": filenameFunc,
-		"repeat":   strings.Repeat,
-		"since":    p.Corpus.pkgAPIInfo.sinceVersionFunc,
-
-		// access to FileInfos (directory listings)
-		"fileInfoName": fileInfoNameFunc,
-		"fileInfoTime": fileInfoTimeFunc,
-
-		// access to search result information
-		"infoKind_html":    infoKind_htmlFunc,
-		"infoLine":         p.infoLineFunc,
-		"infoSnippet_html": p.infoSnippet_htmlFunc,
-
-		// formatting of AST nodes
-		"node":         p.nodeFunc,
-		"node_html":    p.node_htmlFunc,
-		"comment_html": comment_htmlFunc,
-		"sanitize":     sanitizeFunc,
-
-		// support for URL attributes
-		"pkgLink":       pkgLinkFunc,
-		"srcLink":       srcLinkFunc,
-		"posLink_url":   newPosLink_urlFunc(srcPosLinkFunc),
-		"docLink":       docLinkFunc,
-		"queryLink":     queryLinkFunc,
-		"srcBreadcrumb": srcBreadcrumbFunc,
-		"srcToPkgLink":  srcToPkgLinkFunc,
-
-		// formatting of Examples
-		"example_html":   p.example_htmlFunc,
-		"example_name":   p.example_nameFunc,
-		"example_suffix": p.example_suffixFunc,
-
-		// formatting of analysis information
-		"callgraph_html":  p.callgraph_htmlFunc,
-		"implements_html": p.implements_htmlFunc,
-		"methodset_html":  p.methodset_htmlFunc,
-
-		// formatting of Notes
-		"noteTitle": noteTitle,
-
-		// Number operation
-		"multiply": multiply,
-
-		// formatting of PageInfoMode query string
-		"modeQueryString": modeQueryString,
-
-		// check whether to display third party section or not
-		"hasThirdParty": hasThirdParty,
-
-		// get the no. of columns to split the toc in search page
-		"tocColCount": tocColCount,
-	}
-	if p.URLForSrc != nil {
-		p.funcMap["srcLink"] = p.URLForSrc
-	}
-	if p.URLForSrcPos != nil {
-		p.funcMap["posLink_url"] = newPosLink_urlFunc(p.URLForSrcPos)
-	}
-	if p.URLForSrcQuery != nil {
-		p.funcMap["queryLink"] = p.URLForSrcQuery
-	}
-}
-
-func multiply(a, b int) int { return a * b }
-
-func filenameFunc(path string) string {
-	_, localname := pathpkg.Split(path)
-	return localname
-}
-
-func fileInfoNameFunc(fi os.FileInfo) string {
-	name := fi.Name()
-	if fi.IsDir() {
-		name += "/"
-	}
-	return name
-}
-
-func fileInfoTimeFunc(fi os.FileInfo) string {
-	if t := fi.ModTime(); t.Unix() != 0 {
-		return t.Local().String()
-	}
-	return "" // don't return epoch if time is obviously not set
-}
-
-// The strings in infoKinds must be properly html-escaped.
-var infoKinds = [nKinds]string{
-	PackageClause: "package&nbsp;clause",
-	ImportDecl:    "import&nbsp;decl",
-	ConstDecl:     "const&nbsp;decl",
-	TypeDecl:      "type&nbsp;decl",
-	VarDecl:       "var&nbsp;decl",
-	FuncDecl:      "func&nbsp;decl",
-	MethodDecl:    "method&nbsp;decl",
-	Use:           "use",
-}
-
-func infoKind_htmlFunc(info SpotInfo) string {
-	return infoKinds[info.Kind()] // infoKind entries are html-escaped
-}
-
-func (p *Presentation) infoLineFunc(info SpotInfo) int {
-	line := info.Lori()
-	if info.IsIndex() {
-		index, _ := p.Corpus.searchIndex.Get()
-		if index != nil {
-			line = index.(*Index).Snippet(line).Line
-		} else {
-			// no line information available because
-			// we don't have an index - this should
-			// never happen; be conservative and don't
-			// crash
-			line = 0
-		}
-	}
-	return line
-}
-
-func (p *Presentation) infoSnippet_htmlFunc(info SpotInfo) string {
-	if info.IsIndex() {
-		index, _ := p.Corpus.searchIndex.Get()
-		// Snippet.Text was HTML-escaped when it was generated
-		return index.(*Index).Snippet(info.Lori()).Text
-	}
-	return `<span class="alert">no snippet text available</span>`
-}
-
-func (p *Presentation) nodeFunc(info *PageInfo, node interface{}) string {
-	var buf bytes.Buffer
-	p.writeNode(&buf, info, info.FSet, node)
-	return buf.String()
-}
-
-func (p *Presentation) node_htmlFunc(info *PageInfo, node interface{}, linkify bool) string {
-	var buf1 bytes.Buffer
-	p.writeNode(&buf1, info, info.FSet, node)
-
-	var buf2 bytes.Buffer
-	if n, _ := node.(ast.Node); n != nil && linkify && p.DeclLinks {
-		LinkifyText(&buf2, buf1.Bytes(), n)
-		if st, name := isStructTypeDecl(n); st != nil {
-			addStructFieldIDAttributes(&buf2, name, st)
-		}
-	} else {
-		FormatText(&buf2, buf1.Bytes(), -1, true, "", nil)
-	}
-
-	return buf2.String()
-}
-
-// isStructTypeDecl checks whether n is a struct declaration.
-// It either returns a non-nil StructType and its name, or zero values.
-func isStructTypeDecl(n ast.Node) (st *ast.StructType, name string) {
-	gd, ok := n.(*ast.GenDecl)
-	if !ok || gd.Tok != token.TYPE {
-		return nil, ""
-	}
-	if gd.Lparen > 0 {
-		// Parenthesized type. Who does that, anyway?
-		// TODO: Reportedly gri does. Fix this to handle that too.
-		return nil, ""
-	}
-	if len(gd.Specs) != 1 {
-		return nil, ""
-	}
-	ts, ok := gd.Specs[0].(*ast.TypeSpec)
-	if !ok {
-		return nil, ""
-	}
-	st, ok = ts.Type.(*ast.StructType)
-	if !ok {
-		return nil, ""
-	}
-	return st, ts.Name.Name
-}
-
-// addStructFieldIDAttributes modifies the contents of buf such that
-// all struct fields of the named struct have <span id='name.Field'>
-// in them, so people can link to /#Struct.Field.
-func addStructFieldIDAttributes(buf *bytes.Buffer, name string, st *ast.StructType) {
-	if st.Fields == nil {
-		return
-	}
-	// needsLink is a set of identifiers that still need to be
-	// linked, where value == key, to avoid an allocation in func
-	// linkedField.
-	needsLink := make(map[string]string)
-
-	for _, f := range st.Fields.List {
-		if len(f.Names) == 0 {
-			continue
-		}
-		fieldName := f.Names[0].Name
-		needsLink[fieldName] = fieldName
-	}
-	var newBuf bytes.Buffer
-	foreachLine(buf.Bytes(), func(line []byte) {
-		if fieldName := linkedField(line, needsLink); fieldName != "" {
-			fmt.Fprintf(&newBuf, `<span id="%s.%s"></span>`, name, fieldName)
-			delete(needsLink, fieldName)
-		}
-		newBuf.Write(line)
-	})
-	buf.Reset()
-	buf.Write(newBuf.Bytes())
-}
-
-// foreachLine calls fn for each line of in, where a line includes
-// the trailing "\n", except on the last line, if it doesn't exist.
-func foreachLine(in []byte, fn func(line []byte)) {
-	for len(in) > 0 {
-		nl := bytes.IndexByte(in, '\n')
-		if nl == -1 {
-			fn(in)
-			return
-		}
-		fn(in[:nl+1])
-		in = in[nl+1:]
-	}
-}
-
-// commentPrefix is the line prefix for comments after they've been HTMLified.
-var commentPrefix = []byte(`<span class="comment">// `)
-
-// linkedField determines whether the given line starts with an
-// identifer in the provided ids map (mapping from identifier to the
-// same identifier). The line can start with either an identifier or
-// an identifier in a comment. If one matches, it returns the
-// identifier that matched. Otherwise it returns the empty string.
-func linkedField(line []byte, ids map[string]string) string {
-	line = bytes.TrimSpace(line)
-
-	// For fields with a doc string of the
-	// conventional form, we put the new span into
-	// the comment instead of the field.
-	// The "conventional" form is a complete sentence
-	// per https://golang.org/s/style#comment-sentences like:
-	//
-	//    // Foo is an optional Fooer to foo the foos.
-	//    Foo Fooer
-	//
-	// In this case, we want the #StructName.Foo
-	// link to make the browser go to the comment
-	// line "Foo is an optional Fooer" instead of
-	// the "Foo Fooer" line, which could otherwise
-	// obscure the docs above the browser's "fold".
-	//
-	// TODO: do this better, so it works for all
-	// comments, including unconventional ones.
-	if bytes.HasPrefix(line, commentPrefix) {
-		line = line[len(commentPrefix):]
-	}
-	id := scanIdentifier(line)
-	if len(id) == 0 {
-		// No leading identifier. Avoid map lookup for
-		// somewhat common case.
-		return ""
-	}
-	return ids[string(id)]
-}
-
-// scanIdentifier scans a valid Go identifier off the front of v and
-// either returns a subslice of v if there's a valid identifier, or
-// returns a zero-length slice.
-func scanIdentifier(v []byte) []byte {
-	var n int // number of leading bytes of v belonging to an identifier
-	for {
-		r, width := utf8.DecodeRune(v[n:])
-		if !(isLetter(r) || n > 0 && isDigit(r)) {
-			break
-		}
-		n += width
-	}
-	return v[:n]
-}
-
-func isLetter(ch rune) bool {
-	return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
-}
-
-func isDigit(ch rune) bool {
-	return '0' <= ch && ch <= '9' || ch >= utf8.RuneSelf && unicode.IsDigit(ch)
-}
-
-func comment_htmlFunc(comment string) string {
-	var buf bytes.Buffer
-	// TODO(gri) Provide list of words (e.g. function parameters)
-	//           to be emphasized by ToHTML.
-	doc.ToHTML(&buf, comment, nil) // does html-escaping
-	return buf.String()
-}
-
-// punchCardWidth is the number of columns of fixed-width
-// characters to assume when wrapping text.  Very few people
-// use terminals or cards smaller than 80 characters, so 80 it is.
-// We do not try to sniff the environment or the tty to adapt to
-// the situation; instead, by using a constant we make sure that
-// godoc always produces the same output regardless of context,
-// a consistency that is lost otherwise.  For example, if we sniffed
-// the environment or tty, then http://golang.org/pkg/math/?m=text
-// would depend on the width of the terminal where godoc started,
-// which is clearly bogus.  More generally, the Unix tools that behave
-// differently when writing to a tty than when writing to a file have
-// a history of causing confusion (compare `ls` and `ls | cat`), and we
-// want to avoid that mistake here.
-const punchCardWidth = 80
-
-func containsOnlySpace(buf []byte) bool {
-	isNotSpace := func(r rune) bool { return !unicode.IsSpace(r) }
-	return bytes.IndexFunc(buf, isNotSpace) == -1
-}
-
-// sanitizeFunc sanitizes the argument src by replacing newlines with
-// blanks, removing extra blanks, and by removing trailing whitespace
-// and commas before closing parentheses.
-func sanitizeFunc(src string) string {
-	buf := make([]byte, len(src))
-	j := 0      // buf index
-	comma := -1 // comma index if >= 0
-	for i := 0; i < len(src); i++ {
-		ch := src[i]
-		switch ch {
-		case '\t', '\n', ' ':
-			// ignore whitespace at the beginning, after a blank, or after opening parentheses
-			if j == 0 {
-				continue
-			}
-			if p := buf[j-1]; p == ' ' || p == '(' || p == '{' || p == '[' {
-				continue
-			}
-			// replace all whitespace with blanks
-			ch = ' '
-		case ',':
-			comma = j
-		case ')', '}', ']':
-			// remove any trailing comma
-			if comma >= 0 {
-				j = comma
-			}
-			// remove any trailing whitespace
-			if j > 0 && buf[j-1] == ' ' {
-				j--
-			}
-		default:
-			comma = -1
-		}
-		buf[j] = ch
-		j++
-	}
-	// remove trailing blank, if any
-	if j > 0 && buf[j-1] == ' ' {
-		j--
-	}
-	return string(buf[:j])
-}
-
-type PageInfo struct {
-	Dirname  string // directory containing the package
-	Err      error  // error or nil
-	GoogleCN bool   // page is being served from golang.google.cn
-
-	Mode PageInfoMode // display metadata from query string
-
-	// package info
-	FSet       *token.FileSet         // nil if no package documentation
-	PDoc       *doc.Package           // nil if no package documentation
-	Examples   []*doc.Example         // nil if no example code
-	Notes      map[string][]*doc.Note // nil if no package Notes
-	PAst       map[string]*ast.File   // nil if no AST with package exports
-	IsMain     bool                   // true for package main
-	IsFiltered bool                   // true if results were filtered
-
-	// analysis info
-	TypeInfoIndex  map[string]int  // index of JSON datum for type T (if -analysis=type)
-	AnalysisData   htmltemplate.JS // array of TypeInfoJSON values
-	CallGraph      htmltemplate.JS // array of PCGNodeJSON values    (if -analysis=pointer)
-	CallGraphIndex map[string]int  // maps func name to index in CallGraph
-
-	// directory info
-	Dirs    *DirList  // nil if no directory information
-	DirTime time.Time // directory time stamp
-	DirFlat bool      // if set, show directory in a flat (non-indented) manner
-}
-
-func (info *PageInfo) IsEmpty() bool {
-	return info.Err != nil || info.PAst == nil && info.PDoc == nil && info.Dirs == nil
-}
-
-func pkgLinkFunc(path string) string {
-	// because of the irregular mapping under goroot
-	// we need to correct certain relative paths
-	path = strings.TrimPrefix(path, "/")
-	path = strings.TrimPrefix(path, "src/")
-	path = strings.TrimPrefix(path, "pkg/")
-	return "pkg/" + path
-}
-
-// srcToPkgLinkFunc builds an <a> tag linking to the package
-// documentation of relpath.
-func srcToPkgLinkFunc(relpath string) string {
-	relpath = pkgLinkFunc(relpath)
-	relpath = pathpkg.Dir(relpath)
-	if relpath == "pkg" {
-		return `<a href="/pkg">Index</a>`
-	}
-	return fmt.Sprintf(`<a href="/%s">%s</a>`, relpath, relpath[len("pkg/"):])
-}
-
-// srcBreadcrumbFun converts each segment of relpath to a HTML <a>.
-// Each segment links to its corresponding src directories.
-func srcBreadcrumbFunc(relpath string) string {
-	segments := strings.Split(relpath, "/")
-	var buf bytes.Buffer
-	var selectedSegment string
-	var selectedIndex int
-
-	if strings.HasSuffix(relpath, "/") {
-		// relpath is a directory ending with a "/".
-		// Selected segment is the segment before the last slash.
-		selectedIndex = len(segments) - 2
-		selectedSegment = segments[selectedIndex] + "/"
-	} else {
-		selectedIndex = len(segments) - 1
-		selectedSegment = segments[selectedIndex]
-	}
-
-	for i := range segments[:selectedIndex] {
-		buf.WriteString(fmt.Sprintf(`<a href="/%s">%s</a>/`,
-			strings.Join(segments[:i+1], "/"),
-			segments[i],
-		))
-	}
-
-	buf.WriteString(`<span class="text-muted">`)
-	buf.WriteString(selectedSegment)
-	buf.WriteString(`</span>`)
-	return buf.String()
-}
-
-func newPosLink_urlFunc(srcPosLinkFunc func(s string, line, low, high int) string) func(info *PageInfo, n interface{}) string {
-	// n must be an ast.Node or a *doc.Note
-	return func(info *PageInfo, n interface{}) string {
-		var pos, end token.Pos
-
-		switch n := n.(type) {
-		case ast.Node:
-			pos = n.Pos()
-			end = n.End()
-		case *doc.Note:
-			pos = n.Pos
-			end = n.End
-		default:
-			panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n))
-		}
-
-		var relpath string
-		var line int
-		var low, high int // selection offset range
-
-		if pos.IsValid() {
-			p := info.FSet.Position(pos)
-			relpath = p.Filename
-			line = p.Line
-			low = p.Offset
-		}
-		if end.IsValid() {
-			high = info.FSet.Position(end).Offset
-		}
-
-		return srcPosLinkFunc(relpath, line, low, high)
-	}
-}
-
-func srcPosLinkFunc(s string, line, low, high int) string {
-	s = srcLinkFunc(s)
-	var buf bytes.Buffer
-	template.HTMLEscape(&buf, []byte(s))
-	// selection ranges are of form "s=low:high"
-	if low < high {
-		fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping
-		// if we have a selection, position the page
-		// such that the selection is a bit below the top
-		line -= 10
-		if line < 1 {
-			line = 1
-		}
-	}
-	// line id's in html-printed source are of the
-	// form "L%d" where %d stands for the line number
-	if line > 0 {
-		fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping
-	}
-	return buf.String()
-}
-
-func srcLinkFunc(s string) string {
-	s = pathpkg.Clean("/" + s)
-	if !strings.HasPrefix(s, "/src/") {
-		s = "/src" + s
-	}
-	return s
-}
-
-// queryLinkFunc returns a URL for a line in a source file with a highlighted
-// query term.
-// s is expected to be a path to a source file.
-// query is expected to be a string that has already been appropriately escaped
-// for use in a URL query.
-func queryLinkFunc(s, query string, line int) string {
-	url := pathpkg.Clean("/"+s) + "?h=" + query
-	if line > 0 {
-		url += "#L" + strconv.Itoa(line)
-	}
-	return url
-}
-
-func docLinkFunc(s string, ident string) string {
-	return pathpkg.Clean("/pkg/"+s) + "/#" + ident
-}
-
-func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) string {
-	var buf bytes.Buffer
-	for _, eg := range info.Examples {
-		name := stripExampleSuffix(eg.Name)
-
-		if name != funcName {
-			continue
-		}
-
-		// print code
-		cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
-		code := p.node_htmlFunc(info, cnode, true)
-		out := eg.Output
-		wholeFile := true
-
-		// Additional formatting if this is a function body.
-		if n := len(code); n >= 2 && code[0] == '{' && code[n-1] == '}' {
-			wholeFile = false
-			// remove surrounding braces
-			code = code[1 : n-1]
-			// unindent
-			code = replaceLeadingIndentation(code, strings.Repeat(" ", p.TabWidth), "")
-			// remove output comment
-			if loc := exampleOutputRx.FindStringIndex(code); loc != nil {
-				code = strings.TrimSpace(code[:loc[0]])
-			}
-		}
-
-		// Write out the playground code in standard Go style
-		// (use tabs, no comment highlight, etc).
-		play := ""
-		if eg.Play != nil && p.ShowPlayground {
-			var buf bytes.Buffer
-			eg.Play.Comments = filterOutBuildAnnotations(eg.Play.Comments)
-			if err := format.Node(&buf, info.FSet, eg.Play); err != nil {
-				log.Print(err)
-			} else {
-				play = buf.String()
-			}
-		}
-
-		// Drop output, as the output comment will appear in the code.
-		if wholeFile && play == "" {
-			out = ""
-		}
-
-		if p.ExampleHTML == nil {
-			out = ""
-			return ""
-		}
-
-		err := p.ExampleHTML.Execute(&buf, struct {
-			Name, Doc, Code, Play, Output string
-			GoogleCN                      bool
-		}{eg.Name, eg.Doc, code, play, out, info.GoogleCN})
-		if err != nil {
-			log.Print(err)
-		}
-	}
-	return buf.String()
-}
-
-func filterOutBuildAnnotations(cg []*ast.CommentGroup) []*ast.CommentGroup {
-	if len(cg) == 0 {
-		return cg
-	}
-
-	for i := range cg {
-		if !strings.HasPrefix(cg[i].Text(), "+build ") {
-			// Found the first non-build tag, return from here until the end
-			// of the slice.
-			return cg[i:]
-		}
-	}
-
-	// There weren't any non-build tags, return an empty slice.
-	return []*ast.CommentGroup{}
-}
-
-// example_nameFunc takes an example function name and returns its display
-// name. For example, "Foo_Bar_quux" becomes "Foo.Bar (Quux)".
-func (p *Presentation) example_nameFunc(s string) string {
-	name, suffix := splitExampleName(s)
-	// replace _ with . for method names
-	name = strings.Replace(name, "_", ".", 1)
-	// use "Package" if no name provided
-	if name == "" {
-		name = "Package"
-	}
-	return name + suffix
-}
-
-// example_suffixFunc takes an example function name and returns its suffix in
-// parenthesized form. For example, "Foo_Bar_quux" becomes " (Quux)".
-func (p *Presentation) example_suffixFunc(name string) string {
-	_, suffix := splitExampleName(name)
-	return suffix
-}
-
-// implements_html returns the "> Implements" toggle for a package-level named type.
-// Its contents are populated from JSON data by client-side JS at load time.
-func (p *Presentation) implements_htmlFunc(info *PageInfo, typeName string) string {
-	if p.ImplementsHTML == nil {
-		return ""
-	}
-	index, ok := info.TypeInfoIndex[typeName]
-	if !ok {
-		return ""
-	}
-	var buf bytes.Buffer
-	err := p.ImplementsHTML.Execute(&buf, struct{ Index int }{index})
-	if err != nil {
-		log.Print(err)
-	}
-	return buf.String()
-}
-
-// methodset_html returns the "> Method set" toggle for a package-level named type.
-// Its contents are populated from JSON data by client-side JS at load time.
-func (p *Presentation) methodset_htmlFunc(info *PageInfo, typeName string) string {
-	if p.MethodSetHTML == nil {
-		return ""
-	}
-	index, ok := info.TypeInfoIndex[typeName]
-	if !ok {
-		return ""
-	}
-	var buf bytes.Buffer
-	err := p.MethodSetHTML.Execute(&buf, struct{ Index int }{index})
-	if err != nil {
-		log.Print(err)
-	}
-	return buf.String()
-}
-
-// callgraph_html returns the "> Call graph" toggle for a package-level func.
-// Its contents are populated from JSON data by client-side JS at load time.
-func (p *Presentation) callgraph_htmlFunc(info *PageInfo, recv, name string) string {
-	if p.CallGraphHTML == nil {
-		return ""
-	}
-	if recv != "" {
-		// Format must match (*ssa.Function).RelString().
-		name = fmt.Sprintf("(%s).%s", recv, name)
-	}
-	index, ok := info.CallGraphIndex[name]
-	if !ok {
-		return ""
-	}
-	var buf bytes.Buffer
-	err := p.CallGraphHTML.Execute(&buf, struct{ Index int }{index})
-	if err != nil {
-		log.Print(err)
-	}
-	return buf.String()
-}
-
-func noteTitle(note string) string {
-	return strings.Title(strings.ToLower(note))
-}
-
-func startsWithUppercase(s string) bool {
-	r, _ := utf8.DecodeRuneInString(s)
-	return unicode.IsUpper(r)
-}
-
-var exampleOutputRx = regexp.MustCompile(`(?i)//[[:space:]]*(unordered )?output:`)
-
-// stripExampleSuffix strips lowercase braz in Foo_braz or Foo_Bar_braz from name
-// while keeping uppercase Braz in Foo_Braz.
-func stripExampleSuffix(name string) string {
-	if i := strings.LastIndex(name, "_"); i != -1 {
-		if i < len(name)-1 && !startsWithUppercase(name[i+1:]) {
-			name = name[:i]
-		}
-	}
-	return name
-}
-
-func splitExampleName(s string) (name, suffix string) {
-	i := strings.LastIndex(s, "_")
-	if 0 <= i && i < len(s)-1 && !startsWithUppercase(s[i+1:]) {
-		name = s[:i]
-		suffix = " (" + strings.Title(s[i+1:]) + ")"
-		return
-	}
-	name = s
-	return
-}
-
-// replaceLeadingIndentation replaces oldIndent at the beginning of each line
-// with newIndent. This is used for formatting examples. Raw strings that
-// span multiple lines are handled specially: oldIndent is not removed (since
-// go/printer will not add any indentation there), but newIndent is added
-// (since we may still want leading indentation).
-func replaceLeadingIndentation(body, oldIndent, newIndent string) string {
-	// Handle indent at the beginning of the first line. After this, we handle
-	// indentation only after a newline.
-	var buf bytes.Buffer
-	if strings.HasPrefix(body, oldIndent) {
-		buf.WriteString(newIndent)
-		body = body[len(oldIndent):]
-	}
-
-	// Use a state machine to keep track of whether we're in a string or
-	// rune literal while we process the rest of the code.
-	const (
-		codeState = iota
-		runeState
-		interpretedStringState
-		rawStringState
-	)
-	searchChars := []string{
-		"'\"`\n", // codeState
-		`\'`,     // runeState
-		`\"`,     // interpretedStringState
-		"`\n",    // rawStringState
-		// newlineState does not need to search
-	}
-	state := codeState
-	for {
-		i := strings.IndexAny(body, searchChars[state])
-		if i < 0 {
-			buf.WriteString(body)
-			break
-		}
-		c := body[i]
-		buf.WriteString(body[:i+1])
-		body = body[i+1:]
-		switch state {
-		case codeState:
-			switch c {
-			case '\'':
-				state = runeState
-			case '"':
-				state = interpretedStringState
-			case '`':
-				state = rawStringState
-			case '\n':
-				if strings.HasPrefix(body, oldIndent) {
-					buf.WriteString(newIndent)
-					body = body[len(oldIndent):]
-				}
-			}
-
-		case runeState:
-			switch c {
-			case '\\':
-				r, size := utf8.DecodeRuneInString(body)
-				buf.WriteRune(r)
-				body = body[size:]
-			case '\'':
-				state = codeState
-			}
-
-		case interpretedStringState:
-			switch c {
-			case '\\':
-				r, size := utf8.DecodeRuneInString(body)
-				buf.WriteRune(r)
-				body = body[size:]
-			case '"':
-				state = codeState
-			}
-
-		case rawStringState:
-			switch c {
-			case '`':
-				state = codeState
-			case '\n':
-				buf.WriteString(newIndent)
-			}
-		}
-	}
-	return buf.String()
-}
-
-// writeNode writes the AST node x to w.
-//
-// The provided fset must be non-nil. The pageInfo is optional. If
-// present, the pageInfo is used to add comments to struct fields to
-// say which version of Go introduced them.
-func (p *Presentation) writeNode(w io.Writer, pageInfo *PageInfo, fset *token.FileSet, x interface{}) {
-	// convert trailing tabs into spaces using a tconv filter
-	// to ensure a good outcome in most browsers (there may still
-	// be tabs in comments and strings, but converting those into
-	// the right number of spaces is much harder)
-	//
-	// TODO(gri) rethink printer flags - perhaps tconv can be eliminated
-	//           with an another printer mode (which is more efficiently
-	//           implemented in the printer than here with another layer)
-
-	var pkgName, structName string
-	var apiInfo pkgAPIVersions
-	if gd, ok := x.(*ast.GenDecl); ok && pageInfo != nil && pageInfo.PDoc != nil &&
-		p.Corpus != nil &&
-		gd.Tok == token.TYPE && len(gd.Specs) != 0 {
-		pkgName = pageInfo.PDoc.ImportPath
-		if ts, ok := gd.Specs[0].(*ast.TypeSpec); ok {
-			if _, ok := ts.Type.(*ast.StructType); ok {
-				structName = ts.Name.Name
-			}
-		}
-		apiInfo = p.Corpus.pkgAPIInfo[pkgName]
-	}
-
-	var out = w
-	var buf bytes.Buffer
-	if structName != "" {
-		out = &buf
-	}
-
-	mode := printer.TabIndent | printer.UseSpaces
-	err := (&printer.Config{Mode: mode, Tabwidth: p.TabWidth}).Fprint(&tconv{p: p, output: out}, fset, x)
-	if err != nil {
-		log.Print(err)
-	}
-
-	// Add comments to struct fields saying which Go version introducd them.
-	if structName != "" {
-		fieldSince := apiInfo.fieldSince[structName]
-		typeSince := apiInfo.typeSince[structName]
-		// Add/rewrite comments on struct fields to note which Go version added them.
-		var buf2 bytes.Buffer
-		buf2.Grow(buf.Len() + len(" // Added in Go 1.n")*10)
-		bs := bufio.NewScanner(&buf)
-		for bs.Scan() {
-			line := bs.Bytes()
-			field := firstIdent(line)
-			var since string
-			if field != "" {
-				since = fieldSince[field]
-				if since != "" && since == typeSince {
-					// Don't highlight field versions if they were the
-					// same as the struct itself.
-					since = ""
-				}
-			}
-			if since == "" {
-				buf2.Write(line)
-			} else {
-				if bytes.Contains(line, slashSlash) {
-					line = bytes.TrimRight(line, " \t.")
-					buf2.Write(line)
-					buf2.WriteString("; added in Go ")
-				} else {
-					buf2.Write(line)
-					buf2.WriteString(" // Go ")
-				}
-				buf2.WriteString(since)
-			}
-			buf2.WriteByte('\n')
-		}
-		w.Write(buf2.Bytes())
-	}
-}
-
-var slashSlash = []byte("//")
-
-// WriteNode writes x to w.
-// TODO(bgarcia) Is this method needed? It's just a wrapper for p.writeNode.
-func (p *Presentation) WriteNode(w io.Writer, fset *token.FileSet, x interface{}) {
-	p.writeNode(w, nil, fset, x)
-}
-
-// firstIdent returns the first identifier in x.
-// This actually parses "identifiers" that begin with numbers too, but we
-// never feed it such input, so it's fine.
-func firstIdent(x []byte) string {
-	x = bytes.TrimSpace(x)
-	i := bytes.IndexFunc(x, func(r rune) bool { return !unicode.IsLetter(r) && !unicode.IsNumber(r) })
-	if i == -1 {
-		return string(x)
-	}
-	return string(x[:i])
-}
diff --git a/cmd/golangorg/godoc/godoc17_test.go b/cmd/golangorg/godoc/godoc17_test.go
deleted file mode 100644
index d153991..0000000
--- a/cmd/golangorg/godoc/godoc17_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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 go1.7
-
-package godoc
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-)
-
-// Verify that scanIdentifier isn't quadratic.
-// This doesn't actually measure and fail on its own, but it was previously
-// very obvious when running by hand.
-//
-// TODO: if there's a reliable and non-flaky way to test this, do so.
-// Maybe count user CPU time instead of wall time? But that's not easy
-// to do portably in Go.
-func TestStructField(t *testing.T) {
-	for _, n := range []int{10, 100, 1000, 10000} {
-		n := n
-		t.Run(fmt.Sprint(n), func(t *testing.T) {
-			var buf bytes.Buffer
-			fmt.Fprintf(&buf, "package foo\n\ntype T struct {\n")
-			for i := 0; i < n; i++ {
-				fmt.Fprintf(&buf, "\t// Field%d is foo.\n\tField%d int\n\n", i, i)
-			}
-			fmt.Fprintf(&buf, "}\n")
-			linkifySource(t, buf.Bytes())
-		})
-	}
-}
diff --git a/cmd/golangorg/godoc/godoc_test.go b/cmd/golangorg/godoc/godoc_test.go
deleted file mode 100644
index 33dbe3f..0000000
--- a/cmd/golangorg/godoc/godoc_test.go
+++ /dev/null
@@ -1,370 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"bytes"
-	"go/parser"
-	"go/token"
-	"strings"
-	"testing"
-)
-
-func TestPkgLinkFunc(t *testing.T) {
-	for _, tc := range []struct {
-		path string
-		want string
-	}{
-		{"/src/fmt", "pkg/fmt"},
-		{"src/fmt", "pkg/fmt"},
-		{"/fmt", "pkg/fmt"},
-		{"fmt", "pkg/fmt"},
-	} {
-		if got := pkgLinkFunc(tc.path); got != tc.want {
-			t.Errorf("pkgLinkFunc(%v) = %v; want %v", tc.path, got, tc.want)
-		}
-	}
-}
-
-func TestSrcPosLinkFunc(t *testing.T) {
-	for _, tc := range []struct {
-		src  string
-		line int
-		low  int
-		high int
-		want string
-	}{
-		{"/src/fmt/print.go", 42, 30, 50, "/src/fmt/print.go?s=30:50#L32"},
-		{"/src/fmt/print.go", 2, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
-		{"/src/fmt/print.go", 2, 0, 0, "/src/fmt/print.go#L2"},
-		{"/src/fmt/print.go", 0, 0, 0, "/src/fmt/print.go"},
-		{"/src/fmt/print.go", 0, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
-		{"fmt/print.go", 0, 0, 0, "/src/fmt/print.go"},
-		{"fmt/print.go", 0, 1, 5, "/src/fmt/print.go?s=1:5#L1"},
-	} {
-		if got := srcPosLinkFunc(tc.src, tc.line, tc.low, tc.high); got != tc.want {
-			t.Errorf("srcLinkFunc(%v, %v, %v, %v) = %v; want %v", tc.src, tc.line, tc.low, tc.high, got, tc.want)
-		}
-	}
-}
-
-func TestSrcLinkFunc(t *testing.T) {
-	for _, tc := range []struct {
-		src  string
-		want string
-	}{
-		{"/src/fmt/print.go", "/src/fmt/print.go"},
-		{"src/fmt/print.go", "/src/fmt/print.go"},
-		{"/fmt/print.go", "/src/fmt/print.go"},
-		{"fmt/print.go", "/src/fmt/print.go"},
-	} {
-		if got := srcLinkFunc(tc.src); got != tc.want {
-			t.Errorf("srcLinkFunc(%v) = %v; want %v", tc.src, got, tc.want)
-		}
-	}
-}
-
-func TestQueryLinkFunc(t *testing.T) {
-	for _, tc := range []struct {
-		src   string
-		query string
-		line  int
-		want  string
-	}{
-		{"/src/fmt/print.go", "Sprintf", 33, "/src/fmt/print.go?h=Sprintf#L33"},
-		{"/src/fmt/print.go", "Sprintf", 0, "/src/fmt/print.go?h=Sprintf"},
-		{"src/fmt/print.go", "EOF", 33, "/src/fmt/print.go?h=EOF#L33"},
-		{"src/fmt/print.go", "a%3f+%26b", 1, "/src/fmt/print.go?h=a%3f+%26b#L1"},
-	} {
-		if got := queryLinkFunc(tc.src, tc.query, tc.line); got != tc.want {
-			t.Errorf("queryLinkFunc(%v, %v, %v) = %v; want %v", tc.src, tc.query, tc.line, got, tc.want)
-		}
-	}
-}
-
-func TestDocLinkFunc(t *testing.T) {
-	for _, tc := range []struct {
-		src   string
-		ident string
-		want  string
-	}{
-		{"fmt", "Sprintf", "/pkg/fmt/#Sprintf"},
-		{"fmt", "EOF", "/pkg/fmt/#EOF"},
-	} {
-		if got := docLinkFunc(tc.src, tc.ident); got != tc.want {
-			t.Errorf("docLinkFunc(%v, %v) = %v; want %v", tc.src, tc.ident, got, tc.want)
-		}
-	}
-}
-
-func TestSanitizeFunc(t *testing.T) {
-	for _, tc := range []struct {
-		src  string
-		want string
-	}{
-		{},
-		{"foo", "foo"},
-		{"func   f()", "func f()"},
-		{"func f(a int,)", "func f(a int)"},
-		{"func f(a int,\n)", "func f(a int)"},
-		{"func f(\n\ta int,\n\tb int,\n\tc int,\n)", "func f(a int, b int, c int)"},
-		{"  (   a,   b,  c  )  ", "(a, b, c)"},
-		{"(  a,  b, c    int, foo   bar  ,  )", "(a, b, c int, foo bar)"},
-		{"{   a,   b}", "{a, b}"},
-		{"[   a,   b]", "[a, b]"},
-	} {
-		if got := sanitizeFunc(tc.src); got != tc.want {
-			t.Errorf("sanitizeFunc(%v) = %v; want %v", tc.src, got, tc.want)
-		}
-	}
-}
-
-// Test that we add <span id="StructName.FieldName"> elements
-// to the HTML of struct fields.
-func TestStructFieldsIDAttributes(t *testing.T) {
-	got := linkifySource(t, []byte(`
-package foo
-
-type T struct {
-	NoDoc string
-
-	// Doc has a comment.
-	Doc string
-
-	// Opt, if non-nil, is an option.
-	Opt *int
-
-	// Опция - другое поле.
-	Опция bool
-}
-`))
-	want := `type T struct {
-<span id="T.NoDoc"></span>NoDoc <a href="/pkg/builtin/#string">string</a>
-
-<span id="T.Doc"></span><span class="comment">// Doc has a comment.</span>
-Doc <a href="/pkg/builtin/#string">string</a>
-
-<span id="T.Opt"></span><span class="comment">// Opt, if non-nil, is an option.</span>
-Opt *<a href="/pkg/builtin/#int">int</a>
-
-<span id="T.Опция"></span><span class="comment">// Опция - другое поле.</span>
-Опция <a href="/pkg/builtin/#bool">bool</a>
-}`
-	if got != want {
-		t.Errorf("got: %s\n\nwant: %s\n", got, want)
-	}
-}
-
-// Test that we add <span id="ConstName"> elements to the HTML
-// of definitions in const and var specs.
-func TestValueSpecIDAttributes(t *testing.T) {
-	got := linkifySource(t, []byte(`
-package foo
-
-const (
-	NoDoc string = "NoDoc"
-
-	// Doc has a comment
-	Doc = "Doc"
-
-	NoVal
-)`))
-	want := `const (
-<span id="NoDoc">NoDoc</span> <a href="/pkg/builtin/#string">string</a> = &#34;NoDoc&#34;
-
-<span class="comment">// Doc has a comment</span>
-<span id="Doc">Doc</span> = &#34;Doc&#34;
-
-<span id="NoVal">NoVal</span>
-)`
-	if got != want {
-		t.Errorf("got: %s\n\nwant: %s\n", got, want)
-	}
-}
-
-func TestCompositeLitLinkFields(t *testing.T) {
-	got := linkifySource(t, []byte(`
-package foo
-
-type T struct {
-	X int
-}
-
-var S T = T{X: 12}`))
-	want := `type T struct {
-<span id="T.X"></span>X <a href="/pkg/builtin/#int">int</a>
-}
-var <span id="S">S</span> <a href="#T">T</a> = <a href="#T">T</a>{<a href="#T.X">X</a>: 12}`
-	if got != want {
-		t.Errorf("got: %s\n\nwant: %s\n", got, want)
-	}
-}
-
-func TestFuncDeclNotLink(t *testing.T) {
-	// Function.
-	got := linkifySource(t, []byte(`
-package http
-
-func Get(url string) (resp *Response, err error)`))
-	want := `func Get(url <a href="/pkg/builtin/#string">string</a>) (resp *<a href="#Response">Response</a>, err <a href="/pkg/builtin/#error">error</a>)`
-	if got != want {
-		t.Errorf("got: %s\n\nwant: %s\n", got, want)
-	}
-
-	// Method.
-	got = linkifySource(t, []byte(`
-package http
-
-func (h Header) Get(key string) string`))
-	want = `func (h <a href="#Header">Header</a>) Get(key <a href="/pkg/builtin/#string">string</a>) <a href="/pkg/builtin/#string">string</a>`
-	if got != want {
-		t.Errorf("got: %s\n\nwant: %s\n", got, want)
-	}
-}
-
-func linkifySource(t *testing.T, src []byte) string {
-	p := &Presentation{
-		DeclLinks: true,
-	}
-	fset := token.NewFileSet()
-	af, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments)
-	if err != nil {
-		t.Fatal(err)
-	}
-	var buf bytes.Buffer
-	pi := &PageInfo{
-		FSet: fset,
-	}
-	sep := ""
-	for _, decl := range af.Decls {
-		buf.WriteString(sep)
-		sep = "\n"
-		buf.WriteString(p.node_htmlFunc(pi, decl, true))
-	}
-	return buf.String()
-}
-
-func TestScanIdentifier(t *testing.T) {
-	tests := []struct {
-		in, want string
-	}{
-		{"foo bar", "foo"},
-		{"foo/bar", "foo"},
-		{" foo", ""},
-		{"фоо", "фоо"},
-		{"f123", "f123"},
-		{"123f", ""},
-	}
-	for _, tt := range tests {
-		got := scanIdentifier([]byte(tt.in))
-		if string(got) != tt.want {
-			t.Errorf("scanIdentifier(%q) = %q; want %q", tt.in, got, tt.want)
-		}
-	}
-}
-
-func TestReplaceLeadingIndentation(t *testing.T) {
-	oldIndent := strings.Repeat(" ", 2)
-	newIndent := strings.Repeat(" ", 4)
-	tests := []struct {
-		src, want string
-	}{
-		{"  foo\n    bar\n  baz", "    foo\n      bar\n    baz"},
-		{"  '`'\n  '`'\n", "    '`'\n    '`'\n"},
-		{"  '\\''\n  '`'\n", "    '\\''\n    '`'\n"},
-		{"  \"`\"\n  \"`\"\n", "    \"`\"\n    \"`\"\n"},
-		{"  `foo\n  bar`", "    `foo\n      bar`"},
-		{"  `foo\\`\n  bar", "    `foo\\`\n    bar"},
-		{"  '\\`'`foo\n  bar", "    '\\`'`foo\n      bar"},
-		{
-			"  if true {\n    foo := `One\n    \tTwo\nThree`\n  }\n",
-			"    if true {\n      foo := `One\n        \tTwo\n    Three`\n    }\n",
-		},
-	}
-	for _, tc := range tests {
-		if got := replaceLeadingIndentation(tc.src, oldIndent, newIndent); got != tc.want {
-			t.Errorf("replaceLeadingIndentation:\n%v\n---\nhave:\n%v\n---\nwant:\n%v\n",
-				tc.src, got, tc.want)
-		}
-	}
-}
-
-func TestSrcBreadcrumbFunc(t *testing.T) {
-	for _, tc := range []struct {
-		path string
-		want string
-	}{
-		{"src/", `<span class="text-muted">src/</span>`},
-		{"src/fmt/", `<a href="/src">src</a>/<span class="text-muted">fmt/</span>`},
-		{"src/fmt/print.go", `<a href="/src">src</a>/<a href="/src/fmt">fmt</a>/<span class="text-muted">print.go</span>`},
-	} {
-		if got := srcBreadcrumbFunc(tc.path); got != tc.want {
-			t.Errorf("srcBreadcrumbFunc(%v) = %v; want %v", tc.path, got, tc.want)
-		}
-	}
-}
-
-func TestSrcToPkgLinkFunc(t *testing.T) {
-	for _, tc := range []struct {
-		path string
-		want string
-	}{
-		{"src/", `<a href="/pkg">Index</a>`},
-		{"src/fmt/", `<a href="/pkg/fmt">fmt</a>`},
-		{"pkg/", `<a href="/pkg">Index</a>`},
-		{"pkg/LICENSE", `<a href="/pkg">Index</a>`},
-	} {
-		if got := srcToPkgLinkFunc(tc.path); got != tc.want {
-			t.Errorf("srcToPkgLinkFunc(%v) = %v; want %v", tc.path, got, tc.want)
-		}
-	}
-}
-
-func TestFilterOutBuildAnnotations(t *testing.T) {
-	// TODO: simplify this by using a multiline string once we stop
-	// using go vet from 1.10 on the build dashboard.
-	// https://golang.org/issue/26627
-	src := []byte("// +build !foo\n" +
-		"// +build !anothertag\n" +
-		"\n" +
-		"// non-tag comment\n" +
-		"\n" +
-		"package foo\n" +
-		"\n" +
-		"func bar() int {\n" +
-		"	return 42\n" +
-		"}\n")
-
-	fset := token.NewFileSet()
-	af, err := parser.ParseFile(fset, "foo.go", src, parser.ParseComments)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	var found bool
-	for _, cg := range af.Comments {
-		if strings.HasPrefix(cg.Text(), "+build ") {
-			found = true
-			break
-		}
-	}
-	if !found {
-		t.Errorf("TestFilterOutBuildAnnotations is broken: missing build tag in test input")
-	}
-
-	found = false
-	for _, cg := range filterOutBuildAnnotations(af.Comments) {
-		if strings.HasPrefix(cg.Text(), "+build ") {
-			t.Errorf("filterOutBuildAnnotations failed to filter build tag")
-		}
-
-		if strings.Contains(cg.Text(), "non-tag comment") {
-			found = true
-		}
-	}
-	if !found {
-		t.Errorf("filterOutBuildAnnotations should not remove non-build tag comment")
-	}
-}
diff --git a/cmd/golangorg/godoc/index.go b/cmd/golangorg/godoc/index.go
deleted file mode 100644
index ee54447..0000000
--- a/cmd/golangorg/godoc/index.go
+++ /dev/null
@@ -1,1580 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains the infrastructure to create an
-// identifier and full-text index for a set of Go files.
-//
-// Algorithm for identifier index:
-// - traverse all .go files of the file tree specified by root
-// - for each identifier (word) encountered, collect all occurrences (spots)
-//   into a list; this produces a list of spots for each word
-// - reduce the lists: from a list of spots to a list of FileRuns,
-//   and from a list of FileRuns into a list of PakRuns
-// - make a HitList from the PakRuns
-//
-// Details:
-// - keep two lists per word: one containing package-level declarations
-//   that have snippets, and one containing all other spots
-// - keep the snippets in a separate table indexed by snippet index
-//   and store the snippet index in place of the line number in a SpotInfo
-//   (the line number for spots with snippets is stored in the snippet)
-// - at the end, create lists of alternative spellings for a given
-//   word
-//
-// Algorithm for full text index:
-// - concatenate all source code in a byte buffer (in memory)
-// - add the files to a file set in lockstep as they are added to the byte
-//   buffer such that a byte buffer offset corresponds to the Pos value for
-//   that file location
-// - create a suffix array from the concatenated sources
-//
-// String lookup in full text index:
-// - use the suffix array to lookup a string's offsets - the offsets
-//   correspond to the Pos values relative to the file set
-// - translate the Pos values back into file and line information and
-//   sort the result
-
-package godoc
-
-import (
-	"bufio"
-	"bytes"
-	"encoding/gob"
-	"errors"
-	"fmt"
-	"go/ast"
-	"go/doc"
-	"go/parser"
-	"go/token"
-	"index/suffixarray"
-	"io"
-	"log"
-	"os"
-	pathpkg "path"
-	"path/filepath"
-	"regexp"
-	"runtime"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-	"unicode"
-
-	"golang.org/x/website/cmd/golangorg/godoc/util"
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// ----------------------------------------------------------------------------
-// InterfaceSlice is a helper type for sorting interface
-// slices according to some slice-specific sort criteria.
-
-type comparer func(x, y interface{}) bool
-
-type interfaceSlice struct {
-	slice []interface{}
-	less  comparer
-}
-
-// ----------------------------------------------------------------------------
-// RunList
-
-// A RunList is a list of entries that can be sorted according to some
-// criteria. A RunList may be compressed by grouping "runs" of entries
-// which are equal (according to the sort criteria) into a new RunList of
-// runs. For instance, a RunList containing pairs (x, y) may be compressed
-// into a RunList containing pair runs (x, {y}) where each run consists of
-// a list of y's with the same x.
-type RunList []interface{}
-
-func (h RunList) sort(less comparer) {
-	sort.Sort(&interfaceSlice{h, less})
-}
-
-func (p *interfaceSlice) Len() int           { return len(p.slice) }
-func (p *interfaceSlice) Less(i, j int) bool { return p.less(p.slice[i], p.slice[j]) }
-func (p *interfaceSlice) Swap(i, j int)      { p.slice[i], p.slice[j] = p.slice[j], p.slice[i] }
-
-// Compress entries which are the same according to a sort criteria
-// (specified by less) into "runs".
-func (h RunList) reduce(less comparer, newRun func(h RunList) interface{}) RunList {
-	if len(h) == 0 {
-		return nil
-	}
-	// len(h) > 0
-
-	// create runs of entries with equal values
-	h.sort(less)
-
-	// for each run, make a new run object and collect them in a new RunList
-	var hh RunList
-	i, x := 0, h[0]
-	for j, y := range h {
-		if less(x, y) {
-			hh = append(hh, newRun(h[i:j]))
-			i, x = j, h[j] // start a new run
-		}
-	}
-	// add final run, if any
-	if i < len(h) {
-		hh = append(hh, newRun(h[i:]))
-	}
-
-	return hh
-}
-
-// ----------------------------------------------------------------------------
-// KindRun
-
-// Debugging support. Disable to see multiple entries per line.
-const removeDuplicates = true
-
-// A KindRun is a run of SpotInfos of the same kind in a given file.
-// The kind (3 bits) is stored in each SpotInfo element; to find the
-// kind of a KindRun, look at any of its elements.
-type KindRun []SpotInfo
-
-// KindRuns are sorted by line number or index. Since the isIndex bit
-// is always the same for all infos in one list we can compare lori's.
-func (k KindRun) Len() int           { return len(k) }
-func (k KindRun) Less(i, j int) bool { return k[i].Lori() < k[j].Lori() }
-func (k KindRun) Swap(i, j int)      { k[i], k[j] = k[j], k[i] }
-
-// FileRun contents are sorted by Kind for the reduction into KindRuns.
-func lessKind(x, y interface{}) bool { return x.(SpotInfo).Kind() < y.(SpotInfo).Kind() }
-
-// newKindRun allocates a new KindRun from the SpotInfo run h.
-func newKindRun(h RunList) interface{} {
-	run := make(KindRun, len(h))
-	for i, x := range h {
-		run[i] = x.(SpotInfo)
-	}
-
-	// Spots were sorted by file and kind to create this run.
-	// Within this run, sort them by line number or index.
-	sort.Sort(run)
-
-	if removeDuplicates {
-		// Since both the lori and kind field must be
-		// same for duplicates, and since the isIndex
-		// bit is always the same for all infos in one
-		// list we can simply compare the entire info.
-		k := 0
-		prev := SpotInfo(1<<32 - 1) // an unlikely value
-		for _, x := range run {
-			if x != prev {
-				run[k] = x
-				k++
-				prev = x
-			}
-		}
-		run = run[0:k]
-	}
-
-	return run
-}
-
-// ----------------------------------------------------------------------------
-// FileRun
-
-// A Pak describes a Go package.
-type Pak struct {
-	Path string // path of directory containing the package
-	Name string // package name as declared by package clause
-}
-
-// Paks are sorted by name (primary key) and by import path (secondary key).
-func (p *Pak) less(q *Pak) bool {
-	return p.Name < q.Name || p.Name == q.Name && p.Path < q.Path
-}
-
-// A File describes a Go file.
-type File struct {
-	Name string // directory-local file name
-	Pak  *Pak   // the package to which the file belongs
-}
-
-// Path returns the file path of f.
-func (f *File) Path() string {
-	return pathpkg.Join(f.Pak.Path, f.Name)
-}
-
-// A Spot describes a single occurrence of a word.
-type Spot struct {
-	File *File
-	Info SpotInfo
-}
-
-// A FileRun is a list of KindRuns belonging to the same file.
-type FileRun struct {
-	File   *File
-	Groups []KindRun
-}
-
-// Spots are sorted by file path for the reduction into FileRuns.
-func lessSpot(x, y interface{}) bool {
-	fx := x.(Spot).File
-	fy := y.(Spot).File
-	// same as "return fx.Path() < fy.Path()" but w/o computing the file path first
-	px := fx.Pak.Path
-	py := fy.Pak.Path
-	return px < py || px == py && fx.Name < fy.Name
-}
-
-// newFileRun allocates a new FileRun from the Spot run h.
-func newFileRun(h RunList) interface{} {
-	file := h[0].(Spot).File
-
-	// reduce the list of Spots into a list of KindRuns
-	h1 := make(RunList, len(h))
-	for i, x := range h {
-		h1[i] = x.(Spot).Info
-	}
-	h2 := h1.reduce(lessKind, newKindRun)
-
-	// create the FileRun
-	groups := make([]KindRun, len(h2))
-	for i, x := range h2 {
-		groups[i] = x.(KindRun)
-	}
-	return &FileRun{file, groups}
-}
-
-// ----------------------------------------------------------------------------
-// PakRun
-
-// A PakRun describes a run of *FileRuns of a package.
-type PakRun struct {
-	Pak   *Pak
-	Files []*FileRun
-}
-
-// Sorting support for files within a PakRun.
-func (p *PakRun) Len() int           { return len(p.Files) }
-func (p *PakRun) Less(i, j int) bool { return p.Files[i].File.Name < p.Files[j].File.Name }
-func (p *PakRun) Swap(i, j int)      { p.Files[i], p.Files[j] = p.Files[j], p.Files[i] }
-
-// FileRuns are sorted by package for the reduction into PakRuns.
-func lessFileRun(x, y interface{}) bool {
-	return x.(*FileRun).File.Pak.less(y.(*FileRun).File.Pak)
-}
-
-// newPakRun allocates a new PakRun from the *FileRun run h.
-func newPakRun(h RunList) interface{} {
-	pak := h[0].(*FileRun).File.Pak
-	files := make([]*FileRun, len(h))
-	for i, x := range h {
-		files[i] = x.(*FileRun)
-	}
-	run := &PakRun{pak, files}
-	sort.Sort(run) // files were sorted by package; sort them by file now
-	return run
-}
-
-// ----------------------------------------------------------------------------
-// HitList
-
-// A HitList describes a list of PakRuns.
-type HitList []*PakRun
-
-// PakRuns are sorted by package.
-func lessPakRun(x, y interface{}) bool { return x.(*PakRun).Pak.less(y.(*PakRun).Pak) }
-
-func reduce(h0 RunList) HitList {
-	// reduce a list of Spots into a list of FileRuns
-	h1 := h0.reduce(lessSpot, newFileRun)
-	// reduce a list of FileRuns into a list of PakRuns
-	h2 := h1.reduce(lessFileRun, newPakRun)
-	// sort the list of PakRuns by package
-	h2.sort(lessPakRun)
-	// create a HitList
-	h := make(HitList, len(h2))
-	for i, p := range h2 {
-		h[i] = p.(*PakRun)
-	}
-	return h
-}
-
-// filter returns a new HitList created by filtering
-// all PakRuns from h that have a matching pakname.
-func (h HitList) filter(pakname string) HitList {
-	var hh HitList
-	for _, p := range h {
-		if p.Pak.Name == pakname {
-			hh = append(hh, p)
-		}
-	}
-	return hh
-}
-
-// ----------------------------------------------------------------------------
-// AltWords
-
-type wordPair struct {
-	canon string // canonical word spelling (all lowercase)
-	alt   string // alternative spelling
-}
-
-// An AltWords describes a list of alternative spellings for a
-// canonical (all lowercase) spelling of a word.
-type AltWords struct {
-	Canon string   // canonical word spelling (all lowercase)
-	Alts  []string // alternative spelling for the same word
-}
-
-// wordPairs are sorted by their canonical spelling.
-func lessWordPair(x, y interface{}) bool { return x.(*wordPair).canon < y.(*wordPair).canon }
-
-// newAltWords allocates a new AltWords from the *wordPair run h.
-func newAltWords(h RunList) interface{} {
-	canon := h[0].(*wordPair).canon
-	alts := make([]string, len(h))
-	for i, x := range h {
-		alts[i] = x.(*wordPair).alt
-	}
-	return &AltWords{canon, alts}
-}
-
-func (a *AltWords) filter(s string) *AltWords {
-	var alts []string
-	for _, w := range a.Alts {
-		if w != s {
-			alts = append(alts, w)
-		}
-	}
-	if len(alts) > 0 {
-		return &AltWords{a.Canon, alts}
-	}
-	return nil
-}
-
-// Ident stores information about external identifiers in order to create
-// links to package documentation.
-type Ident struct {
-	Path    string // e.g. "net/http"
-	Package string // e.g. "http"
-	Name    string // e.g. "NewRequest"
-	Doc     string // e.g. "NewRequest returns a new Request..."
-}
-
-// byImportCount sorts the given slice of Idents by the import
-// counts of the packages to which they belong.
-type byImportCount struct {
-	Idents      []Ident
-	ImportCount map[string]int
-}
-
-func (ic byImportCount) Len() int {
-	return len(ic.Idents)
-}
-
-func (ic byImportCount) Less(i, j int) bool {
-	ri := ic.ImportCount[ic.Idents[i].Path]
-	rj := ic.ImportCount[ic.Idents[j].Path]
-	if ri == rj {
-		return ic.Idents[i].Path < ic.Idents[j].Path
-	}
-	return ri > rj
-}
-
-func (ic byImportCount) Swap(i, j int) {
-	ic.Idents[i], ic.Idents[j] = ic.Idents[j], ic.Idents[i]
-}
-
-func (ic byImportCount) String() string {
-	buf := bytes.NewBuffer([]byte("["))
-	for _, v := range ic.Idents {
-		buf.WriteString(fmt.Sprintf("\n\t%s, %s (%d)", v.Path, v.Name, ic.ImportCount[v.Path]))
-	}
-	buf.WriteString("\n]")
-	return buf.String()
-}
-
-// filter creates a new Ident list where the results match the given
-// package name.
-func (ic byImportCount) filter(pakname string) []Ident {
-	if ic.Idents == nil {
-		return nil
-	}
-	var res []Ident
-	for _, i := range ic.Idents {
-		if i.Package == pakname {
-			res = append(res, i)
-		}
-	}
-	return res
-}
-
-// top returns the top n identifiers.
-func (ic byImportCount) top(n int) []Ident {
-	if len(ic.Idents) > n {
-		return ic.Idents[:n]
-	}
-	return ic.Idents
-}
-
-// ----------------------------------------------------------------------------
-// Indexer
-
-type IndexResult struct {
-	Decls  RunList // package-level declarations (with snippets)
-	Others RunList // all other occurrences
-}
-
-// Statistics provides statistics information for an index.
-type Statistics struct {
-	Bytes int // total size of indexed source files
-	Files int // number of indexed source files
-	Lines int // number of lines (all files)
-	Words int // number of different identifiers
-	Spots int // number of identifier occurrences
-}
-
-// An Indexer maintains the data structures and provides the machinery
-// for indexing .go files under a file tree. It implements the path.Visitor
-// interface for walking file trees, and the ast.Visitor interface for
-// walking Go ASTs.
-type Indexer struct {
-	c          *Corpus
-	fset       *token.FileSet // file set for all indexed files
-	fsOpenGate chan bool      // send pre fs.Open; receive on close
-
-	mu            sync.Mutex              // guards all the following
-	sources       bytes.Buffer            // concatenated sources
-	strings       map[string]string       // interned string
-	packages      map[Pak]*Pak            // interned *Paks
-	words         map[string]*IndexResult // RunLists of Spots
-	snippets      []*Snippet              // indices are stored in SpotInfos
-	current       *token.File             // last file added to file set
-	file          *File                   // AST for current file
-	decl          ast.Decl                // AST for current decl
-	stats         Statistics
-	throttle      *util.Throttle
-	importCount   map[string]int                 // package path ("net/http") => count
-	packagePath   map[string]map[string]bool     // "template" => "text/template" => true
-	exports       map[string]map[string]SpotKind // "net/http" => "ListenAndServe" => FuncDecl
-	curPkgExports map[string]SpotKind
-	idents        map[SpotKind]map[string][]Ident // kind => name => list of Idents
-}
-
-func (x *Indexer) intern(s string) string {
-	if s, ok := x.strings[s]; ok {
-		return s
-	}
-	x.strings[s] = s
-	return s
-}
-
-func (x *Indexer) lookupPackage(path, name string) *Pak {
-	// In the source directory tree, more than one package may
-	// live in the same directory. For the packages map, construct
-	// a key that includes both the directory path and the package
-	// name.
-	key := Pak{Path: x.intern(path), Name: x.intern(name)}
-	pak := x.packages[key]
-	if pak == nil {
-		pak = &key
-		x.packages[key] = pak
-	}
-	return pak
-}
-
-func (x *Indexer) addSnippet(s *Snippet) int {
-	index := len(x.snippets)
-	x.snippets = append(x.snippets, s)
-	return index
-}
-
-func (x *Indexer) visitIdent(kind SpotKind, id *ast.Ident) {
-	if id == nil {
-		return
-	}
-	name := x.intern(id.Name)
-
-	switch kind {
-	case TypeDecl, FuncDecl, ConstDecl, VarDecl:
-		x.curPkgExports[name] = kind
-	}
-
-	lists, found := x.words[name]
-	if !found {
-		lists = new(IndexResult)
-		x.words[name] = lists
-	}
-
-	if kind == Use || x.decl == nil {
-		if x.c.IndexGoCode {
-			// not a declaration or no snippet required
-			info := makeSpotInfo(kind, x.current.Line(id.Pos()), false)
-			lists.Others = append(lists.Others, Spot{x.file, info})
-		}
-	} else {
-		// a declaration with snippet
-		index := x.addSnippet(NewSnippet(x.fset, x.decl, id))
-		info := makeSpotInfo(kind, index, true)
-		lists.Decls = append(lists.Decls, Spot{x.file, info})
-	}
-
-	x.stats.Spots++
-}
-
-func (x *Indexer) visitFieldList(kind SpotKind, flist *ast.FieldList) {
-	for _, f := range flist.List {
-		x.decl = nil // no snippets for fields
-		for _, name := range f.Names {
-			x.visitIdent(kind, name)
-		}
-		ast.Walk(x, f.Type)
-		// ignore tag - not indexed at the moment
-	}
-}
-
-func (x *Indexer) visitSpec(kind SpotKind, spec ast.Spec) {
-	switch n := spec.(type) {
-	case *ast.ImportSpec:
-		x.visitIdent(ImportDecl, n.Name)
-		if n.Path != nil {
-			if imp, err := strconv.Unquote(n.Path.Value); err == nil {
-				x.importCount[x.intern(imp)]++
-			}
-		}
-
-	case *ast.ValueSpec:
-		for _, n := range n.Names {
-			x.visitIdent(kind, n)
-		}
-		ast.Walk(x, n.Type)
-		for _, v := range n.Values {
-			ast.Walk(x, v)
-		}
-
-	case *ast.TypeSpec:
-		x.visitIdent(TypeDecl, n.Name)
-		ast.Walk(x, n.Type)
-	}
-}
-
-func (x *Indexer) visitGenDecl(decl *ast.GenDecl) {
-	kind := VarDecl
-	if decl.Tok == token.CONST {
-		kind = ConstDecl
-	}
-	x.decl = decl
-	for _, s := range decl.Specs {
-		x.visitSpec(kind, s)
-	}
-}
-
-func (x *Indexer) Visit(node ast.Node) ast.Visitor {
-	switch n := node.(type) {
-	case nil:
-		// nothing to do
-
-	case *ast.Ident:
-		x.visitIdent(Use, n)
-
-	case *ast.FieldList:
-		x.visitFieldList(VarDecl, n)
-
-	case *ast.InterfaceType:
-		x.visitFieldList(MethodDecl, n.Methods)
-
-	case *ast.DeclStmt:
-		// local declarations should only be *ast.GenDecls;
-		// ignore incorrect ASTs
-		if decl, ok := n.Decl.(*ast.GenDecl); ok {
-			x.decl = nil // no snippets for local declarations
-			x.visitGenDecl(decl)
-		}
-
-	case *ast.GenDecl:
-		x.decl = n
-		x.visitGenDecl(n)
-
-	case *ast.FuncDecl:
-		kind := FuncDecl
-		if n.Recv != nil {
-			kind = MethodDecl
-			ast.Walk(x, n.Recv)
-		}
-		x.decl = n
-		x.visitIdent(kind, n.Name)
-		ast.Walk(x, n.Type)
-		if n.Body != nil {
-			ast.Walk(x, n.Body)
-		}
-
-	case *ast.File:
-		x.decl = nil
-		x.visitIdent(PackageClause, n.Name)
-		for _, d := range n.Decls {
-			ast.Walk(x, d)
-		}
-
-	default:
-		return x
-	}
-
-	return nil
-}
-
-// addFile adds a file to the index if possible and returns the file set file
-// and the file's AST if it was successfully parsed as a Go file. If addFile
-// failed (that is, if the file was not added), it returns file == nil.
-func (x *Indexer) addFile(f vfs.ReadSeekCloser, filename string, goFile bool) (file *token.File, ast *ast.File) {
-	defer f.Close()
-
-	// The file set's base offset and x.sources size must be in lock-step;
-	// this permits the direct mapping of suffix array lookup results to
-	// to corresponding Pos values.
-	//
-	// When a file is added to the file set, its offset base increases by
-	// the size of the file + 1; and the initial base offset is 1. Add an
-	// extra byte to the sources here.
-	x.sources.WriteByte(0)
-
-	// If the sources length doesn't match the file set base at this point
-	// the file set implementation changed or we have another error.
-	base := x.fset.Base()
-	if x.sources.Len() != base {
-		panic("internal error: file base incorrect")
-	}
-
-	// append file contents (src) to x.sources
-	if _, err := x.sources.ReadFrom(f); err == nil {
-		src := x.sources.Bytes()[base:]
-
-		if goFile {
-			// parse the file and in the process add it to the file set
-			if ast, err = parser.ParseFile(x.fset, filename, src, parser.ParseComments); err == nil {
-				file = x.fset.File(ast.Pos()) // ast.Pos() is inside the file
-				return
-			}
-			// file has parse errors, and the AST may be incorrect -
-			// set lines information explicitly and index as ordinary
-			// text file (cannot fall through to the text case below
-			// because the file has already been added to the file set
-			// by the parser)
-			file = x.fset.File(token.Pos(base)) // token.Pos(base) is inside the file
-			file.SetLinesForContent(src)
-			ast = nil
-			return
-		}
-
-		if util.IsText(src) {
-			// only add the file to the file set (for the full text index)
-			file = x.fset.AddFile(filename, x.fset.Base(), len(src))
-			file.SetLinesForContent(src)
-			return
-		}
-	}
-
-	// discard possibly added data
-	x.sources.Truncate(base - 1) // -1 to remove added byte 0 since no file was added
-	return
-}
-
-// Design note: Using an explicit white list of permitted files for indexing
-// makes sure that the important files are included and massively reduces the
-// number of files to index. The advantage over a blacklist is that unexpected
-// (non-blacklisted) files won't suddenly explode the index.
-
-// Files are whitelisted if they have a file name or extension
-// present as key in whitelisted.
-var whitelisted = map[string]bool{
-	".bash":        true,
-	".c":           true,
-	".cc":          true,
-	".cpp":         true,
-	".cxx":         true,
-	".css":         true,
-	".go":          true,
-	".goc":         true,
-	".h":           true,
-	".hh":          true,
-	".hpp":         true,
-	".hxx":         true,
-	".html":        true,
-	".js":          true,
-	".out":         true,
-	".py":          true,
-	".s":           true,
-	".sh":          true,
-	".txt":         true,
-	".xml":         true,
-	"AUTHORS":      true,
-	"CONTRIBUTORS": true,
-	"LICENSE":      true,
-	"Makefile":     true,
-	"PATENTS":      true,
-	"README":       true,
-}
-
-// isWhitelisted returns true if a file is on the list
-// of "permitted" files for indexing. The filename must
-// be the directory-local name of the file.
-func isWhitelisted(filename string) bool {
-	key := pathpkg.Ext(filename)
-	if key == "" {
-		// file has no extension - use entire filename
-		key = filename
-	}
-	return whitelisted[key]
-}
-
-func (x *Indexer) indexDocs(dirname string, filename string, astFile *ast.File) {
-	pkgName := x.intern(astFile.Name.Name)
-	if pkgName == "main" {
-		return
-	}
-	pkgPath := x.intern(strings.TrimPrefix(strings.TrimPrefix(dirname, "/src/"), "pkg/"))
-	astPkg := ast.Package{
-		Name: pkgName,
-		Files: map[string]*ast.File{
-			filename: astFile,
-		},
-	}
-	var m doc.Mode
-	docPkg := doc.New(&astPkg, dirname, m)
-	addIdent := func(sk SpotKind, name string, docstr string) {
-		if x.idents[sk] == nil {
-			x.idents[sk] = make(map[string][]Ident)
-		}
-		name = x.intern(name)
-		x.idents[sk][name] = append(x.idents[sk][name], Ident{
-			Path:    pkgPath,
-			Package: pkgName,
-			Name:    name,
-			Doc:     doc.Synopsis(docstr),
-		})
-	}
-
-	if x.idents[PackageClause] == nil {
-		x.idents[PackageClause] = make(map[string][]Ident)
-	}
-	// List of words under which the package identifier will be stored.
-	// This includes the package name and the components of the directory
-	// in which it resides.
-	words := strings.Split(pathpkg.Dir(pkgPath), "/")
-	if words[0] == "." {
-		words = []string{}
-	}
-	name := x.intern(docPkg.Name)
-	synopsis := doc.Synopsis(docPkg.Doc)
-	words = append(words, name)
-	pkgIdent := Ident{
-		Path:    pkgPath,
-		Package: pkgName,
-		Name:    name,
-		Doc:     synopsis,
-	}
-	for _, word := range words {
-		word = x.intern(word)
-		found := false
-		pkgs := x.idents[PackageClause][word]
-		for i, p := range pkgs {
-			if p.Path == pkgPath {
-				if docPkg.Doc != "" {
-					p.Doc = synopsis
-					pkgs[i] = p
-				}
-				found = true
-				break
-			}
-		}
-		if !found {
-			x.idents[PackageClause][word] = append(x.idents[PackageClause][word], pkgIdent)
-		}
-	}
-
-	for _, c := range docPkg.Consts {
-		for _, name := range c.Names {
-			addIdent(ConstDecl, name, c.Doc)
-		}
-	}
-	for _, t := range docPkg.Types {
-		addIdent(TypeDecl, t.Name, t.Doc)
-		for _, c := range t.Consts {
-			for _, name := range c.Names {
-				addIdent(ConstDecl, name, c.Doc)
-			}
-		}
-		for _, v := range t.Vars {
-			for _, name := range v.Names {
-				addIdent(VarDecl, name, v.Doc)
-			}
-		}
-		for _, f := range t.Funcs {
-			addIdent(FuncDecl, f.Name, f.Doc)
-		}
-		for _, f := range t.Methods {
-			addIdent(MethodDecl, f.Name, f.Doc)
-			// Change the name of methods to be "<typename>.<methodname>".
-			// They will still be indexed as <methodname>.
-			idents := x.idents[MethodDecl][f.Name]
-			idents[len(idents)-1].Name = x.intern(t.Name + "." + f.Name)
-		}
-	}
-	for _, v := range docPkg.Vars {
-		for _, name := range v.Names {
-			addIdent(VarDecl, name, v.Doc)
-		}
-	}
-	for _, f := range docPkg.Funcs {
-		addIdent(FuncDecl, f.Name, f.Doc)
-	}
-}
-
-func (x *Indexer) indexGoFile(dirname string, filename string, file *token.File, astFile *ast.File) {
-	pkgName := astFile.Name.Name
-
-	if x.c.IndexGoCode {
-		x.current = file
-		pak := x.lookupPackage(dirname, pkgName)
-		x.file = &File{filename, pak}
-		ast.Walk(x, astFile)
-	}
-
-	if x.c.IndexDocs {
-		// Test files are already filtered out in visitFile if IndexGoCode and
-		// IndexFullText are false.  Otherwise, check here.
-		isTestFile := (x.c.IndexGoCode || x.c.IndexFullText) &&
-			(strings.HasSuffix(filename, "_test.go") || strings.HasPrefix(dirname, "/test/"))
-		if !isTestFile {
-			x.indexDocs(dirname, filename, astFile)
-		}
-	}
-
-	ppKey := x.intern(pkgName)
-	if _, ok := x.packagePath[ppKey]; !ok {
-		x.packagePath[ppKey] = make(map[string]bool)
-	}
-	pkgPath := x.intern(strings.TrimPrefix(strings.TrimPrefix(dirname, "/src/"), "pkg/"))
-	x.packagePath[ppKey][pkgPath] = true
-
-	// Merge in exported symbols found walking this file into
-	// the map for that package.
-	if len(x.curPkgExports) > 0 {
-		dest, ok := x.exports[pkgPath]
-		if !ok {
-			dest = make(map[string]SpotKind)
-			x.exports[pkgPath] = dest
-		}
-		for k, v := range x.curPkgExports {
-			dest[k] = v
-		}
-	}
-}
-
-func (x *Indexer) visitFile(dirname string, fi os.FileInfo) {
-	if fi.IsDir() || !x.c.IndexEnabled {
-		return
-	}
-
-	filename := pathpkg.Join(dirname, fi.Name())
-	goFile := isGoFile(fi)
-
-	switch {
-	case x.c.IndexFullText:
-		if !isWhitelisted(fi.Name()) {
-			return
-		}
-	case x.c.IndexGoCode:
-		if !goFile {
-			return
-		}
-	case x.c.IndexDocs:
-		if !goFile ||
-			strings.HasSuffix(fi.Name(), "_test.go") ||
-			strings.HasPrefix(dirname, "/test/") {
-			return
-		}
-	default:
-		// No indexing turned on.
-		return
-	}
-
-	x.fsOpenGate <- true
-	defer func() { <-x.fsOpenGate }()
-
-	// open file
-	f, err := x.c.fs.Open(filename)
-	if err != nil {
-		return
-	}
-
-	x.mu.Lock()
-	defer x.mu.Unlock()
-
-	x.throttle.Throttle()
-
-	x.curPkgExports = make(map[string]SpotKind)
-	file, fast := x.addFile(f, filename, goFile)
-	if file == nil {
-		return // addFile failed
-	}
-
-	if fast != nil {
-		x.indexGoFile(dirname, fi.Name(), file, fast)
-	}
-
-	// update statistics
-	x.stats.Bytes += file.Size()
-	x.stats.Files++
-	x.stats.Lines += file.LineCount()
-}
-
-// indexOptions contains information that affects the contents of an index.
-type indexOptions struct {
-	// Docs provides documentation search results.
-	// It is only consulted if IndexEnabled is true.
-	// The default values is true.
-	Docs bool
-
-	// GoCode provides Go source code search results.
-	// It is only consulted if IndexEnabled is true.
-	// The default values is true.
-	GoCode bool
-
-	// FullText provides search results from all files.
-	// It is only consulted if IndexEnabled is true.
-	// The default values is true.
-	FullText bool
-
-	// MaxResults optionally specifies the maximum results for indexing.
-	// The default is 1000.
-	MaxResults int
-}
-
-// ----------------------------------------------------------------------------
-// Index
-
-type LookupResult struct {
-	Decls  HitList // package-level declarations (with snippets)
-	Others HitList // all other occurrences
-}
-
-type Index struct {
-	fset        *token.FileSet           // file set used during indexing; nil if no textindex
-	suffixes    *suffixarray.Index       // suffixes for concatenated sources; nil if no textindex
-	words       map[string]*LookupResult // maps words to hit lists
-	alts        map[string]*AltWords     // maps canonical(words) to lists of alternative spellings
-	snippets    []*Snippet               // all snippets, indexed by snippet index
-	stats       Statistics
-	importCount map[string]int                 // package path ("net/http") => count
-	packagePath map[string]map[string]bool     // "template" => "text/template" => true
-	exports     map[string]map[string]SpotKind // "net/http" => "ListenAndServe" => FuncDecl
-	idents      map[SpotKind]map[string][]Ident
-	opts        indexOptions
-}
-
-func canonical(w string) string { return strings.ToLower(w) }
-
-// Somewhat arbitrary, but I figure low enough to not hurt disk-based filesystems
-// consuming file descriptors, where some systems have low 256 or 512 limits.
-// Go should have a built-in way to cap fd usage under the ulimit.
-const (
-	maxOpenFiles = 200
-	maxOpenDirs  = 50
-)
-
-func (c *Corpus) throttle() float64 {
-	if c.IndexThrottle <= 0 {
-		return 0.9
-	}
-	if c.IndexThrottle > 1.0 {
-		return 1.0
-	}
-	return c.IndexThrottle
-}
-
-// NewIndex creates a new index for the .go files provided by the corpus.
-func (c *Corpus) NewIndex() *Index {
-	// initialize Indexer
-	// (use some reasonably sized maps to start)
-	x := &Indexer{
-		c:           c,
-		fset:        token.NewFileSet(),
-		fsOpenGate:  make(chan bool, maxOpenFiles),
-		strings:     make(map[string]string),
-		packages:    make(map[Pak]*Pak, 256),
-		words:       make(map[string]*IndexResult, 8192),
-		throttle:    util.NewThrottle(c.throttle(), 100*time.Millisecond), // run at least 0.1s at a time
-		importCount: make(map[string]int),
-		packagePath: make(map[string]map[string]bool),
-		exports:     make(map[string]map[string]SpotKind),
-		idents:      make(map[SpotKind]map[string][]Ident, 4),
-	}
-
-	// index all files in the directories given by dirnames
-	var wg sync.WaitGroup // outstanding ReadDir + visitFile
-	dirGate := make(chan bool, maxOpenDirs)
-	for dirname := range c.fsDirnames() {
-		if c.IndexDirectory != nil && !c.IndexDirectory(dirname) {
-			continue
-		}
-		dirGate <- true
-		wg.Add(1)
-		go func(dirname string) {
-			defer func() { <-dirGate }()
-			defer wg.Done()
-
-			list, err := c.fs.ReadDir(dirname)
-			if err != nil {
-				log.Printf("ReadDir(%q): %v; skipping directory", dirname, err)
-				return // ignore this directory
-			}
-			for _, fi := range list {
-				wg.Add(1)
-				go func(fi os.FileInfo) {
-					defer wg.Done()
-					x.visitFile(dirname, fi)
-				}(fi)
-			}
-		}(dirname)
-	}
-	wg.Wait()
-
-	if !c.IndexFullText {
-		// the file set, the current file, and the sources are
-		// not needed after indexing if no text index is built -
-		// help GC and clear them
-		x.fset = nil
-		x.sources.Reset()
-		x.current = nil // contains reference to fset!
-	}
-
-	// for each word, reduce the RunLists into a LookupResult;
-	// also collect the word with its canonical spelling in a
-	// word list for later computation of alternative spellings
-	words := make(map[string]*LookupResult)
-	var wlist RunList
-	for w, h := range x.words {
-		decls := reduce(h.Decls)
-		others := reduce(h.Others)
-		words[w] = &LookupResult{
-			Decls:  decls,
-			Others: others,
-		}
-		wlist = append(wlist, &wordPair{canonical(w), w})
-		x.throttle.Throttle()
-	}
-	x.stats.Words = len(words)
-
-	// reduce the word list {canonical(w), w} into
-	// a list of AltWords runs {canonical(w), {w}}
-	alist := wlist.reduce(lessWordPair, newAltWords)
-
-	// convert alist into a map of alternative spellings
-	alts := make(map[string]*AltWords)
-	for i := 0; i < len(alist); i++ {
-		a := alist[i].(*AltWords)
-		alts[a.Canon] = a
-	}
-
-	// create text index
-	var suffixes *suffixarray.Index
-	if c.IndexFullText {
-		suffixes = suffixarray.New(x.sources.Bytes())
-	}
-
-	// sort idents by the number of imports of their respective packages
-	for _, idMap := range x.idents {
-		for _, ir := range idMap {
-			sort.Sort(byImportCount{ir, x.importCount})
-		}
-	}
-
-	return &Index{
-		fset:        x.fset,
-		suffixes:    suffixes,
-		words:       words,
-		alts:        alts,
-		snippets:    x.snippets,
-		stats:       x.stats,
-		importCount: x.importCount,
-		packagePath: x.packagePath,
-		exports:     x.exports,
-		idents:      x.idents,
-		opts: indexOptions{
-			Docs:       x.c.IndexDocs,
-			GoCode:     x.c.IndexGoCode,
-			FullText:   x.c.IndexFullText,
-			MaxResults: x.c.MaxResults,
-		},
-	}
-}
-
-var ErrFileIndexVersion = errors.New("file index version out of date")
-
-const fileIndexVersion = 3
-
-// fileIndex is the subset of Index that's gob-encoded for use by
-// Index.Write and Index.Read.
-type fileIndex struct {
-	Version     int
-	Words       map[string]*LookupResult
-	Alts        map[string]*AltWords
-	Snippets    []*Snippet
-	Fulltext    bool
-	Stats       Statistics
-	ImportCount map[string]int
-	PackagePath map[string]map[string]bool
-	Exports     map[string]map[string]SpotKind
-	Idents      map[SpotKind]map[string][]Ident
-	Opts        indexOptions
-}
-
-func (x *fileIndex) Write(w io.Writer) error {
-	return gob.NewEncoder(w).Encode(x)
-}
-
-func (x *fileIndex) Read(r io.Reader) error {
-	return gob.NewDecoder(r).Decode(x)
-}
-
-// WriteTo writes the index x to w.
-func (x *Index) WriteTo(w io.Writer) (n int64, err error) {
-	w = countingWriter{&n, w}
-	fulltext := false
-	if x.suffixes != nil {
-		fulltext = true
-	}
-	fx := fileIndex{
-		Version:     fileIndexVersion,
-		Words:       x.words,
-		Alts:        x.alts,
-		Snippets:    x.snippets,
-		Fulltext:    fulltext,
-		Stats:       x.stats,
-		ImportCount: x.importCount,
-		PackagePath: x.packagePath,
-		Exports:     x.exports,
-		Idents:      x.idents,
-		Opts:        x.opts,
-	}
-	if err := fx.Write(w); err != nil {
-		return 0, err
-	}
-	if fulltext {
-		encode := func(x interface{}) error {
-			return gob.NewEncoder(w).Encode(x)
-		}
-		if err := x.fset.Write(encode); err != nil {
-			return 0, err
-		}
-		if err := x.suffixes.Write(w); err != nil {
-			return 0, err
-		}
-	}
-	return n, nil
-}
-
-// ReadFrom reads the index from r into x; x must not be nil.
-// If r does not also implement io.ByteReader, it will be wrapped in a bufio.Reader.
-// If the index is from an old version, the error is ErrFileIndexVersion.
-func (x *Index) ReadFrom(r io.Reader) (n int64, err error) {
-	// We use the ability to read bytes as a plausible surrogate for buffering.
-	if _, ok := r.(io.ByteReader); !ok {
-		r = bufio.NewReader(r)
-	}
-	r = countingReader{&n, r.(byteReader)}
-	var fx fileIndex
-	if err := fx.Read(r); err != nil {
-		return n, err
-	}
-	if fx.Version != fileIndexVersion {
-		return 0, ErrFileIndexVersion
-	}
-	x.words = fx.Words
-	x.alts = fx.Alts
-	x.snippets = fx.Snippets
-	x.stats = fx.Stats
-	x.importCount = fx.ImportCount
-	x.packagePath = fx.PackagePath
-	x.exports = fx.Exports
-	x.idents = fx.Idents
-	x.opts = fx.Opts
-	if fx.Fulltext {
-		x.fset = token.NewFileSet()
-		decode := func(x interface{}) error {
-			return gob.NewDecoder(r).Decode(x)
-		}
-		if err := x.fset.Read(decode); err != nil {
-			return n, err
-		}
-		x.suffixes = new(suffixarray.Index)
-		if err := x.suffixes.Read(r); err != nil {
-			return n, err
-		}
-	}
-	return n, nil
-}
-
-// Stats returns index statistics.
-func (x *Index) Stats() Statistics {
-	return x.stats
-}
-
-// ImportCount returns a map from import paths to how many times they were seen.
-func (x *Index) ImportCount() map[string]int {
-	return x.importCount
-}
-
-// PackagePath returns a map from short package name to a set
-// of full package path names that use that short package name.
-func (x *Index) PackagePath() map[string]map[string]bool {
-	return x.packagePath
-}
-
-// Exports returns a map from full package path to exported
-// symbol name to its type.
-func (x *Index) Exports() map[string]map[string]SpotKind {
-	return x.exports
-}
-
-// Idents returns a map from identifier type to exported
-// symbol name to the list of identifiers matching that name.
-func (x *Index) Idents() map[SpotKind]map[string][]Ident {
-	return x.idents
-}
-
-func (x *Index) lookupWord(w string) (match *LookupResult, alt *AltWords) {
-	match = x.words[w]
-	alt = x.alts[canonical(w)]
-	// remove current spelling from alternatives
-	// (if there is no match, the alternatives do
-	// not contain the current spelling)
-	if match != nil && alt != nil {
-		alt = alt.filter(w)
-	}
-	return
-}
-
-// isIdentifier reports whether s is a Go identifier.
-func isIdentifier(s string) bool {
-	for i, ch := range s {
-		if unicode.IsLetter(ch) || ch == '_' || i > 0 && unicode.IsDigit(ch) {
-			continue
-		}
-		return false
-	}
-	return len(s) > 0
-}
-
-// For a given query, which is either a single identifier or a qualified
-// identifier, Lookup returns a SearchResult containing packages, a LookupResult, a
-// list of alternative spellings, and identifiers, if any. Any and all results
-// may be nil.  If the query syntax is wrong, an error is reported.
-func (x *Index) Lookup(query string) (*SearchResult, error) {
-	ss := strings.Split(query, ".")
-
-	// check query syntax
-	for _, s := range ss {
-		if !isIdentifier(s) {
-			return nil, errors.New("all query parts must be identifiers")
-		}
-	}
-	rslt := &SearchResult{
-		Query:  query,
-		Idents: make(map[SpotKind][]Ident, 5),
-	}
-	// handle simple and qualified identifiers
-	switch len(ss) {
-	case 1:
-		ident := ss[0]
-		rslt.Hit, rslt.Alt = x.lookupWord(ident)
-		if rslt.Hit != nil {
-			// found a match - filter packages with same name
-			// for the list of packages called ident, if any
-			rslt.Pak = rslt.Hit.Others.filter(ident)
-		}
-		for k, v := range x.idents {
-			const rsltLimit = 50
-			ids := byImportCount{v[ident], x.importCount}
-			rslt.Idents[k] = ids.top(rsltLimit)
-		}
-
-	case 2:
-		pakname, ident := ss[0], ss[1]
-		rslt.Hit, rslt.Alt = x.lookupWord(ident)
-		if rslt.Hit != nil {
-			// found a match - filter by package name
-			// (no paks - package names are not qualified)
-			decls := rslt.Hit.Decls.filter(pakname)
-			others := rslt.Hit.Others.filter(pakname)
-			rslt.Hit = &LookupResult{decls, others}
-		}
-		for k, v := range x.idents {
-			ids := byImportCount{v[ident], x.importCount}
-			rslt.Idents[k] = ids.filter(pakname)
-		}
-
-	default:
-		return nil, errors.New("query is not a (qualified) identifier")
-	}
-
-	return rslt, nil
-}
-
-func (x *Index) Snippet(i int) *Snippet {
-	// handle illegal snippet indices gracefully
-	if 0 <= i && i < len(x.snippets) {
-		return x.snippets[i]
-	}
-	return nil
-}
-
-type positionList []struct {
-	filename string
-	line     int
-}
-
-func (list positionList) Len() int           { return len(list) }
-func (list positionList) Less(i, j int) bool { return list[i].filename < list[j].filename }
-func (list positionList) Swap(i, j int)      { list[i], list[j] = list[j], list[i] }
-
-// unique returns the list sorted and with duplicate entries removed
-func unique(list []int) []int {
-	sort.Ints(list)
-	var last int
-	i := 0
-	for _, x := range list {
-		if i == 0 || x != last {
-			last = x
-			list[i] = x
-			i++
-		}
-	}
-	return list[0:i]
-}
-
-// A FileLines value specifies a file and line numbers within that file.
-type FileLines struct {
-	Filename string
-	Lines    []int
-}
-
-// LookupRegexp returns the number of matches and the matches where a regular
-// expression r is found in the full text index. At most n matches are
-// returned (thus found <= n).
-//
-func (x *Index) LookupRegexp(r *regexp.Regexp, n int) (found int, result []FileLines) {
-	if x.suffixes == nil || n <= 0 {
-		return
-	}
-	// n > 0
-
-	var list positionList
-	// FindAllIndex may returns matches that span across file boundaries.
-	// Such matches are unlikely, buf after eliminating them we may end up
-	// with fewer than n matches. If we don't have enough at the end, redo
-	// the search with an increased value n1, but only if FindAllIndex
-	// returned all the requested matches in the first place (if it
-	// returned fewer than that there cannot be more).
-	for n1 := n; found < n; n1 += n - found {
-		found = 0
-		matches := x.suffixes.FindAllIndex(r, n1)
-		// compute files, exclude matches that span file boundaries,
-		// and map offsets to file-local offsets
-		list = make(positionList, len(matches))
-		for _, m := range matches {
-			// by construction, an offset corresponds to the Pos value
-			// for the file set - use it to get the file and line
-			p := token.Pos(m[0])
-			if file := x.fset.File(p); file != nil {
-				if base := file.Base(); base <= m[1] && m[1] <= base+file.Size() {
-					// match [m[0], m[1]) is within the file boundaries
-					list[found].filename = file.Name()
-					list[found].line = file.Line(p)
-					found++
-				}
-			}
-		}
-		if found == n || len(matches) < n1 {
-			// found all matches or there's no chance to find more
-			break
-		}
-	}
-	list = list[0:found]
-	sort.Sort(list) // sort by filename
-
-	// collect matches belonging to the same file
-	var last string
-	var lines []int
-	addLines := func() {
-		if len(lines) > 0 {
-			// remove duplicate lines
-			result = append(result, FileLines{last, unique(lines)})
-			lines = nil
-		}
-	}
-	for _, m := range list {
-		if m.filename != last {
-			addLines()
-			last = m.filename
-		}
-		lines = append(lines, m.line)
-	}
-	addLines()
-
-	return
-}
-
-// InvalidateIndex should be called whenever any of the file systems
-// under godoc's observation change so that the indexer is kicked on.
-func (c *Corpus) invalidateIndex() {
-	c.fsModified.Set(nil)
-	c.refreshMetadata()
-}
-
-// feedDirnames feeds the directory names of all directories
-// under the file system given by root to channel c.
-//
-func (c *Corpus) feedDirnames(ch chan<- string) {
-	if dir, _ := c.fsTree.Get(); dir != nil {
-		for d := range dir.(*Directory).iter(false) {
-			ch <- d.Path
-		}
-	}
-}
-
-// fsDirnames() returns a channel sending all directory names
-// of all the file systems under godoc's observation.
-//
-func (c *Corpus) fsDirnames() <-chan string {
-	ch := make(chan string, 256) // buffered for fewer context switches
-	go func() {
-		c.feedDirnames(ch)
-		close(ch)
-	}()
-	return ch
-}
-
-// CompatibleWith reports whether the Index x is compatible with the corpus
-// indexing options set in c.
-func (x *Index) CompatibleWith(c *Corpus) bool {
-	return x.opts.Docs == c.IndexDocs &&
-		x.opts.GoCode == c.IndexGoCode &&
-		x.opts.FullText == c.IndexFullText &&
-		x.opts.MaxResults == c.MaxResults
-}
-
-func (c *Corpus) readIndex(filenames string) error {
-	matches, err := filepath.Glob(filenames)
-	if err != nil {
-		return err
-	} else if matches == nil {
-		return fmt.Errorf("no index files match %q", filenames)
-	}
-	sort.Strings(matches) // make sure files are in the right order
-	files := make([]io.Reader, 0, len(matches))
-	for _, filename := range matches {
-		f, err := os.Open(filename)
-		if err != nil {
-			return err
-		}
-		defer f.Close()
-		files = append(files, f)
-	}
-	return c.ReadIndexFrom(io.MultiReader(files...))
-}
-
-// ReadIndexFrom sets the current index from the serialized version found in r.
-func (c *Corpus) ReadIndexFrom(r io.Reader) error {
-	x := new(Index)
-	if _, err := x.ReadFrom(r); err != nil {
-		return err
-	}
-	if !x.CompatibleWith(c) {
-		return fmt.Errorf("index file options are incompatible: %v", x.opts)
-	}
-	c.searchIndex.Set(x)
-	return nil
-}
-
-func (c *Corpus) UpdateIndex() {
-	if c.Verbose {
-		log.Printf("updating index...")
-	}
-	start := time.Now()
-	index := c.NewIndex()
-	stop := time.Now()
-	c.searchIndex.Set(index)
-	if c.Verbose {
-		secs := stop.Sub(start).Seconds()
-		stats := index.Stats()
-		log.Printf("index updated (%gs, %d bytes of source, %d files, %d lines, %d unique words, %d spots)",
-			secs, stats.Bytes, stats.Files, stats.Lines, stats.Words, stats.Spots)
-	}
-	memstats := new(runtime.MemStats)
-	runtime.ReadMemStats(memstats)
-	if c.Verbose {
-		log.Printf("before GC: bytes = %d footprint = %d", memstats.HeapAlloc, memstats.Sys)
-	}
-	runtime.GC()
-	runtime.ReadMemStats(memstats)
-	if c.Verbose {
-		log.Printf("after  GC: bytes = %d footprint = %d", memstats.HeapAlloc, memstats.Sys)
-	}
-}
-
-// RunIndexer runs forever, indexing.
-func (c *Corpus) RunIndexer() {
-	// initialize the index from disk if possible
-	if c.IndexFiles != "" {
-		c.initFSTree()
-		if err := c.readIndex(c.IndexFiles); err != nil {
-			log.Printf("error reading index from file %s: %v", c.IndexFiles, err)
-		}
-		return
-	}
-
-	// Repeatedly update the package directory tree and index.
-	for {
-		c.initFSTree()
-		c.UpdateIndex()
-		if c.IndexInterval < 0 {
-			return
-		}
-		delay := 5 * time.Minute // by default, reindex every 5 minutes
-		if c.IndexInterval > 0 {
-			delay = c.IndexInterval
-		}
-		time.Sleep(delay)
-	}
-}
-
-type countingWriter struct {
-	n *int64
-	w io.Writer
-}
-
-func (c countingWriter) Write(p []byte) (n int, err error) {
-	n, err = c.w.Write(p)
-	*c.n += int64(n)
-	return
-}
-
-type byteReader interface {
-	io.Reader
-	io.ByteReader
-}
-
-type countingReader struct {
-	n *int64
-	r byteReader
-}
-
-func (c countingReader) Read(p []byte) (n int, err error) {
-	n, err = c.r.Read(p)
-	*c.n += int64(n)
-	return
-}
-
-func (c countingReader) ReadByte() (b byte, err error) {
-	b, err = c.r.ReadByte()
-	*c.n += 1
-	return
-}
diff --git a/cmd/golangorg/godoc/index_test.go b/cmd/golangorg/godoc/index_test.go
deleted file mode 100644
index 5e1d64b..0000000
--- a/cmd/golangorg/godoc/index_test.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"bytes"
-	"reflect"
-	"sort"
-	"strings"
-	"testing"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs/mapfs"
-)
-
-func newCorpus(t *testing.T) *Corpus {
-	c := NewCorpus(mapfs.New(map[string]string{
-		"src/foo/foo.go": `// Package foo is an example.
-package foo
-
-import "bar"
-
-const Pi = 3.1415
-
-var Foos []Foo
-
-// Foo is stuff.
-type Foo struct{}
-
-func New() *Foo {
-   return new(Foo)
-}
-`,
-		"src/bar/bar.go": `// Package bar is another example to test races.
-package bar
-`,
-		"src/other/bar/bar.go": `// Package bar is another bar package.
-package bar
-func X() {}
-`,
-		"src/skip/skip.go": `// Package skip should be skipped.
-package skip
-func Skip() {}
-`,
-		"src/bar/readme.txt": `Whitelisted text file.
-`,
-		"src/bar/baz.zzz": `Text file not whitelisted.
-`,
-	}))
-	c.IndexEnabled = true
-	c.IndexDirectory = func(dir string) bool {
-		return !strings.Contains(dir, "skip")
-	}
-
-	if err := c.Init(); err != nil {
-		t.Fatal(err)
-	}
-	return c
-}
-
-func TestIndex(t *testing.T) {
-	for _, docs := range []bool{true, false} {
-		for _, goCode := range []bool{true, false} {
-			for _, fullText := range []bool{true, false} {
-				c := newCorpus(t)
-				c.IndexDocs = docs
-				c.IndexGoCode = goCode
-				c.IndexFullText = fullText
-				c.UpdateIndex()
-				ix, _ := c.CurrentIndex()
-				if ix == nil {
-					t.Fatal("no index")
-				}
-				t.Logf("docs, goCode, fullText = %v,%v,%v", docs, goCode, fullText)
-				testIndex(t, c, ix)
-			}
-		}
-	}
-}
-
-func TestIndexWriteRead(t *testing.T) {
-	type key struct {
-		docs, goCode, fullText bool
-	}
-	type val struct {
-		buf *bytes.Buffer
-		c   *Corpus
-	}
-	m := map[key]val{}
-
-	for _, docs := range []bool{true, false} {
-		for _, goCode := range []bool{true, false} {
-			for _, fullText := range []bool{true, false} {
-				k := key{docs, goCode, fullText}
-				c := newCorpus(t)
-				c.IndexDocs = docs
-				c.IndexGoCode = goCode
-				c.IndexFullText = fullText
-				c.UpdateIndex()
-				ix, _ := c.CurrentIndex()
-				if ix == nil {
-					t.Fatal("no index")
-				}
-				var buf bytes.Buffer
-				nw, err := ix.WriteTo(&buf)
-				if err != nil {
-					t.Fatalf("Index.WriteTo: %v", err)
-				}
-				m[k] = val{bytes.NewBuffer(buf.Bytes()), c}
-				ix2 := new(Index)
-				nr, err := ix2.ReadFrom(&buf)
-				if err != nil {
-					t.Fatalf("Index.ReadFrom: %v", err)
-				}
-				if nr != nw {
-					t.Errorf("Wrote %d bytes to index but read %d", nw, nr)
-				}
-				testIndex(t, c, ix)
-			}
-		}
-	}
-	// Test CompatibleWith
-	for k1, v1 := range m {
-		ix := new(Index)
-		if _, err := ix.ReadFrom(v1.buf); err != nil {
-			t.Fatalf("Index.ReadFrom: %v", err)
-		}
-		for k2, v2 := range m {
-			if got, want := ix.CompatibleWith(v2.c), k1 == k2; got != want {
-				t.Errorf("CompatibleWith = %v; want %v for %v, %v", got, want, k1, k2)
-			}
-		}
-	}
-}
-
-func testIndex(t *testing.T, c *Corpus, ix *Index) {
-	if _, ok := ix.words["Skip"]; ok {
-		t.Errorf("the word Skip was found; expected it to be skipped")
-	}
-	checkStats(t, c, ix)
-	checkImportCount(t, c, ix)
-	checkPackagePath(t, c, ix)
-	checkExports(t, c, ix)
-	checkIdents(t, c, ix)
-}
-
-// checkStats checks the Index's statistics.
-// Some statistics are only set when we're indexing Go code.
-func checkStats(t *testing.T, c *Corpus, ix *Index) {
-	want := Statistics{}
-	if c.IndexFullText {
-		want.Bytes = 314
-		want.Files = 4
-		want.Lines = 21
-	} else if c.IndexDocs || c.IndexGoCode {
-		want.Bytes = 291
-		want.Files = 3
-		want.Lines = 20
-	}
-	if c.IndexGoCode {
-		want.Words = 8
-		want.Spots = 12
-	}
-	if got := ix.Stats(); !reflect.DeepEqual(got, want) {
-		t.Errorf("Stats = %#v; want %#v", got, want)
-	}
-}
-
-// checkImportCount checks the Index's import count map.
-// It is only set when we're indexing Go code.
-func checkImportCount(t *testing.T, c *Corpus, ix *Index) {
-	want := map[string]int{}
-	if c.IndexGoCode {
-		want = map[string]int{
-			"bar": 1,
-		}
-	}
-	if got := ix.ImportCount(); !reflect.DeepEqual(got, want) {
-		t.Errorf("ImportCount = %v; want %v", got, want)
-	}
-}
-
-// checkPackagePath checks the Index's package path map.
-// It is set if at least one of the indexing options is enabled.
-func checkPackagePath(t *testing.T, c *Corpus, ix *Index) {
-	want := map[string]map[string]bool{}
-	if c.IndexDocs || c.IndexGoCode || c.IndexFullText {
-		want = map[string]map[string]bool{
-			"foo": {
-				"foo": true,
-			},
-			"bar": {
-				"bar":       true,
-				"other/bar": true,
-			},
-		}
-	}
-	if got := ix.PackagePath(); !reflect.DeepEqual(got, want) {
-		t.Errorf("PackagePath = %v; want %v", got, want)
-	}
-}
-
-// checkExports checks the Index's exports map.
-// It is only set when we're indexing Go code.
-func checkExports(t *testing.T, c *Corpus, ix *Index) {
-	want := map[string]map[string]SpotKind{}
-	if c.IndexGoCode {
-		want = map[string]map[string]SpotKind{
-			"foo": {
-				"Pi":   ConstDecl,
-				"Foos": VarDecl,
-				"Foo":  TypeDecl,
-				"New":  FuncDecl,
-			},
-			"other/bar": {
-				"X": FuncDecl,
-			},
-		}
-	}
-	if got := ix.Exports(); !reflect.DeepEqual(got, want) {
-		t.Errorf("Exports = %v; want %v", got, want)
-	}
-}
-
-// checkIdents checks the Index's indents map.
-// It is only set when we're indexing documentation.
-func checkIdents(t *testing.T, c *Corpus, ix *Index) {
-	want := map[SpotKind]map[string][]Ident{}
-	if c.IndexDocs {
-		want = map[SpotKind]map[string][]Ident{
-			PackageClause: {
-				"bar": {
-					{"bar", "bar", "bar", "Package bar is another example to test races."},
-					{"other/bar", "bar", "bar", "Package bar is another bar package."},
-				},
-				"foo":   {{"foo", "foo", "foo", "Package foo is an example."}},
-				"other": {{"other/bar", "bar", "bar", "Package bar is another bar package."}},
-			},
-			ConstDecl: {
-				"Pi": {{"foo", "foo", "Pi", ""}},
-			},
-			VarDecl: {
-				"Foos": {{"foo", "foo", "Foos", ""}},
-			},
-			TypeDecl: {
-				"Foo": {{"foo", "foo", "Foo", "Foo is stuff."}},
-			},
-			FuncDecl: {
-				"New": {{"foo", "foo", "New", ""}},
-				"X":   {{"other/bar", "bar", "X", ""}},
-			},
-		}
-	}
-	if got := ix.Idents(); !reflect.DeepEqual(got, want) {
-		t.Errorf("Idents = %v; want %v", got, want)
-	}
-}
-
-func TestIdentResultSort(t *testing.T) {
-	ic := map[string]int{
-		"/a/b/pkg1": 10,
-		"/a/b/pkg2": 2,
-		"/b/d/pkg3": 20,
-	}
-	for _, tc := range []struct {
-		ir  []Ident
-		exp []Ident
-	}{
-		{
-			ir: []Ident{
-				{"/a/b/pkg2", "pkg2", "MyFunc2", ""},
-				{"/b/d/pkg3", "pkg3", "MyFunc3", ""},
-				{"/a/b/pkg1", "pkg1", "MyFunc1", ""},
-			},
-			exp: []Ident{
-				{"/b/d/pkg3", "pkg3", "MyFunc3", ""},
-				{"/a/b/pkg1", "pkg1", "MyFunc1", ""},
-				{"/a/b/pkg2", "pkg2", "MyFunc2", ""},
-			},
-		},
-		{
-			ir: []Ident{
-				{"/a/a/pkg1", "pkg1", "MyFunc1", ""},
-				{"/a/b/pkg1", "pkg1", "MyFunc1", ""},
-			},
-			exp: []Ident{
-				{"/a/b/pkg1", "pkg1", "MyFunc1", ""},
-				{"/a/a/pkg1", "pkg1", "MyFunc1", ""},
-			},
-		},
-	} {
-		if sort.Sort(byImportCount{tc.ir, ic}); !reflect.DeepEqual(tc.ir, tc.exp) {
-			t.Errorf("got: %v, want %v", tc.ir, tc.exp)
-		}
-	}
-}
-
-func TestIdentFilter(t *testing.T) {
-	ic := map[string]int{}
-	for _, tc := range []struct {
-		ir  []Ident
-		pak string
-		exp []Ident
-	}{
-		{
-			ir: []Ident{
-				{"/a/b/pkg2", "pkg2", "MyFunc2", ""},
-				{"/b/d/pkg3", "pkg3", "MyFunc3", ""},
-				{"/a/b/pkg1", "pkg1", "MyFunc1", ""},
-			},
-			pak: "pkg2",
-			exp: []Ident{
-				{"/a/b/pkg2", "pkg2", "MyFunc2", ""},
-			},
-		},
-	} {
-		res := byImportCount{tc.ir, ic}.filter(tc.pak)
-		if !reflect.DeepEqual(res, tc.exp) {
-			t.Errorf("got: %v, want %v", res, tc.exp)
-		}
-	}
-}
diff --git a/cmd/golangorg/godoc/linkify.go b/cmd/golangorg/godoc/linkify.go
deleted file mode 100644
index e4add22..0000000
--- a/cmd/golangorg/godoc/linkify.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements LinkifyText which introduces
-// links for identifiers pointing to their declarations.
-// The approach does not cover all cases because godoc
-// doesn't have complete type information, but it's
-// reasonably good for browsing.
-
-package godoc
-
-import (
-	"fmt"
-	"go/ast"
-	"go/doc"
-	"go/token"
-	"io"
-	"strconv"
-)
-
-// LinkifyText HTML-escapes source text and writes it to w.
-// Identifiers that are in a "use" position (i.e., that are
-// not being declared), are wrapped with HTML links pointing
-// to the respective declaration, if possible. Comments are
-// formatted the same way as with FormatText.
-//
-func LinkifyText(w io.Writer, text []byte, n ast.Node) {
-	links := linksFor(n)
-
-	i := 0     // links index
-	prev := "" // prev HTML tag
-	linkWriter := func(w io.Writer, _ int, start bool) {
-		// end tag
-		if !start {
-			if prev != "" {
-				fmt.Fprintf(w, `</%s>`, prev)
-				prev = ""
-			}
-			return
-		}
-
-		// start tag
-		prev = ""
-		if i < len(links) {
-			switch info := links[i]; {
-			case info.path != "" && info.name == "":
-				// package path
-				fmt.Fprintf(w, `<a href="/pkg/%s/">`, info.path)
-				prev = "a"
-			case info.path != "" && info.name != "":
-				// qualified identifier
-				fmt.Fprintf(w, `<a href="/pkg/%s/#%s">`, info.path, info.name)
-				prev = "a"
-			case info.path == "" && info.name != "":
-				// local identifier
-				if info.isVal {
-					fmt.Fprintf(w, `<span id="%s">`, info.name)
-					prev = "span"
-				} else if ast.IsExported(info.name) {
-					fmt.Fprintf(w, `<a href="#%s">`, info.name)
-					prev = "a"
-				}
-			}
-			i++
-		}
-	}
-
-	idents := tokenSelection(text, token.IDENT)
-	comments := tokenSelection(text, token.COMMENT)
-	FormatSelections(w, text, linkWriter, idents, selectionTag, comments)
-}
-
-// A link describes the (HTML) link information for an identifier.
-// The zero value of a link represents "no link".
-//
-type link struct {
-	path, name string // package path, identifier name
-	isVal      bool   // identifier is defined in a const or var declaration
-}
-
-// linksFor returns the list of links for the identifiers used
-// by node in the same order as they appear in the source.
-//
-func linksFor(node ast.Node) (links []link) {
-	// linkMap tracks link information for each ast.Ident node. Entries may
-	// be created out of source order (for example, when we visit a parent
-	// definition node). These links are appended to the returned slice when
-	// their ast.Ident nodes are visited.
-	linkMap := make(map[*ast.Ident]link)
-
-	ast.Inspect(node, func(node ast.Node) bool {
-		switch n := node.(type) {
-		case *ast.Field:
-			for _, n := range n.Names {
-				linkMap[n] = link{}
-			}
-		case *ast.ImportSpec:
-			if name := n.Name; name != nil {
-				linkMap[name] = link{}
-			}
-		case *ast.ValueSpec:
-			for _, n := range n.Names {
-				linkMap[n] = link{name: n.Name, isVal: true}
-			}
-		case *ast.FuncDecl:
-			linkMap[n.Name] = link{}
-		case *ast.TypeSpec:
-			linkMap[n.Name] = link{}
-		case *ast.AssignStmt:
-			// Short variable declarations only show up if we apply
-			// this code to all source code (as opposed to exported
-			// declarations only).
-			if n.Tok == token.DEFINE {
-				// Some of the lhs variables may be re-declared,
-				// so technically they are not defs. We don't
-				// care for now.
-				for _, x := range n.Lhs {
-					// Each lhs expression should be an
-					// ident, but we are conservative and check.
-					if n, _ := x.(*ast.Ident); n != nil {
-						linkMap[n] = link{isVal: true}
-					}
-				}
-			}
-		case *ast.SelectorExpr:
-			// Detect qualified identifiers of the form pkg.ident.
-			// If anything fails we return true and collect individual
-			// identifiers instead.
-			if x, _ := n.X.(*ast.Ident); x != nil {
-				// Create links only if x is a qualified identifier.
-				if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
-					if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
-						// spec.Path.Value is the import path
-						if path, err := strconv.Unquote(spec.Path.Value); err == nil {
-							// Register two links, one for the package
-							// and one for the qualified identifier.
-							linkMap[x] = link{path: path}
-							linkMap[n.Sel] = link{path: path, name: n.Sel.Name}
-						}
-					}
-				}
-			}
-		case *ast.CompositeLit:
-			// Detect field names within composite literals. These links should
-			// be prefixed by the type name.
-			fieldPath := ""
-			prefix := ""
-			switch typ := n.Type.(type) {
-			case *ast.Ident:
-				prefix = typ.Name + "."
-			case *ast.SelectorExpr:
-				if x, _ := typ.X.(*ast.Ident); x != nil {
-					// Create links only if x is a qualified identifier.
-					if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
-						if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
-							// spec.Path.Value is the import path
-							if path, err := strconv.Unquote(spec.Path.Value); err == nil {
-								// Register two links, one for the package
-								// and one for the qualified identifier.
-								linkMap[x] = link{path: path}
-								linkMap[typ.Sel] = link{path: path, name: typ.Sel.Name}
-								fieldPath = path
-								prefix = typ.Sel.Name + "."
-							}
-						}
-					}
-				}
-			}
-			for _, e := range n.Elts {
-				if kv, ok := e.(*ast.KeyValueExpr); ok {
-					if k, ok := kv.Key.(*ast.Ident); ok {
-						// Note: there is some syntactic ambiguity here. We cannot determine
-						// if this is a struct literal or a map literal without type
-						// information. We assume struct literal.
-						name := prefix + k.Name
-						linkMap[k] = link{path: fieldPath, name: name}
-					}
-				}
-			}
-		case *ast.Ident:
-			if l, ok := linkMap[n]; ok {
-				links = append(links, l)
-			} else {
-				l := link{name: n.Name}
-				if n.Obj == nil && doc.IsPredeclared(n.Name) {
-					l.path = builtinPkgPath
-				}
-				links = append(links, l)
-			}
-		}
-		return true
-	})
-	return
-}
diff --git a/cmd/golangorg/godoc/meta.go b/cmd/golangorg/godoc/meta.go
deleted file mode 100644
index 4fa67a7..0000000
--- a/cmd/golangorg/godoc/meta.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"bytes"
-	"encoding/json"
-	"log"
-	pathpkg "path"
-	"strings"
-	"time"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-var (
-	doctype   = []byte("<!DOCTYPE ")
-	jsonStart = []byte("<!--{")
-	jsonEnd   = []byte("}-->")
-)
-
-// ----------------------------------------------------------------------------
-// Documentation Metadata
-
-// TODO(adg): why are some exported and some aren't? -brad
-type Metadata struct {
-	Title    string
-	Subtitle string
-	Template bool   // execute as template
-	Path     string // canonical path for this page
-	filePath string // filesystem path relative to goroot
-}
-
-func (m *Metadata) FilePath() string { return m.filePath }
-
-// extractMetadata extracts the Metadata from a byte slice.
-// It returns the Metadata value and the remaining data.
-// If no metadata is present the original byte slice is returned.
-//
-func extractMetadata(b []byte) (meta Metadata, tail []byte, err error) {
-	tail = b
-	if !bytes.HasPrefix(b, jsonStart) {
-		return
-	}
-	end := bytes.Index(b, jsonEnd)
-	if end < 0 {
-		return
-	}
-	b = b[len(jsonStart)-1 : end+1] // drop leading <!-- and include trailing }
-	if err = json.Unmarshal(b, &meta); err != nil {
-		return
-	}
-	tail = tail[end+len(jsonEnd):]
-	return
-}
-
-// UpdateMetadata scans $GOROOT/doc for HTML files, reads their metadata,
-// and updates the DocMetadata map.
-func (c *Corpus) updateMetadata() {
-	metadata := make(map[string]*Metadata)
-	var scan func(string) // scan is recursive
-	scan = func(dir string) {
-		fis, err := c.fs.ReadDir(dir)
-		if err != nil {
-			log.Println("updateMetadata:", err)
-			return
-		}
-		for _, fi := range fis {
-			name := pathpkg.Join(dir, fi.Name())
-			if fi.IsDir() {
-				scan(name) // recurse
-				continue
-			}
-			if !strings.HasSuffix(name, ".html") {
-				continue
-			}
-			// Extract metadata from the file.
-			b, err := vfs.ReadFile(c.fs, name)
-			if err != nil {
-				log.Printf("updateMetadata %s: %v", name, err)
-				continue
-			}
-			meta, _, err := extractMetadata(b)
-			if err != nil {
-				log.Printf("updateMetadata: %s: %v", name, err)
-				continue
-			}
-			// Store relative filesystem path in Metadata.
-			meta.filePath = name
-			if meta.Path == "" {
-				// If no Path, canonical path is actual path.
-				meta.Path = meta.filePath
-			}
-			// Store under both paths.
-			metadata[meta.Path] = &meta
-			metadata[meta.filePath] = &meta
-		}
-	}
-	scan("/doc")
-	c.docMetadata.Set(metadata)
-}
-
-// MetadataFor returns the *Metadata for a given relative path or nil if none
-// exists.
-//
-func (c *Corpus) MetadataFor(relpath string) *Metadata {
-	if m, _ := c.docMetadata.Get(); m != nil {
-		meta := m.(map[string]*Metadata)
-		// If metadata for this relpath exists, return it.
-		if p := meta[relpath]; p != nil {
-			return p
-		}
-		// Try with or without trailing slash.
-		if strings.HasSuffix(relpath, "/") {
-			relpath = relpath[:len(relpath)-1]
-		} else {
-			relpath = relpath + "/"
-		}
-		return meta[relpath]
-	}
-	return nil
-}
-
-// refreshMetadata sends a signal to update DocMetadata. If a refresh is in
-// progress the metadata will be refreshed again afterward.
-//
-func (c *Corpus) refreshMetadata() {
-	select {
-	case c.refreshMetadataSignal <- true:
-	default:
-	}
-}
-
-// RefreshMetadataLoop runs forever, updating DocMetadata when the underlying
-// file system changes. It should be launched in a goroutine.
-func (c *Corpus) refreshMetadataLoop() {
-	for {
-		<-c.refreshMetadataSignal
-		c.updateMetadata()
-		time.Sleep(10 * time.Second) // at most once every 10 seconds
-	}
-}
diff --git a/cmd/golangorg/godoc/page.go b/cmd/golangorg/godoc/page.go
deleted file mode 100644
index 719789e..0000000
--- a/cmd/golangorg/godoc/page.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"net/http"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strings"
-
-	"golang.org/x/website/cmd/golangorg/godoc/env"
-)
-
-// Page describes the contents of the top-level godoc webpage.
-type Page struct {
-	Title    string
-	Tabtitle string
-	Subtitle string
-	SrcPath  string
-	Query    string
-	Body     []byte
-	GoogleCN bool // page is being served from golang.google.cn
-	TreeView bool // page needs to contain treeview related js and css
-
-	// filled in by ServePage
-	SearchBox       bool
-	Playground      bool
-	Version         string
-	GoogleAnalytics string
-}
-
-func (p *Presentation) ServePage(w http.ResponseWriter, page Page) {
-	if page.Tabtitle == "" {
-		page.Tabtitle = page.Title
-	}
-	page.SearchBox = p.Corpus.IndexEnabled
-	page.Playground = p.ShowPlayground
-	page.Version = runtime.Version()
-	page.GoogleAnalytics = p.GoogleAnalytics
-	applyTemplateToResponseWriter(w, p.GodocHTML, page)
-}
-
-func (p *Presentation) ServeError(w http.ResponseWriter, r *http.Request, relpath string, err error) {
-	w.WriteHeader(http.StatusNotFound)
-	if perr, ok := err.(*os.PathError); ok {
-		rel, err := filepath.Rel(runtime.GOROOT(), perr.Path)
-		if err != nil {
-			perr.Path = "REDACTED"
-		} else {
-			perr.Path = filepath.Join("$GOROOT", rel)
-		}
-	}
-	p.ServePage(w, Page{
-		Title:           "File " + relpath,
-		Subtitle:        relpath,
-		Body:            applyTemplate(p.ErrorHTML, "errorHTML", err),
-		GoogleCN:        googleCN(r),
-		GoogleAnalytics: p.GoogleAnalytics,
-	})
-}
-
-func googleCN(r *http.Request) bool {
-	if r.FormValue("googlecn") != "" {
-		return true
-	}
-	if !env.IsProd() {
-		return false
-	}
-	if strings.HasSuffix(r.Host, ".cn") {
-		return true
-	}
-	switch r.Header.Get("X-AppEngine-Country") {
-	case "", "ZZ", "CN":
-		return true
-	}
-	return false
-}
diff --git a/cmd/golangorg/godoc/parser.go b/cmd/golangorg/godoc/parser.go
deleted file mode 100644
index 6a00b3b..0000000
--- a/cmd/golangorg/godoc/parser.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains support functions for parsing .go files
-// accessed via godoc's file system fs.
-
-package godoc
-
-import (
-	"bytes"
-	"go/ast"
-	"go/parser"
-	"go/token"
-	pathpkg "path"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-var linePrefix = []byte("//line ")
-
-// This function replaces source lines starting with "//line " with a blank line.
-// It does this irrespective of whether the line is truly a line comment or not;
-// e.g., the line may be inside a string, or a /*-style comment; however that is
-// rather unlikely (proper testing would require a full Go scan which we want to
-// avoid for performance).
-func replaceLinePrefixCommentsWithBlankLine(src []byte) {
-	for {
-		i := bytes.Index(src, linePrefix)
-		if i < 0 {
-			break // we're done
-		}
-		// 0 <= i && i+len(linePrefix) <= len(src)
-		if i == 0 || src[i-1] == '\n' {
-			// at beginning of line: blank out line
-			for i < len(src) && src[i] != '\n' {
-				src[i] = ' '
-				i++
-			}
-		} else {
-			// not at beginning of line: skip over prefix
-			i += len(linePrefix)
-		}
-		// i <= len(src)
-		src = src[i:]
-	}
-}
-
-func (c *Corpus) parseFile(fset *token.FileSet, filename string, mode parser.Mode) (*ast.File, error) {
-	src, err := vfs.ReadFile(c.fs, filename)
-	if err != nil {
-		return nil, err
-	}
-
-	// Temporary ad-hoc fix for issue 5247.
-	// TODO(gri) Remove this in favor of a better fix, eventually (see issue 7702).
-	replaceLinePrefixCommentsWithBlankLine(src)
-
-	return parser.ParseFile(fset, filename, src, mode)
-}
-
-func (c *Corpus) parseFiles(fset *token.FileSet, relpath string, abspath string, localnames []string) (map[string]*ast.File, error) {
-	files := make(map[string]*ast.File)
-	for _, f := range localnames {
-		absname := pathpkg.Join(abspath, f)
-		file, err := c.parseFile(fset, absname, parser.ParseComments)
-		if err != nil {
-			return nil, err
-		}
-		files[pathpkg.Join(relpath, f)] = file
-	}
-
-	return files, nil
-}
diff --git a/cmd/golangorg/godoc/pres.go b/cmd/golangorg/godoc/pres.go
deleted file mode 100644
index a5c7fa5..0000000
--- a/cmd/golangorg/godoc/pres.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"net/http"
-	"regexp"
-	"sync"
-	"text/template"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs/httpfs"
-)
-
-// SearchResultFunc functions return an HTML body for displaying search results.
-type SearchResultFunc func(p *Presentation, result SearchResult) []byte
-
-// Presentation generates output from a corpus.
-type Presentation struct {
-	Corpus *Corpus
-
-	mux        *http.ServeMux
-	fileServer http.Handler
-	cmdHandler handlerServer
-	pkgHandler handlerServer
-
-	CallGraphHTML,
-	DirlistHTML,
-	ErrorHTML,
-	ExampleHTML,
-	GodocHTML,
-	ImplementsHTML,
-	MethodSetHTML,
-	PackageHTML,
-	PackageRootHTML,
-	SearchHTML,
-	SearchDocHTML,
-	SearchCodeHTML,
-	SearchTxtHTML,
-	SearchDescXML *template.Template
-
-	// TabWidth optionally specifies the tab width.
-	TabWidth int
-
-	ShowTimestamps bool
-	ShowPlayground bool
-	DeclLinks      bool
-
-	// SrcMode outputs source code instead of documentation in command-line mode.
-	SrcMode bool
-	// HTMLMode outputs HTML instead of plain text in command-line mode.
-	HTMLMode bool
-	// AllMode includes unexported identifiers in the output in command-line mode.
-	AllMode bool
-
-	// NotesRx optionally specifies a regexp to match
-	// notes to render in the output.
-	NotesRx *regexp.Regexp
-
-	// AdjustPageInfoMode optionally specifies a function to
-	// modify the PageInfoMode of a request. The default chosen
-	// value is provided.
-	AdjustPageInfoMode func(req *http.Request, mode PageInfoMode) PageInfoMode
-
-	// URLForSrc optionally specifies a function that takes a source file and
-	// returns a URL for it.
-	// The source file argument has the form /src/<path>/<filename>.
-	URLForSrc func(src string) string
-
-	// URLForSrcPos optionally specifies a function to create a URL given a
-	// source file, a line from the source file (1-based), and low & high offset
-	// positions (0-based, bytes from beginning of file). Ideally, the returned
-	// URL will be for the specified line of the file, while the high & low
-	// positions will be used to highlight a section of the file.
-	// The source file argument has the form /src/<path>/<filename>.
-	URLForSrcPos func(src string, line, low, high int) string
-
-	// URLForSrcQuery optionally specifies a function to create a URL given a
-	// source file, a query string, and a line from the source file (1-based).
-	// The source file argument has the form /src/<path>/<filename>.
-	// The query argument will be escaped for the purposes of embedding in a URL
-	// query parameter.
-	// Ideally, the returned URL will be for the specified line of the file with
-	// the query string highlighted.
-	URLForSrcQuery func(src, query string, line int) string
-
-	// SearchResults optionally specifies a list of functions returning an HTML
-	// body for displaying search results.
-	SearchResults []SearchResultFunc
-
-	// GoogleAnalytics optionally adds Google Analytics via the provided
-	// tracking ID to each page.
-	GoogleAnalytics string
-
-	initFuncMapOnce sync.Once
-	funcMap         template.FuncMap
-	templateFuncs   template.FuncMap
-}
-
-// NewPresentation returns a new Presentation from a corpus.
-// It sets SearchResults to:
-// [SearchResultDoc SearchResultCode SearchResultTxt].
-func NewPresentation(c *Corpus) *Presentation {
-	if c == nil {
-		panic("nil Corpus")
-	}
-	p := &Presentation{
-		Corpus:     c,
-		mux:        http.NewServeMux(),
-		fileServer: http.FileServer(httpfs.New(c.fs)),
-
-		TabWidth:  4,
-		DeclLinks: true,
-		SearchResults: []SearchResultFunc{
-			(*Presentation).SearchResultDoc,
-			(*Presentation).SearchResultCode,
-			(*Presentation).SearchResultTxt,
-		},
-	}
-	p.cmdHandler = handlerServer{
-		p:       p,
-		c:       c,
-		pattern: "/cmd/",
-		fsRoot:  "/src",
-	}
-	p.pkgHandler = handlerServer{
-		p:           p,
-		c:           c,
-		pattern:     "/pkg/",
-		stripPrefix: "pkg/",
-		fsRoot:      "/src",
-		exclude:     []string{"/src/cmd"},
-	}
-	p.cmdHandler.registerWithMux(p.mux)
-	p.pkgHandler.registerWithMux(p.mux)
-	p.mux.HandleFunc("/", p.ServeFile)
-	p.mux.HandleFunc("/search", p.HandleSearch)
-	p.mux.HandleFunc("/opensearch.xml", p.serveSearchDesc)
-	return p
-}
-
-func (p *Presentation) FileServer() http.Handler {
-	return p.fileServer
-}
-
-func (p *Presentation) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	p.mux.ServeHTTP(w, r)
-}
-
-func (p *Presentation) PkgFSRoot() string {
-	return p.pkgHandler.fsRoot
-}
-
-func (p *Presentation) CmdFSRoot() string {
-	return p.cmdHandler.fsRoot
-}
-
-// TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
-// but this doesn't feel right.
-func (p *Presentation) GetPkgPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
-	return p.pkgHandler.GetPageInfo(abspath, relpath, mode, "", "")
-}
-
-// TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
-// but this doesn't feel right.
-func (p *Presentation) GetCmdPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
-	return p.cmdHandler.GetPageInfo(abspath, relpath, mode, "", "")
-}
diff --git a/cmd/golangorg/godoc/proxy/proxy.go b/cmd/golangorg/godoc/proxy/proxy.go
deleted file mode 100644
index faba509..0000000
--- a/cmd/golangorg/godoc/proxy/proxy.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package proxy proxies requests to the playground's compile and share handlers.
-// It is designed to run only on the instance of godoc that serves golang.org.
-package proxy
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"strings"
-	"time"
-
-	"golang.org/x/website/cmd/golangorg/godoc/env"
-)
-
-const playgroundURL = "https://play.golang.org"
-
-type Request struct {
-	Body string
-}
-
-type Response struct {
-	Errors string
-	Events []Event
-}
-
-type Event struct {
-	Message string
-	Kind    string        // "stdout" or "stderr"
-	Delay   time.Duration // time to wait before printing Message
-}
-
-const expires = 7 * 24 * time.Hour // 1 week
-var cacheControlHeader = fmt.Sprintf("public, max-age=%d", int(expires.Seconds()))
-
-func RegisterHandlers(mux *http.ServeMux) {
-	mux.HandleFunc("/compile", compile)
-	mux.HandleFunc("/share", share)
-}
-
-func compile(w http.ResponseWriter, r *http.Request) {
-	if r.Method != "POST" {
-		http.Error(w, "I only answer to POST requests.", http.StatusMethodNotAllowed)
-		return
-	}
-
-	ctx := r.Context()
-
-	body := r.FormValue("body")
-	res := &Response{}
-	req := &Request{Body: body}
-	if err := makeCompileRequest(ctx, req, res); err != nil {
-		log.Printf("ERROR compile error: %v", err)
-		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
-		return
-	}
-
-	var out interface{}
-	switch r.FormValue("version") {
-	case "2":
-		out = res
-	default: // "1"
-		out = struct {
-			CompileErrors string `json:"compile_errors"`
-			Output        string `json:"output"`
-		}{res.Errors, flatten(res.Events)}
-	}
-	b, err := json.Marshal(out)
-	if err != nil {
-		log.Printf("ERROR encoding response: %v", err)
-		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
-		return
-	}
-
-	expiresTime := time.Now().Add(expires).UTC()
-	w.Header().Set("Expires", expiresTime.Format(time.RFC1123))
-	w.Header().Set("Cache-Control", cacheControlHeader)
-	w.Write(b)
-}
-
-// makePlaygroundRequest sends the given Request to the playground compile
-// endpoint and stores the response in the given Response.
-func makeCompileRequest(ctx context.Context, req *Request, res *Response) error {
-	reqJ, err := json.Marshal(req)
-	if err != nil {
-		return fmt.Errorf("marshalling request: %v", err)
-	}
-	hReq, _ := http.NewRequest("POST", playgroundURL+"/compile", bytes.NewReader(reqJ))
-	hReq.Header.Set("Content-Type", "application/json")
-	hReq = hReq.WithContext(ctx)
-
-	r, err := http.DefaultClient.Do(hReq)
-	if err != nil {
-		return fmt.Errorf("making request: %v", err)
-	}
-	defer r.Body.Close()
-
-	if r.StatusCode != http.StatusOK {
-		b, _ := ioutil.ReadAll(r.Body)
-		return fmt.Errorf("bad status: %v body:\n%s", r.Status, b)
-	}
-
-	if err := json.NewDecoder(r.Body).Decode(res); err != nil {
-		return fmt.Errorf("unmarshalling response: %v", err)
-	}
-	return nil
-}
-
-// flatten takes a sequence of Events and returns their contents, concatenated.
-func flatten(seq []Event) string {
-	var buf bytes.Buffer
-	for _, e := range seq {
-		buf.WriteString(e.Message)
-	}
-	return buf.String()
-}
-
-func share(w http.ResponseWriter, r *http.Request) {
-	if googleCN(r) {
-		http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
-		return
-	}
-
-	// HACK(cbro): use a simple proxy rather than httputil.ReverseProxy because of Issue #28168.
-	// TODO: investigate using ReverseProxy with a Director, unsetting whatever's necessary to make that work.
-	req, _ := http.NewRequest("POST", playgroundURL+"/share", r.Body)
-	req.Header.Set("Content-Type", r.Header.Get("Content-Type"))
-	req = req.WithContext(r.Context())
-	resp, err := http.DefaultClient.Do(req)
-	if err != nil {
-		log.Printf("ERROR share error: %v", err)
-		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
-		return
-	}
-	copyHeader := func(k string) {
-		if v := resp.Header.Get(k); v != "" {
-			w.Header().Set(k, v)
-		}
-	}
-	copyHeader("Content-Type")
-	copyHeader("Content-Length")
-	defer resp.Body.Close()
-	w.WriteHeader(resp.StatusCode)
-	io.Copy(w, resp.Body)
-}
-
-func googleCN(r *http.Request) bool {
-	if r.FormValue("googlecn") != "" {
-		return true
-	}
-	if !env.IsProd() {
-		return false
-	}
-	if strings.HasSuffix(r.Host, ".cn") {
-		return true
-	}
-	switch r.Header.Get("X-AppEngine-Country") {
-	case "", "ZZ", "CN":
-		return true
-	}
-	return false
-}
diff --git a/cmd/golangorg/godoc/redirect/hash.go b/cmd/golangorg/godoc/redirect/hash.go
deleted file mode 100644
index d5a1e3e..0000000
--- a/cmd/golangorg/godoc/redirect/hash.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file provides a compact encoding of
-// a map of Mercurial hashes to Git hashes.
-
-package redirect
-
-import (
-	"encoding/binary"
-	"fmt"
-	"io"
-	"os"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-// hashMap is a map of Mercurial hashes to Git hashes.
-type hashMap struct {
-	file    *os.File
-	entries int
-}
-
-// newHashMap takes a file handle that contains a map of Mercurial to Git
-// hashes. The file should be a sequence of pairs of little-endian encoded
-// uint32s, representing a hgHash and a gitHash respectively.
-// The sequence must be sorted by hgHash.
-// The file must remain open for as long as the returned hashMap is used.
-func newHashMap(f *os.File) (*hashMap, error) {
-	fi, err := f.Stat()
-	if err != nil {
-		return nil, err
-	}
-	return &hashMap{file: f, entries: int(fi.Size() / 8)}, nil
-}
-
-// Lookup finds an hgHash in the map that matches the given prefix, and returns
-// its corresponding gitHash. The prefix must be at least 8 characters long.
-func (m *hashMap) Lookup(s string) gitHash {
-	if m == nil {
-		return 0
-	}
-	hg, err := hgHashFromString(s)
-	if err != nil {
-		return 0
-	}
-	var git gitHash
-	b := make([]byte, 8)
-	sort.Search(m.entries, func(i int) bool {
-		n, err := m.file.ReadAt(b, int64(i*8))
-		if err != nil {
-			panic(err)
-		}
-		if n != 8 {
-			panic(io.ErrUnexpectedEOF)
-		}
-		v := hgHash(binary.LittleEndian.Uint32(b[:4]))
-		if v == hg {
-			git = gitHash(binary.LittleEndian.Uint32(b[4:]))
-		}
-		return v >= hg
-	})
-	return git
-}
-
-// hgHash represents the lower (leftmost) 32 bits of a Mercurial hash.
-type hgHash uint32
-
-func (h hgHash) String() string {
-	return intToHash(int64(h))
-}
-
-func hgHashFromString(s string) (hgHash, error) {
-	if len(s) < 8 {
-		return 0, fmt.Errorf("string too small: len(s) = %d", len(s))
-	}
-	hash := s[:8]
-	i, err := strconv.ParseInt(hash, 16, 64)
-	if err != nil {
-		return 0, err
-	}
-	return hgHash(i), nil
-}
-
-// gitHash represents the leftmost 28 bits of a Git hash in its upper 28 bits,
-// and it encodes hash's repository in the lower 4  bits.
-type gitHash uint32
-
-func (h gitHash) Hash() string {
-	return intToHash(int64(h))[:7]
-}
-
-func (h gitHash) Repo() string {
-	return repo(h & 0xF).String()
-}
-
-func intToHash(i int64) string {
-	s := strconv.FormatInt(i, 16)
-	if len(s) < 8 {
-		s = strings.Repeat("0", 8-len(s)) + s
-	}
-	return s
-}
-
-// repo represents a Go Git repository.
-type repo byte
-
-const (
-	repoGo repo = iota
-	repoBlog
-	repoCrypto
-	repoExp
-	repoImage
-	repoMobile
-	repoNet
-	repoSys
-	repoTalks
-	repoText
-	repoTools
-)
-
-func (r repo) String() string {
-	return map[repo]string{
-		repoGo:     "go",
-		repoBlog:   "blog",
-		repoCrypto: "crypto",
-		repoExp:    "exp",
-		repoImage:  "image",
-		repoMobile: "mobile",
-		repoNet:    "net",
-		repoSys:    "sys",
-		repoTalks:  "talks",
-		repoText:   "text",
-		repoTools:  "tools",
-	}[r]
-}
diff --git a/cmd/golangorg/godoc/redirect/redirect.go b/cmd/golangorg/godoc/redirect/redirect.go
deleted file mode 100644
index 1edc17c..0000000
--- a/cmd/golangorg/godoc/redirect/redirect.go
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package redirect provides hooks to register HTTP handlers that redirect old
-// godoc paths to their new equivalents and assist in accessing the issue
-// tracker, wiki, code review system, etc.
-package redirect // import "golang.org/x/website/cmd/golangorg/godoc/redirect"
-
-import (
-	"fmt"
-	"net/http"
-	"os"
-	"regexp"
-	"strconv"
-	"strings"
-)
-
-// Register registers HTTP handlers that redirect old godoc paths to their new
-// equivalents and assist in accessing the issue tracker, wiki, code review
-// system, etc. If mux is nil it uses http.DefaultServeMux.
-func Register(mux *http.ServeMux) {
-	if mux == nil {
-		mux = http.DefaultServeMux
-	}
-	handlePathRedirects(mux, pkgRedirects, "/pkg/")
-	handlePathRedirects(mux, cmdRedirects, "/cmd/")
-	for prefix, redirect := range prefixHelpers {
-		p := "/" + prefix + "/"
-		mux.Handle(p, PrefixHandler(p, redirect))
-	}
-	for path, redirect := range redirects {
-		mux.Handle(path, Handler(redirect))
-	}
-	// NB: /src/pkg (sans trailing slash) is the index of packages.
-	mux.HandleFunc("/src/pkg/", srcPkgHandler)
-	mux.HandleFunc("/cl/", clHandler)
-	mux.HandleFunc("/change/", changeHandler)
-	mux.HandleFunc("/design/", designHandler)
-}
-
-func handlePathRedirects(mux *http.ServeMux, redirects map[string]string, prefix string) {
-	for source, target := range redirects {
-		h := Handler(prefix + target + "/")
-		p := prefix + source
-		mux.Handle(p, h)
-		mux.Handle(p+"/", h)
-	}
-}
-
-// Packages that were renamed between r60 and go1.
-var pkgRedirects = map[string]string{
-	"asn1":              "encoding/asn1",
-	"big":               "math/big",
-	"cmath":             "math/cmplx",
-	"csv":               "encoding/csv",
-	"exec":              "os/exec",
-	"exp/template/html": "html/template",
-	"gob":               "encoding/gob",
-	"http":              "net/http",
-	"http/cgi":          "net/http/cgi",
-	"http/fcgi":         "net/http/fcgi",
-	"http/httptest":     "net/http/httptest",
-	"http/pprof":        "net/http/pprof",
-	"json":              "encoding/json",
-	"mail":              "net/mail",
-	"rand":              "math/rand",
-	"rpc":               "net/rpc",
-	"rpc/jsonrpc":       "net/rpc/jsonrpc",
-	"scanner":           "text/scanner",
-	"smtp":              "net/smtp",
-	"tabwriter":         "text/tabwriter",
-	"template":          "text/template",
-	"template/parse":    "text/template/parse",
-	"url":               "net/url",
-	"utf16":             "unicode/utf16",
-	"utf8":              "unicode/utf8",
-	"xml":               "encoding/xml",
-}
-
-// Commands that were renamed between r60 and go1.
-var cmdRedirects = map[string]string{
-	"gofix":     "fix",
-	"goinstall": "go",
-	"gopack":    "pack",
-	"gotest":    "go",
-	"govet":     "vet",
-	"goyacc":    "yacc",
-}
-
-var redirects = map[string]string{
-	"/blog":       "/blog/",
-	"/build":      "http://build.golang.org",
-	"/change":     "https://go.googlesource.com/go",
-	"/cl":         "https://go-review.googlesource.com",
-	"/cmd/godoc/": "http://godoc.org/golang.org/x/website/cmd/golangorg/",
-	"/issue":      "https://github.com/golang/go/issues",
-	"/issue/new":  "https://github.com/golang/go/issues/new",
-	"/issues":     "https://github.com/golang/go/issues",
-	"/issues/new": "https://github.com/golang/go/issues/new",
-	"/play":       "http://play.golang.org",
-	"/design":     "https://go.googlesource.com/proposal/+/master/design",
-
-	// In Go 1.2 the references page is part of /doc/.
-	"/ref": "/doc/#references",
-	// This next rule clobbers /ref/spec and /ref/mem.
-	// TODO(adg): figure out what to do here, if anything.
-	// "/ref/": "/doc/#references",
-
-	// Be nice to people who are looking in the wrong place.
-	"/doc/mem":  "/ref/mem",
-	"/doc/spec": "/ref/spec",
-
-	"/talks": "http://talks.golang.org",
-	"/tour":  "http://tour.golang.org",
-	"/wiki":  "https://github.com/golang/go/wiki",
-
-	"/doc/articles/c_go_cgo.html":                    "/blog/c-go-cgo",
-	"/doc/articles/concurrency_patterns.html":        "/blog/go-concurrency-patterns-timing-out-and",
-	"/doc/articles/defer_panic_recover.html":         "/blog/defer-panic-and-recover",
-	"/doc/articles/error_handling.html":              "/blog/error-handling-and-go",
-	"/doc/articles/gobs_of_data.html":                "/blog/gobs-of-data",
-	"/doc/articles/godoc_documenting_go_code.html":   "/blog/godoc-documenting-go-code",
-	"/doc/articles/gos_declaration_syntax.html":      "/blog/gos-declaration-syntax",
-	"/doc/articles/image_draw.html":                  "/blog/go-imagedraw-package",
-	"/doc/articles/image_package.html":               "/blog/go-image-package",
-	"/doc/articles/json_and_go.html":                 "/blog/json-and-go",
-	"/doc/articles/json_rpc_tale_of_interfaces.html": "/blog/json-rpc-tale-of-interfaces",
-	"/doc/articles/laws_of_reflection.html":          "/blog/laws-of-reflection",
-	"/doc/articles/slices_usage_and_internals.html":  "/blog/go-slices-usage-and-internals",
-	"/doc/go_for_cpp_programmers.html":               "/wiki/GoForCPPProgrammers",
-	"/doc/go_tutorial.html":                          "http://tour.golang.org/",
-}
-
-var prefixHelpers = map[string]string{
-	"issue":  "https://github.com/golang/go/issues/",
-	"issues": "https://github.com/golang/go/issues/",
-	"play":   "http://play.golang.org/",
-	"talks":  "http://talks.golang.org/",
-	"wiki":   "https://github.com/golang/go/wiki/",
-}
-
-func Handler(target string) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		url := target
-		if qs := r.URL.RawQuery; qs != "" {
-			url += "?" + qs
-		}
-		http.Redirect(w, r, url, http.StatusMovedPermanently)
-	})
-}
-
-var validId = regexp.MustCompile(`^[A-Za-z0-9-]*/?$`)
-
-func PrefixHandler(prefix, baseURL string) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if p := r.URL.Path; p == prefix {
-			// redirect /prefix/ to /prefix
-			http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
-			return
-		}
-		id := r.URL.Path[len(prefix):]
-		if !validId.MatchString(id) {
-			http.Error(w, "Not found", http.StatusNotFound)
-			return
-		}
-		target := baseURL + id
-		http.Redirect(w, r, target, http.StatusFound)
-	})
-}
-
-// Redirect requests from the old "/src/pkg/foo" to the new "/src/foo".
-// See http://golang.org/s/go14nopkg
-func srcPkgHandler(w http.ResponseWriter, r *http.Request) {
-	r.URL.Path = "/src/" + r.URL.Path[len("/src/pkg/"):]
-	http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently)
-}
-
-func clHandler(w http.ResponseWriter, r *http.Request) {
-	const prefix = "/cl/"
-	if p := r.URL.Path; p == prefix {
-		// redirect /prefix/ to /prefix
-		http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
-		return
-	}
-	id := r.URL.Path[len(prefix):]
-	// support /cl/152700045/, which is used in commit 0edafefc36.
-	id = strings.TrimSuffix(id, "/")
-	if !validId.MatchString(id) {
-		http.Error(w, "Not found", http.StatusNotFound)
-		return
-	}
-	target := ""
-
-	if n, err := strconv.Atoi(id); err == nil && isRietveldCL(n) {
-		// TODO: Issue 28836: if this Rietveld CL happens to
-		// also be a Gerrit CL, render a disambiguation HTML
-		// page with two links instead. We'll need to make an
-		// RPC (to maintner?) to figure that out. For now just
-		// redirect to rietveld.
-		target = "https://codereview.appspot.com/" + id
-	} else {
-		target = "https://go-review.googlesource.com/" + id
-	}
-	http.Redirect(w, r, target, http.StatusFound)
-}
-
-var changeMap *hashMap
-
-// LoadChangeMap loads the specified map of Mercurial to Git revisions,
-// which is used by the /change/ handler to intelligently map old hg
-// revisions to their new git equivalents.
-// It should be called before calling Register.
-// The file should remain open as long as the process is running.
-// See the implementation of this package for details.
-func LoadChangeMap(filename string) error {
-	f, err := os.Open(filename)
-	if err != nil {
-		return err
-	}
-	m, err := newHashMap(f)
-	if err != nil {
-		return err
-	}
-	changeMap = m
-	return nil
-}
-
-func changeHandler(w http.ResponseWriter, r *http.Request) {
-	const prefix = "/change/"
-	if p := r.URL.Path; p == prefix {
-		// redirect /prefix/ to /prefix
-		http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
-		return
-	}
-	hash := r.URL.Path[len(prefix):]
-	target := "https://go.googlesource.com/go/+/" + hash
-	if git := changeMap.Lookup(hash); git > 0 {
-		target = fmt.Sprintf("https://go.googlesource.com/%v/+/%v", git.Repo(), git.Hash())
-	}
-	http.Redirect(w, r, target, http.StatusFound)
-}
-
-func designHandler(w http.ResponseWriter, r *http.Request) {
-	const prefix = "/design/"
-	if p := r.URL.Path; p == prefix {
-		// redirect /prefix/ to /prefix
-		http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
-		return
-	}
-	name := r.URL.Path[len(prefix):]
-	target := "https://go.googlesource.com/proposal/+/master/design/" + name + ".md"
-	http.Redirect(w, r, target, http.StatusFound)
-}
diff --git a/cmd/golangorg/godoc/redirect/redirect_test.go b/cmd/golangorg/godoc/redirect/redirect_test.go
deleted file mode 100644
index 804bfb0..0000000
--- a/cmd/golangorg/godoc/redirect/redirect_test.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package redirect
-
-import (
-	"net/http"
-	"net/http/httptest"
-	"testing"
-)
-
-type redirectResult struct {
-	status int
-	path   string
-}
-
-func errorResult(status int) redirectResult {
-	return redirectResult{status, ""}
-}
-
-func TestRedirects(t *testing.T) {
-	var tests = map[string]redirectResult{
-		"/build":    {301, "http://build.golang.org"},
-		"/ref":      {301, "/doc/#references"},
-		"/doc/mem":  {301, "/ref/mem"},
-		"/doc/spec": {301, "/ref/spec"},
-		"/tour":     {301, "http://tour.golang.org"},
-		"/foo":      errorResult(404),
-
-		"/pkg/asn1":           {301, "/pkg/encoding/asn1/"},
-		"/pkg/template/parse": {301, "/pkg/text/template/parse/"},
-
-		"/src/pkg/foo": {301, "/src/foo"},
-
-		"/cmd/gofix": {301, "/cmd/fix/"},
-
-		// git commits (/change)
-		// TODO: mercurial tags and LoadChangeMap.
-		"/change":   {301, "https://go.googlesource.com/go"},
-		"/change/a": {302, "https://go.googlesource.com/go/+/a"},
-
-		"/issue":                    {301, "https://github.com/golang/go/issues"},
-		"/issue?":                   {301, "https://github.com/golang/go/issues"},
-		"/issue/1":                  {302, "https://github.com/golang/go/issues/1"},
-		"/issue/new":                {301, "https://github.com/golang/go/issues/new"},
-		"/issue/new?a=b&c=d%20&e=f": {301, "https://github.com/golang/go/issues/new?a=b&c=d%20&e=f"},
-		"/issues":                   {301, "https://github.com/golang/go/issues"},
-		"/issues/1":                 {302, "https://github.com/golang/go/issues/1"},
-		"/issues/new":               {301, "https://github.com/golang/go/issues/new"},
-		"/issues/1/2/3":             errorResult(404),
-
-		"/wiki/foo":  {302, "https://github.com/golang/go/wiki/foo"},
-		"/wiki/foo/": {302, "https://github.com/golang/go/wiki/foo/"},
-
-		"/design":              {301, "https://go.googlesource.com/proposal/+/master/design"},
-		"/design/":             {302, "/design"},
-		"/design/123-foo":      {302, "https://go.googlesource.com/proposal/+/master/design/123-foo.md"},
-		"/design/text/123-foo": {302, "https://go.googlesource.com/proposal/+/master/design/text/123-foo.md"},
-
-		"/cl/1":          {302, "https://go-review.googlesource.com/1"},
-		"/cl/1/":         {302, "https://go-review.googlesource.com/1"},
-		"/cl/267120043":  {302, "https://codereview.appspot.com/267120043"},
-		"/cl/267120043/": {302, "https://codereview.appspot.com/267120043"},
-
-		// Verify that we're using the Rietveld CL table:
-		"/cl/152046": {302, "https://codereview.appspot.com/152046"},
-		"/cl/152047": {302, "https://go-review.googlesource.com/152047"},
-		"/cl/152048": {302, "https://codereview.appspot.com/152048"},
-
-		// And verify we're using the the "bigEnoughAssumeRietveld" value:
-		"/cl/299999": {302, "https://go-review.googlesource.com/299999"},
-		"/cl/300000": {302, "https://codereview.appspot.com/300000"},
-	}
-
-	mux := http.NewServeMux()
-	Register(mux)
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-
-	for path, want := range tests {
-		if want.path != "" && want.path[0] == '/' {
-			// All redirects are absolute.
-			want.path = ts.URL + want.path
-		}
-
-		req, err := http.NewRequest("GET", ts.URL+path, nil)
-		if err != nil {
-			t.Errorf("(path: %q) unexpected error: %v", path, err)
-			continue
-		}
-
-		resp, err := http.DefaultTransport.RoundTrip(req)
-		if err != nil {
-			t.Errorf("(path: %q) unexpected error: %v", path, err)
-			continue
-		}
-
-		if resp.StatusCode != want.status {
-			t.Errorf("(path: %q) got status %d, want %d", path, resp.StatusCode, want.status)
-		}
-
-		if want.status != 301 && want.status != 302 {
-			// Not a redirect. Just check status.
-			continue
-		}
-
-		out, _ := resp.Location()
-		if got := out.String(); got != want.path {
-			t.Errorf("(path: %q) got %s, want %s", path, got, want.path)
-		}
-	}
-}
diff --git a/cmd/golangorg/godoc/redirect/rietveld.go b/cmd/golangorg/godoc/redirect/rietveld.go
deleted file mode 100644
index 81b1094..0000000
--- a/cmd/golangorg/godoc/redirect/rietveld.go
+++ /dev/null
@@ -1,1093 +0,0 @@
-// 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.
-
-package redirect
-
-// bigEnoughAssumeRietveld is the value where CLs equal or great are
-// assumed to be on Rietveld. By including this threshold we shrink
-// the size of the table below. When Go amasses 150,000 more CLs, we'll
-// need to bump this number and regenerate the list below.
-const bigEnoughAssumeRietveld = 300000
-
-// isRietveldCL reports whether cl was a Rietveld CL number.
-func isRietveldCL(cl int) bool {
-	return cl >= bigEnoughAssumeRietveld || lowRietveldCL[cl]
-}
-
-// lowRietveldCLs are the old CL numbers assigned by Rietveld code
-// review system as used by Go prior to Gerrit which are less than
-// bigEnoughAssumeRietveld.
-//
-// This list of numbers is registered with the /cl/NNNN redirect
-// handler to disambiguate which code review system a particular
-// number corresponds to. In some rare cases there may be duplicates,
-// in which case we might render an HTML choice for the user.
-//
-// To re-generate this list, run:
-//
-// $ cd $GOROOT
-// $ git log 7d7c6a9..94151eb | grep "^    https://golang.org/cl/" | perl -ne 's,^\s+https://golang.org/cl/(\d+).*$,$1,; chomp; print "$_: true,\n" if $_ < 300000' | sort -n | uniq
-//
-// Note that we ignore the x/* repos because we didn't start using
-// "subrepos" until the Rietveld CLs numbers were already 4,000,000+,
-// well above bigEnoughAssumeRietveld.
-var lowRietveldCL = map[int]bool{
-	152046: true,
-	152048: true,
-	152049: true,
-	152050: true,
-	152051: true,
-	152052: true,
-	152055: true,
-	152056: true,
-	152057: true,
-	152072: true,
-	152073: true,
-	152075: true,
-	152076: true,
-	152077: true,
-	152078: true,
-	152079: true,
-	152080: true,
-	152082: true,
-	152084: true,
-	152085: true,
-	152086: true,
-	152088: true,
-	152089: true,
-	152091: true,
-	152098: true,
-	152101: true,
-	152102: true,
-	152105: true,
-	152106: true,
-	152107: true,
-	152108: true,
-	152109: true,
-	152110: true,
-	152114: true,
-	152117: true,
-	152118: true,
-	152120: true,
-	152123: true,
-	152124: true,
-	152128: true,
-	152130: true,
-	152131: true,
-	152138: true,
-	152141: true,
-	152142: true,
-	153048: true,
-	153049: true,
-	153050: true,
-	153051: true,
-	153055: true,
-	153056: true,
-	153057: true,
-	154043: true,
-	154044: true,
-	154045: true,
-	154049: true,
-	154055: true,
-	154057: true,
-	154058: true,
-	154059: true,
-	154061: true,
-	154064: true,
-	154065: true,
-	154067: true,
-	154068: true,
-	154069: true,
-	154071: true,
-	154072: true,
-	154073: true,
-	154076: true,
-	154079: true,
-	154096: true,
-	154097: true,
-	154099: true,
-	154100: true,
-	154101: true,
-	154102: true,
-	154108: true,
-	154118: true,
-	154121: true,
-	154122: true,
-	154123: true,
-	154125: true,
-	154126: true,
-	154128: true,
-	154136: true,
-	154138: true,
-	154139: true,
-	154140: true,
-	154141: true,
-	154142: true,
-	154143: true,
-	154144: true,
-	154145: true,
-	154146: true,
-	154152: true,
-	154153: true,
-	154156: true,
-	154159: true,
-	154161: true,
-	154166: true,
-	154167: true,
-	154169: true,
-	154171: true,
-	154172: true,
-	154173: true,
-	154174: true,
-	154175: true,
-	154176: true,
-	154177: true,
-	154178: true,
-	154179: true,
-	154180: true,
-	155041: true,
-	155042: true,
-	155045: true,
-	155047: true,
-	155048: true,
-	155049: true,
-	155050: true,
-	155054: true,
-	155055: true,
-	155056: true,
-	155057: true,
-	155058: true,
-	155059: true,
-	155061: true,
-	155062: true,
-	155063: true,
-	155065: true,
-	155067: true,
-	155069: true,
-	155072: true,
-	155074: true,
-	155075: true,
-	155077: true,
-	155078: true,
-	155079: true,
-	156041: true,
-	156044: true,
-	156045: true,
-	156046: true,
-	156047: true,
-	156051: true,
-	156052: true,
-	156054: true,
-	156055: true,
-	156056: true,
-	156058: true,
-	156059: true,
-	156060: true,
-	156061: true,
-	156062: true,
-	156063: true,
-	156066: true,
-	156067: true,
-	156070: true,
-	156071: true,
-	156073: true,
-	156075: true,
-	156077: true,
-	156079: true,
-	156080: true,
-	156081: true,
-	156083: true,
-	156084: true,
-	156085: true,
-	156086: true,
-	156089: true,
-	156091: true,
-	156092: true,
-	156093: true,
-	156094: true,
-	156097: true,
-	156099: true,
-	156100: true,
-	156102: true,
-	156103: true,
-	156104: true,
-	156106: true,
-	156107: true,
-	156108: true,
-	156109: true,
-	156110: true,
-	156113: true,
-	156115: true,
-	156116: true,
-	157041: true,
-	157042: true,
-	157043: true,
-	157044: true,
-	157046: true,
-	157053: true,
-	157055: true,
-	157056: true,
-	157058: true,
-	157060: true,
-	157061: true,
-	157062: true,
-	157065: true,
-	157066: true,
-	157067: true,
-	157068: true,
-	157069: true,
-	157071: true,
-	157072: true,
-	157073: true,
-	157074: true,
-	157075: true,
-	157076: true,
-	157077: true,
-	157082: true,
-	157084: true,
-	157085: true,
-	157087: true,
-	157088: true,
-	157091: true,
-	157095: true,
-	157096: true,
-	157099: true,
-	157100: true,
-	157101: true,
-	157102: true,
-	157103: true,
-	157104: true,
-	157106: true,
-	157110: true,
-	157111: true,
-	157112: true,
-	157114: true,
-	157116: true,
-	157119: true,
-	157140: true,
-	157142: true,
-	157143: true,
-	157144: true,
-	157146: true,
-	157147: true,
-	157149: true,
-	157151: true,
-	157152: true,
-	157153: true,
-	157154: true,
-	157156: true,
-	157157: true,
-	157158: true,
-	157159: true,
-	157160: true,
-	157162: true,
-	157166: true,
-	157167: true,
-	157168: true,
-	157170: true,
-	158041: true,
-	159044: true,
-	159049: true,
-	159050: true,
-	159051: true,
-	160043: true,
-	160044: true,
-	160045: true,
-	160046: true,
-	160047: true,
-	160054: true,
-	160056: true,
-	160057: true,
-	160059: true,
-	160060: true,
-	160061: true,
-	160064: true,
-	160065: true,
-	160069: true,
-	160070: true,
-	161049: true,
-	161050: true,
-	161056: true,
-	161058: true,
-	161060: true,
-	161061: true,
-	161069: true,
-	161070: true,
-	161073: true,
-	161075: true,
-	162041: true,
-	162044: true,
-	162046: true,
-	162053: true,
-	162054: true,
-	162055: true,
-	162056: true,
-	162057: true,
-	162058: true,
-	162059: true,
-	162061: true,
-	162062: true,
-	163042: true,
-	163044: true,
-	163049: true,
-	163050: true,
-	163051: true,
-	163052: true,
-	163053: true,
-	163055: true,
-	163058: true,
-	163061: true,
-	163062: true,
-	163064: true,
-	163067: true,
-	163068: true,
-	163069: true,
-	163070: true,
-	163071: true,
-	163072: true,
-	163082: true,
-	163083: true,
-	163085: true,
-	163088: true,
-	163091: true,
-	163092: true,
-	163097: true,
-	163098: true,
-	164043: true,
-	164047: true,
-	164049: true,
-	164052: true,
-	164053: true,
-	164056: true,
-	164059: true,
-	164060: true,
-	164062: true,
-	164068: true,
-	164069: true,
-	164071: true,
-	164073: true,
-	164074: true,
-	164075: true,
-	164078: true,
-	164079: true,
-	164081: true,
-	164082: true,
-	164083: true,
-	164085: true,
-	164086: true,
-	164088: true,
-	164090: true,
-	164091: true,
-	164092: true,
-	164093: true,
-	164094: true,
-	164095: true,
-	165042: true,
-	165044: true,
-	165045: true,
-	165048: true,
-	165049: true,
-	165050: true,
-	165051: true,
-	165055: true,
-	165057: true,
-	165058: true,
-	165059: true,
-	165061: true,
-	165062: true,
-	165063: true,
-	165064: true,
-	165065: true,
-	165068: true,
-	165070: true,
-	165076: true,
-	165078: true,
-	165080: true,
-	165083: true,
-	165086: true,
-	165097: true,
-	165100: true,
-	165101: true,
-	166041: true,
-	166043: true,
-	166044: true,
-	166047: true,
-	166049: true,
-	166052: true,
-	166053: true,
-	166055: true,
-	166058: true,
-	166059: true,
-	166060: true,
-	166064: true,
-	166066: true,
-	166067: true,
-	166068: true,
-	166070: true,
-	166071: true,
-	166072: true,
-	166073: true,
-	166074: true,
-	166076: true,
-	166077: true,
-	166078: true,
-	166080: true,
-	167043: true,
-	167044: true,
-	167047: true,
-	167050: true,
-	167055: true,
-	167057: true,
-	167058: true,
-	168041: true,
-	168045: true,
-	170042: true,
-	170043: true,
-	170044: true,
-	170046: true,
-	170047: true,
-	170048: true,
-	170049: true,
-	171044: true,
-	171046: true,
-	171047: true,
-	171048: true,
-	171051: true,
-	172041: true,
-	172042: true,
-	172043: true,
-	172045: true,
-	172049: true,
-	173041: true,
-	173044: true,
-	173045: true,
-	174042: true,
-	174047: true,
-	174048: true,
-	174050: true,
-	174051: true,
-	174052: true,
-	174053: true,
-	174063: true,
-	174064: true,
-	174072: true,
-	174076: true,
-	174077: true,
-	174078: true,
-	174082: true,
-	174083: true,
-	174087: true,
-	175045: true,
-	175046: true,
-	175047: true,
-	175048: true,
-	176056: true,
-	176057: true,
-	176058: true,
-	176061: true,
-	176062: true,
-	176063: true,
-	176064: true,
-	176066: true,
-	176067: true,
-	176070: true,
-	176071: true,
-	176076: true,
-	178043: true,
-	178044: true,
-	178046: true,
-	178048: true,
-	179047: true,
-	179055: true,
-	179061: true,
-	179062: true,
-	179063: true,
-	179067: true,
-	179069: true,
-	179070: true,
-	179072: true,
-	179079: true,
-	179088: true,
-	179095: true,
-	179096: true,
-	179097: true,
-	179099: true,
-	179105: true,
-	179106: true,
-	179108: true,
-	179118: true,
-	179120: true,
-	179125: true,
-	179126: true,
-	179128: true,
-	179129: true,
-	179130: true,
-	180044: true,
-	180045: true,
-	180046: true,
-	180047: true,
-	180048: true,
-	180049: true,
-	180050: true,
-	180052: true,
-	180053: true,
-	180054: true,
-	180055: true,
-	180056: true,
-	180057: true,
-	180059: true,
-	180061: true,
-	180064: true,
-	180065: true,
-	180068: true,
-	180069: true,
-	180070: true,
-	180074: true,
-	180075: true,
-	180081: true,
-	180082: true,
-	180085: true,
-	180092: true,
-	180099: true,
-	180105: true,
-	180108: true,
-	180112: true,
-	180118: true,
-	181041: true,
-	181043: true,
-	181044: true,
-	181045: true,
-	181049: true,
-	181050: true,
-	181055: true,
-	181057: true,
-	181058: true,
-	181059: true,
-	181063: true,
-	181071: true,
-	181073: true,
-	181075: true,
-	181077: true,
-	181080: true,
-	181083: true,
-	181084: true,
-	181085: true,
-	181086: true,
-	181087: true,
-	181089: true,
-	181097: true,
-	181099: true,
-	181102: true,
-	181111: true,
-	181130: true,
-	181135: true,
-	181137: true,
-	181138: true,
-	181139: true,
-	181151: true,
-	181152: true,
-	181153: true,
-	181155: true,
-	181156: true,
-	181157: true,
-	181158: true,
-	181160: true,
-	181161: true,
-	181163: true,
-	181164: true,
-	181171: true,
-	181179: true,
-	181183: true,
-	181184: true,
-	181186: true,
-	182041: true,
-	182043: true,
-	182044: true,
-	183042: true,
-	183043: true,
-	183044: true,
-	183047: true,
-	183049: true,
-	183065: true,
-	183066: true,
-	183073: true,
-	183074: true,
-	183075: true,
-	183083: true,
-	183084: true,
-	183087: true,
-	183088: true,
-	183090: true,
-	183095: true,
-	183104: true,
-	183107: true,
-	183109: true,
-	183111: true,
-	183112: true,
-	183113: true,
-	183116: true,
-	183123: true,
-	183124: true,
-	183125: true,
-	183126: true,
-	183132: true,
-	183133: true,
-	183135: true,
-	183136: true,
-	183137: true,
-	183138: true,
-	183139: true,
-	183140: true,
-	183141: true,
-	183142: true,
-	183153: true,
-	183155: true,
-	183156: true,
-	183157: true,
-	183160: true,
-	184043: true,
-	184055: true,
-	184058: true,
-	184059: true,
-	184068: true,
-	184069: true,
-	184079: true,
-	184080: true,
-	184081: true,
-	185043: true,
-	185045: true,
-	186042: true,
-	186043: true,
-	186073: true,
-	186076: true,
-	186077: true,
-	186078: true,
-	186079: true,
-	186081: true,
-	186095: true,
-	186108: true,
-	186113: true,
-	186115: true,
-	186116: true,
-	186118: true,
-	186119: true,
-	186132: true,
-	186137: true,
-	186138: true,
-	186139: true,
-	186143: true,
-	186144: true,
-	186145: true,
-	186146: true,
-	186147: true,
-	186148: true,
-	186159: true,
-	186160: true,
-	186161: true,
-	186165: true,
-	186169: true,
-	186173: true,
-	186180: true,
-	186210: true,
-	186211: true,
-	186212: true,
-	186213: true,
-	186214: true,
-	186215: true,
-	186216: true,
-	186228: true,
-	186229: true,
-	186230: true,
-	186232: true,
-	186234: true,
-	186255: true,
-	186263: true,
-	186276: true,
-	186279: true,
-	186282: true,
-	186283: true,
-	188043: true,
-	189042: true,
-	189057: true,
-	189059: true,
-	189062: true,
-	189078: true,
-	189080: true,
-	189083: true,
-	189088: true,
-	189093: true,
-	189095: true,
-	189096: true,
-	189098: true,
-	189100: true,
-	190041: true,
-	190042: true,
-	190043: true,
-	190044: true,
-	190059: true,
-	190062: true,
-	190068: true,
-	190074: true,
-	190076: true,
-	190077: true,
-	190079: true,
-	190085: true,
-	190088: true,
-	190103: true,
-	190104: true,
-	193055: true,
-	193066: true,
-	193067: true,
-	193070: true,
-	193075: true,
-	193079: true,
-	193080: true,
-	193081: true,
-	193091: true,
-	193092: true,
-	193095: true,
-	193101: true,
-	193104: true,
-	194043: true,
-	194045: true,
-	194046: true,
-	194050: true,
-	194051: true,
-	194052: true,
-	194053: true,
-	194064: true,
-	194066: true,
-	194069: true,
-	194071: true,
-	194072: true,
-	194073: true,
-	194074: true,
-	194076: true,
-	194077: true,
-	194078: true,
-	194082: true,
-	194084: true,
-	194085: true,
-	194090: true,
-	194091: true,
-	194092: true,
-	194094: true,
-	194097: true,
-	194098: true,
-	194099: true,
-	194100: true,
-	194114: true,
-	194116: true,
-	194118: true,
-	194119: true,
-	194120: true,
-	194121: true,
-	194122: true,
-	194126: true,
-	194129: true,
-	194131: true,
-	194132: true,
-	194133: true,
-	194134: true,
-	194146: true,
-	194151: true,
-	194156: true,
-	194157: true,
-	194159: true,
-	194161: true,
-	194165: true,
-	195041: true,
-	195044: true,
-	195050: true,
-	195051: true,
-	195052: true,
-	195068: true,
-	195075: true,
-	195076: true,
-	195079: true,
-	195080: true,
-	195081: true,
-	196042: true,
-	196044: true,
-	196050: true,
-	196051: true,
-	196055: true,
-	196056: true,
-	196061: true,
-	196063: true,
-	196065: true,
-	196070: true,
-	196071: true,
-	196075: true,
-	196077: true,
-	196079: true,
-	196087: true,
-	196088: true,
-	196090: true,
-	196091: true,
-	197041: true,
-	197042: true,
-	197043: true,
-	197044: true,
-	198044: true,
-	198045: true,
-	198046: true,
-	198048: true,
-	198049: true,
-	198050: true,
-	198053: true,
-	198057: true,
-	198058: true,
-	198066: true,
-	198071: true,
-	198074: true,
-	198081: true,
-	198084: true,
-	198085: true,
-	198102: true,
-	199042: true,
-	199044: true,
-	199045: true,
-	199046: true,
-	199047: true,
-	199052: true,
-	199054: true,
-	199057: true,
-	199066: true,
-	199070: true,
-	199082: true,
-	199091: true,
-	199094: true,
-	199096: true,
-	201041: true,
-	201042: true,
-	201043: true,
-	201047: true,
-	201048: true,
-	201049: true,
-	201058: true,
-	201061: true,
-	201064: true,
-	201065: true,
-	201068: true,
-	202042: true,
-	202043: true,
-	202044: true,
-	202051: true,
-	202054: true,
-	202055: true,
-	203043: true,
-	203050: true,
-	203051: true,
-	203053: true,
-	203060: true,
-	203062: true,
-	204042: true,
-	204044: true,
-	204048: true,
-	204052: true,
-	204053: true,
-	204061: true,
-	204062: true,
-	204064: true,
-	204065: true,
-	204067: true,
-	204068: true,
-	204069: true,
-	205042: true,
-	205044: true,
-	206043: true,
-	206044: true,
-	206047: true,
-	206050: true,
-	206051: true,
-	206052: true,
-	206053: true,
-	206054: true,
-	206055: true,
-	206058: true,
-	206059: true,
-	206060: true,
-	206067: true,
-	206069: true,
-	206077: true,
-	206078: true,
-	206079: true,
-	206084: true,
-	206089: true,
-	206101: true,
-	206107: true,
-	206109: true,
-	207043: true,
-	207044: true,
-	207049: true,
-	207050: true,
-	207051: true,
-	207052: true,
-	207053: true,
-	207054: true,
-	207055: true,
-	207061: true,
-	207062: true,
-	207069: true,
-	207071: true,
-	207085: true,
-	207086: true,
-	207087: true,
-	207088: true,
-	207095: true,
-	207096: true,
-	207102: true,
-	207103: true,
-	207106: true,
-	207108: true,
-	207110: true,
-	207111: true,
-	207112: true,
-	209041: true,
-	209042: true,
-	209043: true,
-	209044: true,
-	210042: true,
-	210043: true,
-	210044: true,
-	210047: true,
-	211041: true,
-	212041: true,
-	212045: true,
-	212046: true,
-	212047: true,
-	213041: true,
-	213042: true,
-	214042: true,
-	214046: true,
-	214049: true,
-	214050: true,
-	215042: true,
-	215048: true,
-	215050: true,
-	216043: true,
-	216046: true,
-	216047: true,
-	216052: true,
-	216053: true,
-	216054: true,
-	216059: true,
-	216068: true,
-	217041: true,
-	217044: true,
-	217047: true,
-	217048: true,
-	217049: true,
-	217056: true,
-	217058: true,
-	217059: true,
-	217060: true,
-	217061: true,
-	217064: true,
-	217066: true,
-	217069: true,
-	217071: true,
-	217085: true,
-	217086: true,
-	217088: true,
-	217093: true,
-	217094: true,
-	217108: true,
-	217109: true,
-	217111: true,
-	217115: true,
-	217116: true,
-	218042: true,
-	218044: true,
-	218046: true,
-	218050: true,
-	218060: true,
-	218061: true,
-	218063: true,
-	218064: true,
-	218065: true,
-	218070: true,
-	218071: true,
-	218072: true,
-	218074: true,
-	218076: true,
-	222041: true,
-	223041: true,
-	223043: true,
-	223044: true,
-	223050: true,
-	223052: true,
-	223054: true,
-	223058: true,
-	223059: true,
-	223061: true,
-	223068: true,
-	223069: true,
-	223070: true,
-	223071: true,
-	223073: true,
-	223075: true,
-	223076: true,
-	223083: true,
-	223087: true,
-	223094: true,
-	223096: true,
-	223101: true,
-	223106: true,
-	223108: true,
-	224041: true,
-	224042: true,
-	224043: true,
-	224045: true,
-	224051: true,
-	224053: true,
-	224057: true,
-	224060: true,
-	224061: true,
-	224062: true,
-	224063: true,
-	224068: true,
-	224069: true,
-	224081: true,
-	224084: true,
-	224087: true,
-	224090: true,
-	224096: true,
-	224105: true,
-	225042: true,
-	227041: true,
-	229045: true,
-	229046: true,
-	229048: true,
-	229049: true,
-	229050: true,
-	231042: true,
-	236041: true,
-	237041: true,
-	238041: true,
-	238042: true,
-	240041: true,
-	240042: true,
-	240043: true,
-	241041: true,
-	243041: true,
-	244041: true,
-	245041: true,
-	247041: true,
-	250041: true,
-	252041: true,
-	253041: true,
-	253045: true,
-	254043: true,
-	255042: true,
-	255043: true,
-	257041: true,
-	257042: true,
-	258041: true,
-	261041: true,
-	264041: true,
-	294042: true,
-	296042: true,
-}
diff --git a/cmd/golangorg/godoc/search.go b/cmd/golangorg/godoc/search.go
deleted file mode 100644
index 0e7509a..0000000
--- a/cmd/golangorg/godoc/search.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"bytes"
-	"fmt"
-	"net/http"
-	"regexp"
-	"strings"
-)
-
-type SearchResult struct {
-	Query string
-	Alert string // error or warning message
-
-	// identifier matches
-	Pak HitList       // packages matching Query
-	Hit *LookupResult // identifier matches of Query
-	Alt *AltWords     // alternative identifiers to look for
-
-	// textual matches
-	Found    int         // number of textual occurrences found
-	Textual  []FileLines // textual matches of Query
-	Complete bool        // true if all textual occurrences of Query are reported
-	Idents   map[SpotKind][]Ident
-}
-
-func (c *Corpus) Lookup(query string) SearchResult {
-	result := &SearchResult{Query: query}
-
-	index, timestamp := c.CurrentIndex()
-	if index != nil {
-		// identifier search
-		if r, err := index.Lookup(query); err == nil {
-			result = r
-		} else if err != nil && !c.IndexFullText {
-			// ignore the error if full text search is enabled
-			// since the query may be a valid regular expression
-			result.Alert = "Error in query string: " + err.Error()
-			return *result
-		}
-
-		// full text search
-		if c.IndexFullText && query != "" {
-			rx, err := regexp.Compile(query)
-			if err != nil {
-				result.Alert = "Error in query regular expression: " + err.Error()
-				return *result
-			}
-			// If we get maxResults+1 results we know that there are more than
-			// maxResults results and thus the result may be incomplete (to be
-			// precise, we should remove one result from the result set, but
-			// nobody is going to count the results on the result page).
-			result.Found, result.Textual = index.LookupRegexp(rx, c.MaxResults+1)
-			result.Complete = result.Found <= c.MaxResults
-			if !result.Complete {
-				result.Found-- // since we looked for maxResults+1
-			}
-		}
-	}
-
-	// is the result accurate?
-	if c.IndexEnabled {
-		if ts := c.FSModifiedTime(); timestamp.Before(ts) {
-			// The index is older than the latest file system change under godoc's observation.
-			result.Alert = "Indexing in progress: result may be inaccurate"
-		}
-	} else {
-		result.Alert = "Search index disabled: no results available"
-	}
-
-	return *result
-}
-
-// SearchResultDoc optionally specifies a function returning an HTML body
-// displaying search results matching godoc documentation.
-func (p *Presentation) SearchResultDoc(result SearchResult) []byte {
-	return applyTemplate(p.SearchDocHTML, "searchDocHTML", result)
-}
-
-// SearchResultCode optionally specifies a function returning an HTML body
-// displaying search results matching source code.
-func (p *Presentation) SearchResultCode(result SearchResult) []byte {
-	return applyTemplate(p.SearchCodeHTML, "searchCodeHTML", result)
-}
-
-// SearchResultTxt optionally specifies a function returning an HTML body
-// displaying search results of textual matches.
-func (p *Presentation) SearchResultTxt(result SearchResult) []byte {
-	return applyTemplate(p.SearchTxtHTML, "searchTxtHTML", result)
-}
-
-// HandleSearch obtains results for the requested search and returns a page
-// to display them.
-func (p *Presentation) HandleSearch(w http.ResponseWriter, r *http.Request) {
-	query := strings.TrimSpace(r.FormValue("q"))
-	result := p.Corpus.Lookup(query)
-
-	var contents bytes.Buffer
-	for _, f := range p.SearchResults {
-		contents.Write(f(p, result))
-	}
-
-	var title string
-	if haveResults := contents.Len() > 0; haveResults {
-		title = fmt.Sprintf(`Results for query: %v`, query)
-		if !p.Corpus.IndexEnabled {
-			result.Alert = ""
-		}
-	} else {
-		title = fmt.Sprintf(`No results found for query %q`, query)
-	}
-
-	body := bytes.NewBuffer(applyTemplate(p.SearchHTML, "searchHTML", result))
-	body.Write(contents.Bytes())
-
-	p.ServePage(w, Page{
-		Title:    title,
-		Tabtitle: query,
-		Query:    query,
-		Body:     body.Bytes(),
-		GoogleCN: googleCN(r),
-	})
-}
-
-func (p *Presentation) serveSearchDesc(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "application/opensearchdescription+xml")
-	data := map[string]interface{}{
-		"BaseURL": fmt.Sprintf("http://%s", r.Host),
-	}
-	applyTemplateToResponseWriter(w, p.SearchDescXML, &data)
-}
-
-// tocColCount returns the no. of columns
-// to split the toc table to.
-func tocColCount(result SearchResult) int {
-	tocLen := tocLen(result)
-	colCount := 0
-	// Simple heuristic based on visual aesthetic in manual testing.
-	switch {
-	case tocLen <= 10:
-		colCount = 1
-	case tocLen <= 20:
-		colCount = 2
-	case tocLen <= 80:
-		colCount = 3
-	default:
-		colCount = 4
-	}
-	return colCount
-}
-
-// tocLen calculates the no. of items in the toc table
-// by going through various fields in the SearchResult
-// that is rendered in the UI.
-func tocLen(result SearchResult) int {
-	tocLen := 0
-	for _, val := range result.Idents {
-		if len(val) != 0 {
-			tocLen++
-		}
-	}
-	// If no identifiers, then just one item for the header text "Package <result.Query>".
-	// See searchcode.html for further details.
-	if len(result.Idents) == 0 {
-		tocLen++
-	}
-	if result.Hit != nil {
-		if len(result.Hit.Decls) > 0 {
-			tocLen += len(result.Hit.Decls)
-			// We need one extra item for the header text "Package-level declarations".
-			tocLen++
-		}
-		if len(result.Hit.Others) > 0 {
-			tocLen += len(result.Hit.Others)
-			// We need one extra item for the header text "Local declarations and uses".
-			tocLen++
-		}
-	}
-	// For "textual occurrences".
-	tocLen++
-	return tocLen
-}
diff --git a/cmd/golangorg/godoc/server.go b/cmd/golangorg/godoc/server.go
deleted file mode 100644
index 5494fe4..0000000
--- a/cmd/golangorg/godoc/server.go
+++ /dev/null
@@ -1,836 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-import (
-	"bytes"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"go/ast"
-	"go/build"
-	"go/doc"
-	"go/token"
-	htmlpkg "html"
-	htmltemplate "html/template"
-	"io"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"os"
-	pathpkg "path"
-	"path/filepath"
-	"sort"
-	"strings"
-	"text/template"
-	"time"
-
-	"golang.org/x/website/cmd/golangorg/godoc/analysis"
-	"golang.org/x/website/cmd/golangorg/godoc/util"
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// handlerServer is a migration from an old godoc http Handler type.
-// This should probably merge into something else.
-type handlerServer struct {
-	p           *Presentation
-	c           *Corpus  // copy of p.Corpus
-	pattern     string   // url pattern; e.g. "/pkg/"
-	stripPrefix string   // prefix to strip from import path; e.g. "pkg/"
-	fsRoot      string   // file system root to which the pattern is mapped; e.g. "/src"
-	exclude     []string // file system paths to exclude; e.g. "/src/cmd"
-}
-
-func (s *handlerServer) registerWithMux(mux *http.ServeMux) {
-	mux.Handle(s.pattern, s)
-}
-
-// getPageInfo returns the PageInfo for a package directory abspath. If the
-// parameter genAST is set, an AST containing only the package exports is
-// computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc)
-// is extracted from the AST. If there is no corresponding package in the
-// directory, PageInfo.PAst and PageInfo.PDoc are nil. If there are no sub-
-// directories, PageInfo.Dirs is nil. If an error occurred, PageInfo.Err is
-// set to the respective error but the error is not logged.
-//
-func (h *handlerServer) GetPageInfo(abspath, relpath string, mode PageInfoMode, goos, goarch string) *PageInfo {
-	info := &PageInfo{Dirname: abspath, Mode: mode}
-
-	// Restrict to the package files that would be used when building
-	// the package on this system.  This makes sure that if there are
-	// separate implementations for, say, Windows vs Unix, we don't
-	// jumble them all together.
-	// Note: If goos/goarch aren't set, the current binary's GOOS/GOARCH
-	// are used.
-	ctxt := build.Default
-	ctxt.IsAbsPath = pathpkg.IsAbs
-	ctxt.IsDir = func(path string) bool {
-		fi, err := h.c.fs.Stat(filepath.ToSlash(path))
-		return err == nil && fi.IsDir()
-	}
-	ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) {
-		f, err := h.c.fs.ReadDir(filepath.ToSlash(dir))
-		filtered := make([]os.FileInfo, 0, len(f))
-		for _, i := range f {
-			if mode&NoFiltering != 0 || i.Name() != "internal" {
-				filtered = append(filtered, i)
-			}
-		}
-		return filtered, err
-	}
-	ctxt.OpenFile = func(name string) (r io.ReadCloser, err error) {
-		data, err := vfs.ReadFile(h.c.fs, filepath.ToSlash(name))
-		if err != nil {
-			return nil, err
-		}
-		return ioutil.NopCloser(bytes.NewReader(data)), nil
-	}
-
-	// Make the syscall/js package always visible by default.
-	// It defaults to the host's GOOS/GOARCH, and golang.org's
-	// linux/amd64 means the wasm syscall/js package was blank.
-	// And you can't run godoc on js/wasm anyway, so host defaults
-	// don't make sense here.
-	if goos == "" && goarch == "" && relpath == "syscall/js" {
-		goos, goarch = "js", "wasm"
-	}
-	if goos != "" {
-		ctxt.GOOS = goos
-	}
-	if goarch != "" {
-		ctxt.GOARCH = goarch
-	}
-
-	pkginfo, err := ctxt.ImportDir(abspath, 0)
-	// continue if there are no Go source files; we still want the directory info
-	if _, nogo := err.(*build.NoGoError); err != nil && !nogo {
-		info.Err = err
-		return info
-	}
-
-	// collect package files
-	pkgname := pkginfo.Name
-	pkgfiles := append(pkginfo.GoFiles, pkginfo.CgoFiles...)
-	if len(pkgfiles) == 0 {
-		// Commands written in C have no .go files in the build.
-		// Instead, documentation may be found in an ignored file.
-		// The file may be ignored via an explicit +build ignore
-		// constraint (recommended), or by defining the package
-		// documentation (historic).
-		pkgname = "main" // assume package main since pkginfo.Name == ""
-		pkgfiles = pkginfo.IgnoredGoFiles
-	}
-
-	// get package information, if any
-	if len(pkgfiles) > 0 {
-		// build package AST
-		fset := token.NewFileSet()
-		files, err := h.c.parseFiles(fset, relpath, abspath, pkgfiles)
-		if err != nil {
-			info.Err = err
-			return info
-		}
-
-		// ignore any errors - they are due to unresolved identifiers
-		pkg, _ := ast.NewPackage(fset, files, poorMansImporter, nil)
-
-		// extract package documentation
-		info.FSet = fset
-		if mode&ShowSource == 0 {
-			// show extracted documentation
-			var m doc.Mode
-			if mode&NoFiltering != 0 {
-				m |= doc.AllDecls
-			}
-			if mode&AllMethods != 0 {
-				m |= doc.AllMethods
-			}
-			info.PDoc = doc.New(pkg, pathpkg.Clean(relpath), m) // no trailing '/' in importpath
-			if mode&NoTypeAssoc != 0 {
-				for _, t := range info.PDoc.Types {
-					info.PDoc.Consts = append(info.PDoc.Consts, t.Consts...)
-					info.PDoc.Vars = append(info.PDoc.Vars, t.Vars...)
-					info.PDoc.Funcs = append(info.PDoc.Funcs, t.Funcs...)
-					t.Consts = nil
-					t.Vars = nil
-					t.Funcs = nil
-				}
-				// for now we cannot easily sort consts and vars since
-				// go/doc.Value doesn't export the order information
-				sort.Sort(funcsByName(info.PDoc.Funcs))
-			}
-
-			// collect examples
-			testfiles := append(pkginfo.TestGoFiles, pkginfo.XTestGoFiles...)
-			files, err = h.c.parseFiles(fset, relpath, abspath, testfiles)
-			if err != nil {
-				log.Println("parsing examples:", err)
-			}
-			info.Examples = collectExamples(h.c, pkg, files)
-
-			// collect any notes that we want to show
-			if info.PDoc.Notes != nil {
-				// could regexp.Compile only once per godoc, but probably not worth it
-				if rx := h.p.NotesRx; rx != nil {
-					for m, n := range info.PDoc.Notes {
-						if rx.MatchString(m) {
-							if info.Notes == nil {
-								info.Notes = make(map[string][]*doc.Note)
-							}
-							info.Notes[m] = n
-						}
-					}
-				}
-			}
-
-		} else {
-			// show source code
-			// TODO(gri) Consider eliminating export filtering in this mode,
-			//           or perhaps eliminating the mode altogether.
-			if mode&NoFiltering == 0 {
-				packageExports(fset, pkg)
-			}
-			info.PAst = files
-		}
-		info.IsMain = pkgname == "main"
-	}
-
-	// get directory information, if any
-	var dir *Directory
-	var timestamp time.Time
-	if tree, ts := h.c.fsTree.Get(); tree != nil && tree.(*Directory) != nil {
-		// directory tree is present; lookup respective directory
-		// (may still fail if the file system was updated and the
-		// new directory tree has not yet been computed)
-		dir = tree.(*Directory).lookup(abspath)
-		timestamp = ts
-	}
-	if dir == nil {
-		// TODO(agnivade): handle this case better, now since there is no CLI mode.
-		// no directory tree present (happens in command-line mode);
-		// compute 2 levels for this page. The second level is to
-		// get the synopses of sub-directories.
-		// note: cannot use path filter here because in general
-		// it doesn't contain the FSTree path
-		dir = h.c.newDirectory(abspath, 2)
-		timestamp = time.Now()
-	}
-	info.Dirs = dir.listing(true, func(path string) bool { return h.includePath(path, mode) })
-
-	info.DirTime = timestamp
-	info.DirFlat = mode&FlatDir != 0
-
-	return info
-}
-
-func (h *handlerServer) includePath(path string, mode PageInfoMode) (r bool) {
-	// if the path is under one of the exclusion paths, don't list.
-	for _, e := range h.exclude {
-		if strings.HasPrefix(path, e) {
-			return false
-		}
-	}
-
-	// if the path includes 'internal', don't list unless we are in the NoFiltering mode.
-	if mode&NoFiltering != 0 {
-		return true
-	}
-	if strings.Contains(path, "internal") || strings.Contains(path, "vendor") {
-		for _, c := range strings.Split(filepath.Clean(path), string(os.PathSeparator)) {
-			if c == "internal" || c == "vendor" {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-type funcsByName []*doc.Func
-
-func (s funcsByName) Len() int           { return len(s) }
-func (s funcsByName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s funcsByName) Less(i, j int) bool { return s[i].Name < s[j].Name }
-
-func (h *handlerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	if redirect(w, r) {
-		return
-	}
-
-	relpath := pathpkg.Clean(r.URL.Path[len(h.stripPrefix)+1:])
-
-	if !h.corpusInitialized() {
-		h.p.ServeError(w, r, relpath, errors.New("Scan is not yet complete. Please retry after a few moments"))
-		return
-	}
-
-	abspath := pathpkg.Join(h.fsRoot, relpath)
-	mode := h.p.GetPageInfoMode(r)
-	if relpath == builtinPkgPath {
-		mode = NoFiltering | NoTypeAssoc
-	}
-	info := h.GetPageInfo(abspath, relpath, mode, r.FormValue("GOOS"), r.FormValue("GOARCH"))
-	if info.Err != nil {
-		log.Print(info.Err)
-		h.p.ServeError(w, r, relpath, info.Err)
-		return
-	}
-
-	var tabtitle, title, subtitle string
-	switch {
-	case info.PAst != nil:
-		for _, ast := range info.PAst {
-			tabtitle = ast.Name.Name
-			break
-		}
-	case info.PDoc != nil:
-		tabtitle = info.PDoc.Name
-	default:
-		tabtitle = info.Dirname
-		title = "Directory "
-		if h.p.ShowTimestamps {
-			subtitle = "Last update: " + info.DirTime.String()
-		}
-	}
-	if title == "" {
-		if info.IsMain {
-			// assume that the directory name is the command name
-			_, tabtitle = pathpkg.Split(relpath)
-			title = "Command "
-		} else {
-			title = "Package "
-		}
-	}
-	title += tabtitle
-
-	// special cases for top-level package/command directories
-	switch tabtitle {
-	case "/src":
-		title = "Packages"
-		tabtitle = "Packages"
-	case "/src/cmd":
-		title = "Commands"
-		tabtitle = "Commands"
-	}
-
-	// Emit JSON array for type information.
-	pi := h.c.Analysis.PackageInfo(relpath)
-	hasTreeView := len(pi.CallGraph) != 0
-	info.CallGraphIndex = pi.CallGraphIndex
-	info.CallGraph = htmltemplate.JS(marshalJSON(pi.CallGraph))
-	info.AnalysisData = htmltemplate.JS(marshalJSON(pi.Types))
-	info.TypeInfoIndex = make(map[string]int)
-	for i, ti := range pi.Types {
-		info.TypeInfoIndex[ti.Name] = i
-	}
-
-	info.GoogleCN = googleCN(r)
-	var body []byte
-	if info.Dirname == "/src" {
-		body = applyTemplate(h.p.PackageRootHTML, "packageRootHTML", info)
-	} else {
-		body = applyTemplate(h.p.PackageHTML, "packageHTML", info)
-	}
-	h.p.ServePage(w, Page{
-		Title:    title,
-		Tabtitle: tabtitle,
-		Subtitle: subtitle,
-		Body:     body,
-		GoogleCN: info.GoogleCN,
-		TreeView: hasTreeView,
-	})
-}
-
-func (h *handlerServer) corpusInitialized() bool {
-	h.c.initMu.RLock()
-	defer h.c.initMu.RUnlock()
-	return h.c.initDone
-}
-
-type PageInfoMode uint
-
-const (
-	PageInfoModeQueryString = "m" // query string where PageInfoMode is stored
-
-	NoFiltering PageInfoMode = 1 << iota // do not filter exports
-	AllMethods                           // show all embedded methods
-	ShowSource                           // show source code, do not extract documentation
-	NoHTML                               // show result in textual form, do not generate HTML
-	FlatDir                              // show directory in a flat (non-indented) manner
-	NoTypeAssoc                          // don't associate consts, vars, and factory functions with types
-)
-
-// modeNames defines names for each PageInfoMode flag.
-var modeNames = map[string]PageInfoMode{
-	"all":     NoFiltering,
-	"methods": AllMethods,
-	"src":     ShowSource,
-	"text":    NoHTML,
-	"flat":    FlatDir,
-}
-
-// generate a query string for persisting PageInfoMode between pages.
-func modeQueryString(mode PageInfoMode) string {
-	if modeNames := mode.names(); len(modeNames) > 0 {
-		return "?m=" + strings.Join(modeNames, ",")
-	}
-	return ""
-}
-
-// alphabetically sorted names of active flags for a PageInfoMode.
-func (m PageInfoMode) names() []string {
-	var names []string
-	for name, mode := range modeNames {
-		if m&mode != 0 {
-			names = append(names, name)
-		}
-	}
-	sort.Strings(names)
-	return names
-}
-
-// GetPageInfoMode computes the PageInfoMode flags by analyzing the request
-// URL form value "m". It is value is a comma-separated list of mode names
-// as defined by modeNames (e.g.: m=src,text).
-func (p *Presentation) GetPageInfoMode(r *http.Request) PageInfoMode {
-	var mode PageInfoMode
-	for _, k := range strings.Split(r.FormValue(PageInfoModeQueryString), ",") {
-		if m, found := modeNames[strings.TrimSpace(k)]; found {
-			mode |= m
-		}
-	}
-	if p.AdjustPageInfoMode != nil {
-		mode = p.AdjustPageInfoMode(r, mode)
-	}
-	return mode
-}
-
-// poorMansImporter returns a (dummy) package object named
-// by the last path component of the provided package path
-// (as is the convention for packages). This is sufficient
-// to resolve package identifiers without doing an actual
-// import. It never returns an error.
-//
-func poorMansImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) {
-	pkg := imports[path]
-	if pkg == nil {
-		// note that strings.LastIndex returns -1 if there is no "/"
-		pkg = ast.NewObj(ast.Pkg, path[strings.LastIndex(path, "/")+1:])
-		pkg.Data = ast.NewScope(nil) // required by ast.NewPackage for dot-import
-		imports[path] = pkg
-	}
-	return pkg, nil
-}
-
-// globalNames returns a set of the names declared by all package-level
-// declarations. Method names are returned in the form Receiver_Method.
-func globalNames(pkg *ast.Package) map[string]bool {
-	names := make(map[string]bool)
-	for _, file := range pkg.Files {
-		for _, decl := range file.Decls {
-			addNames(names, decl)
-		}
-	}
-	return names
-}
-
-// collectExamples collects examples for pkg from testfiles.
-func collectExamples(c *Corpus, pkg *ast.Package, testfiles map[string]*ast.File) []*doc.Example {
-	var files []*ast.File
-	for _, f := range testfiles {
-		files = append(files, f)
-	}
-
-	var examples []*doc.Example
-	globals := globalNames(pkg)
-	for _, e := range doc.Examples(files...) {
-		name := stripExampleSuffix(e.Name)
-		if name == "" || globals[name] {
-			examples = append(examples, e)
-		} else if c.Verbose {
-			log.Printf("skipping example 'Example%s' because '%s' is not a known function or type", e.Name, e.Name)
-		}
-	}
-
-	return examples
-}
-
-// addNames adds the names declared by decl to the names set.
-// Method names are added in the form ReceiverTypeName_Method.
-func addNames(names map[string]bool, decl ast.Decl) {
-	switch d := decl.(type) {
-	case *ast.FuncDecl:
-		name := d.Name.Name
-		if d.Recv != nil {
-			var typeName string
-			switch r := d.Recv.List[0].Type.(type) {
-			case *ast.StarExpr:
-				typeName = r.X.(*ast.Ident).Name
-			case *ast.Ident:
-				typeName = r.Name
-			}
-			name = typeName + "_" + name
-		}
-		names[name] = true
-	case *ast.GenDecl:
-		for _, spec := range d.Specs {
-			switch s := spec.(type) {
-			case *ast.TypeSpec:
-				names[s.Name.Name] = true
-			case *ast.ValueSpec:
-				for _, id := range s.Names {
-					names[id.Name] = true
-				}
-			}
-		}
-	}
-}
-
-// packageExports is a local implementation of ast.PackageExports
-// which correctly updates each package file's comment list.
-// (The ast.PackageExports signature is frozen, hence the local
-// implementation).
-//
-func packageExports(fset *token.FileSet, pkg *ast.Package) {
-	for _, src := range pkg.Files {
-		cmap := ast.NewCommentMap(fset, src, src.Comments)
-		ast.FileExports(src)
-		src.Comments = cmap.Filter(src).Comments()
-	}
-}
-
-func applyTemplate(t *template.Template, name string, data interface{}) []byte {
-	var buf bytes.Buffer
-	if err := t.Execute(&buf, data); err != nil {
-		log.Printf("%s.Execute: %s", name, err)
-	}
-	return buf.Bytes()
-}
-
-type writerCapturesErr struct {
-	w   io.Writer
-	err error
-}
-
-func (w *writerCapturesErr) Write(p []byte) (int, error) {
-	n, err := w.w.Write(p)
-	if err != nil {
-		w.err = err
-	}
-	return n, err
-}
-
-// applyTemplateToResponseWriter uses an http.ResponseWriter as the io.Writer
-// for the call to template.Execute.  It uses an io.Writer wrapper to capture
-// errors from the underlying http.ResponseWriter.  Errors are logged only when
-// they come from the template processing and not the Writer; this avoid
-// polluting log files with error messages due to networking issues, such as
-// client disconnects and http HEAD protocol violations.
-func applyTemplateToResponseWriter(rw http.ResponseWriter, t *template.Template, data interface{}) {
-	w := &writerCapturesErr{w: rw}
-	err := t.Execute(w, data)
-	// There are some cases where template.Execute does not return an error when
-	// rw returns an error, and some where it does.  So check w.err first.
-	if w.err == nil && err != nil {
-		// Log template errors.
-		log.Printf("%s.Execute: %s", t.Name(), err)
-	}
-}
-
-func redirect(w http.ResponseWriter, r *http.Request) (redirected bool) {
-	canonical := pathpkg.Clean(r.URL.Path)
-	if !strings.HasSuffix(canonical, "/") {
-		canonical += "/"
-	}
-	if r.URL.Path != canonical {
-		url := *r.URL
-		url.Path = canonical
-		http.Redirect(w, r, url.String(), http.StatusMovedPermanently)
-		redirected = true
-	}
-	return
-}
-
-func redirectFile(w http.ResponseWriter, r *http.Request) (redirected bool) {
-	c := pathpkg.Clean(r.URL.Path)
-	c = strings.TrimRight(c, "/")
-	if r.URL.Path != c {
-		url := *r.URL
-		url.Path = c
-		http.Redirect(w, r, url.String(), http.StatusMovedPermanently)
-		redirected = true
-	}
-	return
-}
-
-func (p *Presentation) serveTextFile(w http.ResponseWriter, r *http.Request, abspath, relpath, title string) {
-	src, err := vfs.ReadFile(p.Corpus.fs, abspath)
-	if err != nil {
-		log.Printf("ReadFile: %s", err)
-		p.ServeError(w, r, relpath, err)
-		return
-	}
-
-	if r.FormValue(PageInfoModeQueryString) == "text" {
-		p.ServeText(w, src)
-		return
-	}
-
-	h := r.FormValue("h")
-	s := RangeSelection(r.FormValue("s"))
-
-	var buf bytes.Buffer
-	if pathpkg.Ext(abspath) == ".go" {
-		// Find markup links for this file (e.g. "/src/fmt/print.go").
-		fi := p.Corpus.Analysis.FileInfo(abspath)
-		buf.WriteString("<script type='text/javascript'>document.ANALYSIS_DATA = ")
-		buf.Write(marshalJSON(fi.Data))
-		buf.WriteString(";</script>\n")
-
-		if status := p.Corpus.Analysis.Status(); status != "" {
-			buf.WriteString("<a href='/lib/godoc/analysis/help.html'>Static analysis features</a> ")
-			// TODO(adonovan): show analysis status at per-file granularity.
-			fmt.Fprintf(&buf, "<span style='color: grey'>[%s]</span><br/>", htmlpkg.EscapeString(status))
-		}
-
-		buf.WriteString("<pre>")
-		formatGoSource(&buf, src, fi.Links, h, s)
-		buf.WriteString("</pre>")
-	} else {
-		buf.WriteString("<pre>")
-		FormatText(&buf, src, 1, false, h, s)
-		buf.WriteString("</pre>")
-	}
-	fmt.Fprintf(&buf, `<p><a href="/%s?m=text">View as plain text</a></p>`, htmlpkg.EscapeString(relpath))
-
-	p.ServePage(w, Page{
-		Title:    title,
-		SrcPath:  relpath,
-		Tabtitle: relpath,
-		Body:     buf.Bytes(),
-		GoogleCN: googleCN(r),
-	})
-}
-
-// formatGoSource HTML-escapes Go source text and writes it to w,
-// decorating it with the specified analysis links.
-//
-func formatGoSource(buf *bytes.Buffer, text []byte, links []analysis.Link, pattern string, selection Selection) {
-	// Emit to a temp buffer so that we can add line anchors at the end.
-	saved, buf := buf, new(bytes.Buffer)
-
-	var i int
-	var link analysis.Link // shared state of the two funcs below
-	segmentIter := func() (seg Segment) {
-		if i < len(links) {
-			link = links[i]
-			i++
-			seg = Segment{link.Start(), link.End()}
-		}
-		return
-	}
-	linkWriter := func(w io.Writer, offs int, start bool) {
-		link.Write(w, offs, start)
-	}
-
-	comments := tokenSelection(text, token.COMMENT)
-	var highlights Selection
-	if pattern != "" {
-		highlights = regexpSelection(text, pattern)
-	}
-
-	FormatSelections(buf, text, linkWriter, segmentIter, selectionTag, comments, highlights, selection)
-
-	// Now copy buf to saved, adding line anchors.
-
-	// The lineSelection mechanism can't be composed with our
-	// linkWriter, so we have to add line spans as another pass.
-	n := 1
-	for _, line := range bytes.Split(buf.Bytes(), []byte("\n")) {
-		// The line numbers are inserted into the document via a CSS ::before
-		// pseudo-element. This prevents them from being copied when users
-		// highlight and copy text.
-		// ::before is supported in 98% of browsers: https://caniuse.com/#feat=css-gencontent
-		// This is also the trick Github uses to hide line numbers.
-		//
-		// The first tab for the code snippet needs to start in column 9, so
-		// it indents a full 8 spaces, hence the two nbsp's. Otherwise the tab
-		// character only indents a short amount.
-		//
-		// Due to rounding and font width Firefox might not treat 8 rendered
-		// characters as 8 characters wide, and subsequently may treat the tab
-		// character in the 9th position as moving the width from (7.5 or so) up
-		// to 8. See
-		// https://github.com/webcompat/web-bugs/issues/17530#issuecomment-402675091
-		// for a fuller explanation. The solution is to add a CSS class to
-		// explicitly declare the width to be 8 characters.
-		fmt.Fprintf(saved, `<span id="L%d" class="ln">%6d&nbsp;&nbsp;</span>`, n, n)
-		n++
-		saved.Write(line)
-		saved.WriteByte('\n')
-	}
-}
-
-func (p *Presentation) serveDirectory(w http.ResponseWriter, r *http.Request, abspath, relpath string) {
-	if redirect(w, r) {
-		return
-	}
-
-	list, err := p.Corpus.fs.ReadDir(abspath)
-	if err != nil {
-		p.ServeError(w, r, relpath, err)
-		return
-	}
-
-	p.ServePage(w, Page{
-		Title:    "Directory",
-		SrcPath:  relpath,
-		Tabtitle: relpath,
-		Body:     applyTemplate(p.DirlistHTML, "dirlistHTML", list),
-		GoogleCN: googleCN(r),
-	})
-}
-
-func (p *Presentation) ServeHTMLDoc(w http.ResponseWriter, r *http.Request, abspath, relpath string) {
-	// get HTML body contents
-	src, err := vfs.ReadFile(p.Corpus.fs, abspath)
-	if err != nil {
-		log.Printf("ReadFile: %s", err)
-		p.ServeError(w, r, relpath, err)
-		return
-	}
-
-	// if it begins with "<!DOCTYPE " assume it is standalone
-	// html that doesn't need the template wrapping.
-	if bytes.HasPrefix(src, doctype) {
-		w.Write(src)
-		return
-	}
-
-	// if it begins with a JSON blob, read in the metadata.
-	meta, src, err := extractMetadata(src)
-	if err != nil {
-		log.Printf("decoding metadata %s: %v", relpath, err)
-	}
-
-	page := Page{
-		Title:    meta.Title,
-		Subtitle: meta.Subtitle,
-		GoogleCN: googleCN(r),
-	}
-
-	// evaluate as template if indicated
-	if meta.Template {
-		tmpl, err := template.New("main").Funcs(p.TemplateFuncs()).Parse(string(src))
-		if err != nil {
-			log.Printf("parsing template %s: %v", relpath, err)
-			p.ServeError(w, r, relpath, err)
-			return
-		}
-		var buf bytes.Buffer
-		if err := tmpl.Execute(&buf, page); err != nil {
-			log.Printf("executing template %s: %v", relpath, err)
-			p.ServeError(w, r, relpath, err)
-			return
-		}
-		src = buf.Bytes()
-	}
-
-	// if it's the language spec, add tags to EBNF productions
-	if strings.HasSuffix(abspath, "go_spec.html") {
-		var buf bytes.Buffer
-		Linkify(&buf, src)
-		src = buf.Bytes()
-	}
-
-	page.Body = src
-	p.ServePage(w, page)
-}
-
-func (p *Presentation) ServeFile(w http.ResponseWriter, r *http.Request) {
-	p.serveFile(w, r)
-}
-
-func (p *Presentation) serveFile(w http.ResponseWriter, r *http.Request) {
-	relpath := r.URL.Path
-
-	// Check to see if we need to redirect or serve another file.
-	if m := p.Corpus.MetadataFor(relpath); m != nil {
-		if m.Path != relpath {
-			// Redirect to canonical path.
-			http.Redirect(w, r, m.Path, http.StatusMovedPermanently)
-			return
-		}
-		// Serve from the actual filesystem path.
-		relpath = m.filePath
-	}
-
-	abspath := relpath
-	relpath = relpath[1:] // strip leading slash
-
-	switch pathpkg.Ext(relpath) {
-	case ".html":
-		if strings.HasSuffix(relpath, "/index.html") {
-			// We'll show index.html for the directory.
-			// Use the dir/ version as canonical instead of dir/index.html.
-			http.Redirect(w, r, r.URL.Path[0:len(r.URL.Path)-len("index.html")], http.StatusMovedPermanently)
-			return
-		}
-		p.ServeHTMLDoc(w, r, abspath, relpath)
-		return
-
-	case ".go":
-		p.serveTextFile(w, r, abspath, relpath, "Source file")
-		return
-	}
-
-	dir, err := p.Corpus.fs.Lstat(abspath)
-	if err != nil {
-		log.Print(err)
-		p.ServeError(w, r, relpath, err)
-		return
-	}
-
-	if dir != nil && dir.IsDir() {
-		if redirect(w, r) {
-			return
-		}
-		if index := pathpkg.Join(abspath, "index.html"); util.IsTextFile(p.Corpus.fs, index) {
-			p.ServeHTMLDoc(w, r, index, index)
-			return
-		}
-		p.serveDirectory(w, r, abspath, relpath)
-		return
-	}
-
-	if util.IsTextFile(p.Corpus.fs, abspath) {
-		if redirectFile(w, r) {
-			return
-		}
-		p.serveTextFile(w, r, abspath, relpath, "Text file")
-		return
-	}
-
-	p.fileServer.ServeHTTP(w, r)
-}
-
-func (p *Presentation) ServeText(w http.ResponseWriter, text []byte) {
-	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	w.Write(text)
-}
-
-func marshalJSON(x interface{}) []byte {
-	var data []byte
-	var err error
-	const indentJSON = false // for easier debugging
-	if indentJSON {
-		data, err = json.MarshalIndent(x, "", "    ")
-	} else {
-		data, err = json.Marshal(x)
-	}
-	if err != nil {
-		panic(fmt.Sprintf("json.Marshal failed: %s", err))
-	}
-	return data
-}
diff --git a/cmd/golangorg/godoc/server_test.go b/cmd/golangorg/godoc/server_test.go
deleted file mode 100644
index 4419759..0000000
--- a/cmd/golangorg/godoc/server_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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.
-
-package godoc
-
-import (
-	"testing"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs/mapfs"
-)
-
-// TestIgnoredGoFiles tests the scenario where a folder has no .go or .c files,
-// but has an ignored go file.
-func TestIgnoredGoFiles(t *testing.T) {
-	packagePath := "github.com/package"
-	packageComment := "main is documented in an ignored .go file"
-
-	c := NewCorpus(mapfs.New(map[string]string{
-		"src/" + packagePath + "/ignored.go": `// +build ignore
-
-// ` + packageComment + `
-package main`}))
-	srv := &handlerServer{
-		p: &Presentation{
-			Corpus: c,
-		},
-		c: c,
-	}
-	pInfo := srv.GetPageInfo("/src/"+packagePath, packagePath, NoFiltering, "linux", "amd64")
-
-	if pInfo.PDoc == nil {
-		t.Error("pInfo.PDoc = nil; want non-nil.")
-	} else {
-		if got, want := pInfo.PDoc.Doc, packageComment+"\n"; got != want {
-			t.Errorf("pInfo.PDoc.Doc = %q; want %q.", got, want)
-		}
-		if got, want := pInfo.PDoc.Name, "main"; got != want {
-			t.Errorf("pInfo.PDoc.Name = %q; want %q.", got, want)
-		}
-		if got, want := pInfo.PDoc.ImportPath, packagePath; got != want {
-			t.Errorf("pInfo.PDoc.ImportPath = %q; want %q.", got, want)
-		}
-	}
-	if pInfo.FSet == nil {
-		t.Error("pInfo.FSet = nil; want non-nil.")
-	}
-}
diff --git a/cmd/golangorg/godoc/short/short.go b/cmd/golangorg/godoc/short/short.go
deleted file mode 100644
index 69e82dc..0000000
--- a/cmd/golangorg/godoc/short/short.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-// +build golangorg
-
-// Package short implements a simple URL shortener, serving an administrative
-// interface at /s and shortened urls from /s/key.
-// It is designed to run only on the instance of godoc that serves golang.org.
-package short
-
-// TODO(adg): collect statistics on URL visits
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"html/template"
-	"io"
-	"log"
-	"net/http"
-	"net/url"
-	"regexp"
-
-	"cloud.google.com/go/datastore"
-	"golang.org/x/website/internal/memcache"
-	"google.golang.org/appengine/user"
-)
-
-const (
-	prefix  = "/s"
-	kind    = "Link"
-	baseURL = "https://golang.org" + prefix
-)
-
-// Link represents a short link.
-type Link struct {
-	Key, Target string
-}
-
-var validKey = regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`)
-
-type server struct {
-	datastore *datastore.Client
-	memcache  *memcache.CodecClient
-}
-
-func RegisterHandlers(mux *http.ServeMux, dc *datastore.Client, mc *memcache.Client) {
-	s := server{dc, mc.WithCodec(memcache.JSON)}
-	mux.HandleFunc(prefix+"/", s.linkHandler)
-
-	// TODO(cbro): move storage of the links to a text file in Gerrit.
-	// Disable the admin handler until that happens, since GAE Flex doesn't support
-	// the "google.golang.org/appengine/user" package.
-	// See golang.org/issue/27205#issuecomment-418673218
-	// mux.HandleFunc(prefix, adminHandler)
-	mux.HandleFunc(prefix, func(w http.ResponseWriter, r *http.Request) {
-		w.WriteHeader(http.StatusForbidden)
-		io.WriteString(w, "Link creation temporarily unavailable. See golang.org/issue/27205.")
-	})
-}
-
-// linkHandler services requests to short URLs.
-//   http://golang.org/s/key
-// It consults memcache and datastore for the Link for key.
-// It then sends a redirects or an error message.
-func (h server) linkHandler(w http.ResponseWriter, r *http.Request) {
-	ctx := r.Context()
-
-	key := r.URL.Path[len(prefix)+1:]
-	if !validKey.MatchString(key) {
-		http.Error(w, "not found", http.StatusNotFound)
-		return
-	}
-
-	var link Link
-	if err := h.memcache.Get(ctx, cacheKey(key), &link); err != nil {
-		k := datastore.NameKey(kind, key, nil)
-		err = h.datastore.Get(ctx, k, &link)
-		switch err {
-		case datastore.ErrNoSuchEntity:
-			http.Error(w, "not found", http.StatusNotFound)
-			return
-		default: // != nil
-			log.Printf("ERROR %q: %v", key, err)
-			http.Error(w, "internal server error", http.StatusInternalServerError)
-			return
-		case nil:
-			item := &memcache.Item{
-				Key:    cacheKey(key),
-				Object: &link,
-			}
-			if err := h.memcache.Set(ctx, item); err != nil {
-				log.Printf("WARNING %q: %v", key, err)
-			}
-		}
-	}
-
-	http.Redirect(w, r, link.Target, http.StatusFound)
-}
-
-var adminTemplate = template.Must(template.New("admin").Parse(templateHTML))
-
-// adminHandler serves an administrative interface.
-func (h server) adminHandler(w http.ResponseWriter, r *http.Request) {
-	ctx := r.Context()
-
-	if !user.IsAdmin(ctx) {
-		http.Error(w, "forbidden", http.StatusForbidden)
-		return
-	}
-
-	var newLink *Link
-	var doErr error
-	if r.Method == "POST" {
-		key := r.FormValue("key")
-		switch r.FormValue("do") {
-		case "Add":
-			newLink = &Link{key, r.FormValue("target")}
-			doErr = h.putLink(ctx, newLink)
-		case "Delete":
-			k := datastore.NameKey(kind, key, nil)
-			doErr = h.datastore.Delete(ctx, k)
-		default:
-			http.Error(w, "unknown action", http.StatusBadRequest)
-		}
-		err := h.memcache.Delete(ctx, cacheKey(key))
-		if err != nil && err != memcache.ErrCacheMiss {
-			log.Printf("WARNING %q: %v", key, err)
-		}
-	}
-
-	var links []*Link
-	q := datastore.NewQuery(kind).Order("Key")
-	if _, err := h.datastore.GetAll(ctx, q, &links); err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		log.Printf("ERROR %v", err)
-		return
-	}
-
-	// Put the new link in the list if it's not there already.
-	// (Eventual consistency means that it might not show up
-	// immediately, which might be confusing for the user.)
-	if newLink != nil && doErr == nil {
-		found := false
-		for i := range links {
-			if links[i].Key == newLink.Key {
-				found = true
-				break
-			}
-		}
-		if !found {
-			links = append([]*Link{newLink}, links...)
-		}
-		newLink = nil
-	}
-
-	var data = struct {
-		BaseURL string
-		Prefix  string
-		Links   []*Link
-		New     *Link
-		Error   error
-	}{baseURL, prefix, links, newLink, doErr}
-	if err := adminTemplate.Execute(w, &data); err != nil {
-		log.Printf("ERROR adminTemplate: %v", err)
-	}
-}
-
-// putLink validates the provided link and puts it into the datastore.
-func (h server) putLink(ctx context.Context, link *Link) error {
-	if !validKey.MatchString(link.Key) {
-		return errors.New("invalid key; must match " + validKey.String())
-	}
-	if _, err := url.Parse(link.Target); err != nil {
-		return fmt.Errorf("bad target: %v", err)
-	}
-	k := datastore.NameKey(kind, link.Key, nil)
-	_, err := h.datastore.Put(ctx, k, link)
-	return err
-}
-
-// cacheKey returns a short URL key as a memcache key.
-func cacheKey(key string) string {
-	return "link-" + key
-}
diff --git a/cmd/golangorg/godoc/short/tmpl.go b/cmd/golangorg/godoc/short/tmpl.go
deleted file mode 100644
index 66f5401..0000000
--- a/cmd/golangorg/godoc/short/tmpl.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-package short
-
-const templateHTML = `
-<!doctype HTML>
-<html>
-<head>
-<title>golang.org URL shortener</title>
-<style>
-body {
-	background: white;
-}
-input {
-	border: 1px solid #ccc;
-}
-input[type=text] {
-	width: 400px;
-}
-input, td, th {
-	color: #333;
-	font-family: Georgia, Times New Roman, serif;
-}
-input, td {
-	font-size: 14pt;
-}
-th {
-	font-size: 16pt;
-	text-align: left;
-	padding-top: 10px;
-}
-.autoselect {
-	border: none;
-}
-.error {
-	color: #900;
-}
-table {
-	margin-left: auto;
-	margin-right: auto;
-}
-</style>
-</head>
-<body>
-
-<table>
-
-{{with .Error}}
-<tr>
-	<th colspan="3">Error</th>
-</tr>
-<tr>
-	<td class="error" colspan="3">{{.}}</td>
-</tr>
-{{end}}
-
-<tr>
-	<th>Key</th>
-	<th>Target</th>
-	<th></th>
-</tr>
-
-<form method="POST" action="{{.Prefix}}">
-<tr>
-	<td><input type="text" name="key"{{with .New}} value="{{.Key}}"{{end}}></td>
-	<td><input type="text" name="target"{{with .New}} value="{{.Target}}"{{end}}></td>
-	<td><input type="submit" name="do" value="Add">
-</tr>
-</form>
-
-{{with .Links}}
-<tr>
-	<th>Short Link</th>
-	<th>&nbsp;</th>
-	<th>&nbsp;</th>
-</tr>
-{{range .}}
-<tr>
-	<td><input class="autoselect" type="text" orig="{{$.BaseURL}}/{{.Key}}" value="{{$.BaseURL}}/{{.Key}}"></td>
-	<td><input class="autoselect" type="text" orig="{{.Target}}" value="{{.Target}}"></td>
-	<td>
-		<form method="POST" action="{{$.Prefix}}">
-			<input type="hidden" name="key" value="{{.Key}}">
-			<input type="submit" name="do" value="Delete" class="delete">
-		</form>
-	</td>
-</tr>
-{{end}}
-{{end}}
-
-</table>
-
-</body>
-<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
-<script type="text/javascript">window.jQuery || document.write(unescape("%3Cscript src='/doc/jquery.js' type='text/javascript'%3E%3C/script%3E"));</script>
-<script>
-$(document).ready(function() {
-	$('.autoselect').each(function() {
-		$(this).click(function() {
-			$(this).select();
-		});
-		$(this).change(function() {
-			$(this).val($(this).attr('orig'));
-		});
-	});
-	$('.delete').click(function(e) {
-		var link = $(this).closest('tr').find('input').first().val();
-		var ok = confirm('Delete this link?\n' + link);
-		if (!ok) {
-			e.preventDefault();
-			return false;
-		}
-	});
-});
-</script>
-</html>
-`
diff --git a/cmd/golangorg/godoc/snippet.go b/cmd/golangorg/godoc/snippet.go
deleted file mode 100644
index 1750478..0000000
--- a/cmd/golangorg/godoc/snippet.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains the infrastructure to create a code
-// snippet for search results.
-//
-// Note: At the moment, this only creates HTML snippets.
-
-package godoc
-
-import (
-	"bytes"
-	"fmt"
-	"go/ast"
-	"go/token"
-)
-
-type Snippet struct {
-	Line int
-	Text string // HTML-escaped
-}
-
-func (p *Presentation) newSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
-	// TODO instead of pretty-printing the node, should use the original source instead
-	var buf1 bytes.Buffer
-	p.writeNode(&buf1, nil, fset, decl)
-	// wrap text with <pre> tag
-	var buf2 bytes.Buffer
-	buf2.WriteString("<pre>")
-	FormatText(&buf2, buf1.Bytes(), -1, true, id.Name, nil)
-	buf2.WriteString("</pre>")
-	return &Snippet{fset.Position(id.Pos()).Line, buf2.String()}
-}
-
-func findSpec(list []ast.Spec, id *ast.Ident) ast.Spec {
-	for _, spec := range list {
-		switch s := spec.(type) {
-		case *ast.ImportSpec:
-			if s.Name == id {
-				return s
-			}
-		case *ast.ValueSpec:
-			for _, n := range s.Names {
-				if n == id {
-					return s
-				}
-			}
-		case *ast.TypeSpec:
-			if s.Name == id {
-				return s
-			}
-		}
-	}
-	return nil
-}
-
-func (p *Presentation) genSnippet(fset *token.FileSet, d *ast.GenDecl, id *ast.Ident) *Snippet {
-	s := findSpec(d.Specs, id)
-	if s == nil {
-		return nil //  declaration doesn't contain id - exit gracefully
-	}
-
-	// only use the spec containing the id for the snippet
-	dd := &ast.GenDecl{
-		Doc:    d.Doc,
-		TokPos: d.Pos(),
-		Tok:    d.Tok,
-		Lparen: d.Lparen,
-		Specs:  []ast.Spec{s},
-		Rparen: d.Rparen,
-	}
-
-	return p.newSnippet(fset, dd, id)
-}
-
-func (p *Presentation) funcSnippet(fset *token.FileSet, d *ast.FuncDecl, id *ast.Ident) *Snippet {
-	if d.Name != id {
-		return nil //  declaration doesn't contain id - exit gracefully
-	}
-
-	// only use the function signature for the snippet
-	dd := &ast.FuncDecl{
-		Doc:  d.Doc,
-		Recv: d.Recv,
-		Name: d.Name,
-		Type: d.Type,
-	}
-
-	return p.newSnippet(fset, dd, id)
-}
-
-// NewSnippet creates a text snippet from a declaration decl containing an
-// identifier id. Parts of the declaration not containing the identifier
-// may be removed for a more compact snippet.
-func NewSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
-	// TODO(bradfitz, adg): remove this function.  But it's used by indexer, which
-	// doesn't have a *Presentation, and NewSnippet needs a TabWidth.
-	var p Presentation
-	p.TabWidth = 4
-	return p.NewSnippet(fset, decl, id)
-}
-
-// NewSnippet creates a text snippet from a declaration decl containing an
-// identifier id. Parts of the declaration not containing the identifier
-// may be removed for a more compact snippet.
-func (p *Presentation) NewSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {
-	var s *Snippet
-	switch d := decl.(type) {
-	case *ast.GenDecl:
-		s = p.genSnippet(fset, d, id)
-	case *ast.FuncDecl:
-		s = p.funcSnippet(fset, d, id)
-	}
-
-	// handle failure gracefully
-	if s == nil {
-		var buf bytes.Buffer
-		fmt.Fprintf(&buf, `<span class="alert">could not generate a snippet for <span class="highlight">%s</span></span>`, id.Name)
-		s = &Snippet{fset.Position(id.Pos()).Line, buf.String()}
-	}
-	return s
-}
diff --git a/cmd/golangorg/godoc/spec.go b/cmd/golangorg/godoc/spec.go
deleted file mode 100644
index 9ec9427..0000000
--- a/cmd/golangorg/godoc/spec.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-// This file contains the mechanism to "linkify" html source
-// text containing EBNF sections (as found in go_spec.html).
-// The result is the input source text with the EBNF sections
-// modified such that identifiers are linked to the respective
-// definitions.
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"text/scanner"
-)
-
-type ebnfParser struct {
-	out     io.Writer // parser output
-	src     []byte    // parser input
-	scanner scanner.Scanner
-	prev    int    // offset of previous token
-	pos     int    // offset of current token
-	tok     rune   // one token look-ahead
-	lit     string // token literal
-}
-
-func (p *ebnfParser) flush() {
-	p.out.Write(p.src[p.prev:p.pos])
-	p.prev = p.pos
-}
-
-func (p *ebnfParser) next() {
-	p.tok = p.scanner.Scan()
-	p.pos = p.scanner.Position.Offset
-	p.lit = p.scanner.TokenText()
-}
-
-func (p *ebnfParser) printf(format string, args ...interface{}) {
-	p.flush()
-	fmt.Fprintf(p.out, format, args...)
-}
-
-func (p *ebnfParser) errorExpected(msg string) {
-	p.printf(`<span class="highlight">error: expected %s, found %s</span>`, msg, scanner.TokenString(p.tok))
-}
-
-func (p *ebnfParser) expect(tok rune) {
-	if p.tok != tok {
-		p.errorExpected(scanner.TokenString(tok))
-	}
-	p.next() // make progress in any case
-}
-
-func (p *ebnfParser) parseIdentifier(def bool) {
-	if p.tok == scanner.Ident {
-		name := p.lit
-		if def {
-			p.printf(`<a id="%s">%s</a>`, name, name)
-		} else {
-			p.printf(`<a href="#%s" class="noline">%s</a>`, name, name)
-		}
-		p.prev += len(name) // skip identifier when printing next time
-		p.next()
-	} else {
-		p.expect(scanner.Ident)
-	}
-}
-
-func (p *ebnfParser) parseTerm() bool {
-	switch p.tok {
-	case scanner.Ident:
-		p.parseIdentifier(false)
-
-	case scanner.String, scanner.RawString:
-		p.next()
-		const ellipsis = '…' // U+2026, the horizontal ellipsis character
-		if p.tok == ellipsis {
-			p.next()
-			p.expect(scanner.String)
-		}
-
-	case '(':
-		p.next()
-		p.parseExpression()
-		p.expect(')')
-
-	case '[':
-		p.next()
-		p.parseExpression()
-		p.expect(']')
-
-	case '{':
-		p.next()
-		p.parseExpression()
-		p.expect('}')
-
-	default:
-		return false // no term found
-	}
-
-	return true
-}
-
-func (p *ebnfParser) parseSequence() {
-	if !p.parseTerm() {
-		p.errorExpected("term")
-	}
-	for p.parseTerm() {
-	}
-}
-
-func (p *ebnfParser) parseExpression() {
-	for {
-		p.parseSequence()
-		if p.tok != '|' {
-			break
-		}
-		p.next()
-	}
-}
-
-func (p *ebnfParser) parseProduction() {
-	p.parseIdentifier(true)
-	p.expect('=')
-	if p.tok != '.' {
-		p.parseExpression()
-	}
-	p.expect('.')
-}
-
-func (p *ebnfParser) parse(out io.Writer, src []byte) {
-	// initialize ebnfParser
-	p.out = out
-	p.src = src
-	p.scanner.Init(bytes.NewBuffer(src))
-	p.next() // initializes pos, tok, lit
-
-	// process source
-	for p.tok != scanner.EOF {
-		p.parseProduction()
-	}
-	p.flush()
-}
-
-// Markers around EBNF sections
-var (
-	openTag  = []byte(`<pre class="ebnf">`)
-	closeTag = []byte(`</pre>`)
-)
-
-func Linkify(out io.Writer, src []byte) {
-	for len(src) > 0 {
-		// i: beginning of EBNF text (or end of source)
-		i := bytes.Index(src, openTag)
-		if i < 0 {
-			i = len(src) - len(openTag)
-		}
-		i += len(openTag)
-
-		// j: end of EBNF text (or end of source)
-		j := bytes.Index(src[i:], closeTag) // close marker
-		if j < 0 {
-			j = len(src) - i
-		}
-		j += i
-
-		// write text before EBNF
-		out.Write(src[0:i])
-		// process EBNF
-		var p ebnfParser
-		p.parse(out, src[i:j])
-
-		// advance
-		src = src[j:]
-	}
-}
diff --git a/cmd/golangorg/godoc/spec_test.go b/cmd/golangorg/godoc/spec_test.go
deleted file mode 100644
index c016516..0000000
--- a/cmd/golangorg/godoc/spec_test.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-
-package godoc
-
-import (
-	"bytes"
-	"strings"
-	"testing"
-)
-
-func TestParseEBNFString(t *testing.T) {
-	var p ebnfParser
-	var buf bytes.Buffer
-	src := []byte("octal_byte_value = `\\` octal_digit octal_digit octal_digit .")
-	p.parse(&buf, src)
-
-	if strings.Contains(buf.String(), "error") {
-		t.Error(buf.String())
-	}
-}
diff --git a/cmd/golangorg/godoc/spot.go b/cmd/golangorg/godoc/spot.go
deleted file mode 100644
index 95ffa4b..0000000
--- a/cmd/golangorg/godoc/spot.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package godoc
-
-// ----------------------------------------------------------------------------
-// SpotInfo
-
-// A SpotInfo value describes a particular identifier spot in a given file;
-// It encodes three values: the SpotKind (declaration or use), a line or
-// snippet index "lori", and whether it's a line or index.
-//
-// The following encoding is used:
-//
-//   bits    32   4    1       0
-//   value    [lori|kind|isIndex]
-//
-type SpotInfo uint32
-
-// SpotKind describes whether an identifier is declared (and what kind of
-// declaration) or used.
-type SpotKind uint32
-
-const (
-	PackageClause SpotKind = iota
-	ImportDecl
-	ConstDecl
-	TypeDecl
-	VarDecl
-	FuncDecl
-	MethodDecl
-	Use
-	nKinds
-)
-
-var (
-	// These must match the SpotKind values above.
-	name = []string{
-		"Packages",
-		"Imports",
-		"Constants",
-		"Types",
-		"Variables",
-		"Functions",
-		"Methods",
-		"Uses",
-		"Unknown",
-	}
-)
-
-func (x SpotKind) Name() string { return name[x] }
-
-func init() {
-	// sanity check: if nKinds is too large, the SpotInfo
-	// accessor functions may need to be updated
-	if nKinds > 8 {
-		panic("internal error: nKinds > 8")
-	}
-}
-
-// makeSpotInfo makes a SpotInfo.
-func makeSpotInfo(kind SpotKind, lori int, isIndex bool) SpotInfo {
-	// encode lori: bits [4..32)
-	x := SpotInfo(lori) << 4
-	if int(x>>4) != lori {
-		// lori value doesn't fit - since snippet indices are
-		// most certainly always smaller then 1<<28, this can
-		// only happen for line numbers; give it no line number (= 0)
-		x = 0
-	}
-	// encode kind: bits [1..4)
-	x |= SpotInfo(kind) << 1
-	// encode isIndex: bit 0
-	if isIndex {
-		x |= 1
-	}
-	return x
-}
-
-func (x SpotInfo) Kind() SpotKind { return SpotKind(x >> 1 & 7) }
-func (x SpotInfo) Lori() int      { return int(x >> 4) }
-func (x SpotInfo) IsIndex() bool  { return x&1 != 0 }
diff --git a/cmd/golangorg/godoc/tab.go b/cmd/golangorg/godoc/tab.go
deleted file mode 100644
index d314ac7..0000000
--- a/cmd/golangorg/godoc/tab.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(bradfitz,adg): move to util
-
-package godoc
-
-import "io"
-
-var spaces = []byte("                                ") // 32 spaces seems like a good number
-
-const (
-	indenting = iota
-	collecting
-)
-
-// A tconv is an io.Writer filter for converting leading tabs into spaces.
-type tconv struct {
-	output io.Writer
-	state  int // indenting or collecting
-	indent int // valid if state == indenting
-	p      *Presentation
-}
-
-func (p *tconv) writeIndent() (err error) {
-	i := p.indent
-	for i >= len(spaces) {
-		i -= len(spaces)
-		if _, err = p.output.Write(spaces); err != nil {
-			return
-		}
-	}
-	// i < len(spaces)
-	if i > 0 {
-		_, err = p.output.Write(spaces[0:i])
-	}
-	return
-}
-
-func (p *tconv) Write(data []byte) (n int, err error) {
-	if len(data) == 0 {
-		return
-	}
-	pos := 0 // valid if p.state == collecting
-	var b byte
-	for n, b = range data {
-		switch p.state {
-		case indenting:
-			switch b {
-			case '\t':
-				p.indent += p.p.TabWidth
-			case '\n':
-				p.indent = 0
-				if _, err = p.output.Write(data[n : n+1]); err != nil {
-					return
-				}
-			case ' ':
-				p.indent++
-			default:
-				p.state = collecting
-				pos = n
-				if err = p.writeIndent(); err != nil {
-					return
-				}
-			}
-		case collecting:
-			if b == '\n' {
-				p.state = indenting
-				p.indent = 0
-				if _, err = p.output.Write(data[pos : n+1]); err != nil {
-					return
-				}
-			}
-		}
-	}
-	n = len(data)
-	if pos < n && p.state == collecting {
-		_, err = p.output.Write(data[pos:])
-	}
-	return
-}
diff --git a/cmd/golangorg/godoc/template.go b/cmd/golangorg/godoc/template.go
deleted file mode 100644
index d236f5d..0000000
--- a/cmd/golangorg/godoc/template.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Template support for writing HTML documents.
-// Documents that include Template: true in their
-// metadata are executed as input to text/template.
-//
-// This file defines functions for those templates to invoke.
-
-// The template uses the function "code" to inject program
-// source into the output by extracting code from files and
-// injecting them as HTML-escaped <pre> blocks.
-//
-// The syntax is simple: 1, 2, or 3 space-separated arguments:
-//
-// Whole file:
-//	{{code "foo.go"}}
-// One line (here the signature of main):
-//	{{code "foo.go" `/^func.main/`}}
-// Block of text, determined by start and end (here the body of main):
-//	{{code "foo.go" `/^func.main/` `/^}/`
-//
-// Patterns can be `/regular expression/`, a decimal number, or "$"
-// to signify the end of the file. In multi-line matches,
-// lines that end with the four characters
-//	OMIT
-// are omitted from the output, making it easy to provide marker
-// lines in the input that will not appear in the output but are easy
-// to identify by pattern.
-
-package godoc
-
-import (
-	"bytes"
-	"fmt"
-	"log"
-	"regexp"
-	"strings"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// Functions in this file panic on error, but the panic is recovered
-// to an error by 'code'.
-
-// contents reads and returns the content of the named file
-// (from the virtual file system, so for example /doc refers to $GOROOT/doc).
-func (c *Corpus) contents(name string) string {
-	file, err := vfs.ReadFile(c.fs, name)
-	if err != nil {
-		log.Panic(err)
-	}
-	return string(file)
-}
-
-// stringFor returns a textual representation of the arg, formatted according to its nature.
-func stringFor(arg interface{}) string {
-	switch arg := arg.(type) {
-	case int:
-		return fmt.Sprintf("%d", arg)
-	case string:
-		if len(arg) > 2 && arg[0] == '/' && arg[len(arg)-1] == '/' {
-			return fmt.Sprintf("%#q", arg)
-		}
-		return fmt.Sprintf("%q", arg)
-	default:
-		log.Panicf("unrecognized argument: %v type %T", arg, arg)
-	}
-	return ""
-}
-
-func (p *Presentation) code(file string, arg ...interface{}) (s string, err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			err = fmt.Errorf("%v", r)
-		}
-	}()
-
-	text := p.Corpus.contents(file)
-	var command string
-	switch len(arg) {
-	case 0:
-		// text is already whole file.
-		command = fmt.Sprintf("code %q", file)
-	case 1:
-		command = fmt.Sprintf("code %q %s", file, stringFor(arg[0]))
-		text = p.Corpus.oneLine(file, text, arg[0])
-	case 2:
-		command = fmt.Sprintf("code %q %s %s", file, stringFor(arg[0]), stringFor(arg[1]))
-		text = p.Corpus.multipleLines(file, text, arg[0], arg[1])
-	default:
-		return "", fmt.Errorf("incorrect code invocation: code %q [%v, ...] (%d arguments)", file, arg[0], len(arg))
-	}
-	// Trim spaces from output.
-	text = strings.Trim(text, "\n")
-	// Replace tabs by spaces, which work better in HTML.
-	text = strings.Replace(text, "\t", "    ", -1)
-	var buf bytes.Buffer
-	// HTML-escape text and syntax-color comments like elsewhere.
-	FormatText(&buf, []byte(text), -1, true, "", nil)
-	// Include the command as a comment.
-	text = fmt.Sprintf("<pre><!--{{%s}}\n-->%s</pre>", command, buf.Bytes())
-	return text, nil
-}
-
-// parseArg returns the integer or string value of the argument and tells which it is.
-func parseArg(arg interface{}, file string, max int) (ival int, sval string, isInt bool) {
-	switch n := arg.(type) {
-	case int:
-		if n <= 0 || n > max {
-			log.Panicf("%q:%d is out of range", file, n)
-		}
-		return n, "", true
-	case string:
-		return 0, n, false
-	}
-	log.Panicf("unrecognized argument %v type %T", arg, arg)
-	return
-}
-
-// oneLine returns the single line generated by a two-argument code invocation.
-func (c *Corpus) oneLine(file, text string, arg interface{}) string {
-	lines := strings.SplitAfter(c.contents(file), "\n")
-	line, pattern, isInt := parseArg(arg, file, len(lines))
-	if isInt {
-		return lines[line-1]
-	}
-	return lines[match(file, 0, lines, pattern)-1]
-}
-
-// multipleLines returns the text generated by a three-argument code invocation.
-func (c *Corpus) multipleLines(file, text string, arg1, arg2 interface{}) string {
-	lines := strings.SplitAfter(c.contents(file), "\n")
-	line1, pattern1, isInt1 := parseArg(arg1, file, len(lines))
-	line2, pattern2, isInt2 := parseArg(arg2, file, len(lines))
-	if !isInt1 {
-		line1 = match(file, 0, lines, pattern1)
-	}
-	if !isInt2 {
-		line2 = match(file, line1, lines, pattern2)
-	} else if line2 < line1 {
-		log.Panicf("lines out of order for %q: %d %d", text, line1, line2)
-	}
-	for k := line1 - 1; k < line2; k++ {
-		if strings.HasSuffix(lines[k], "OMIT\n") {
-			lines[k] = ""
-		}
-	}
-	return strings.Join(lines[line1-1:line2], "")
-}
-
-// match identifies the input line that matches the pattern in a code invocation.
-// If start>0, match lines starting there rather than at the beginning.
-// The return value is 1-indexed.
-func match(file string, start int, lines []string, pattern string) int {
-	// $ matches the end of the file.
-	if pattern == "$" {
-		if len(lines) == 0 {
-			log.Panicf("%q: empty file", file)
-		}
-		return len(lines)
-	}
-	// /regexp/ matches the line that matches the regexp.
-	if len(pattern) > 2 && pattern[0] == '/' && pattern[len(pattern)-1] == '/' {
-		re, err := regexp.Compile(pattern[1 : len(pattern)-1])
-		if err != nil {
-			log.Panic(err)
-		}
-		for i := start; i < len(lines); i++ {
-			if re.MatchString(lines[i]) {
-				return i + 1
-			}
-		}
-		log.Panicf("%s: no match for %#q", file, pattern)
-	}
-	log.Panicf("unrecognized pattern: %q", pattern)
-	return 0
-}
diff --git a/cmd/golangorg/godoc/util/throttle.go b/cmd/golangorg/godoc/util/throttle.go
deleted file mode 100644
index 53d9ba6..0000000
--- a/cmd/golangorg/godoc/util/throttle.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package util
-
-import "time"
-
-// A Throttle permits throttling of a goroutine by
-// calling the Throttle method repeatedly.
-//
-type Throttle struct {
-	f  float64       // f = (1-r)/r for 0 < r < 1
-	dt time.Duration // minimum run time slice; >= 0
-	tr time.Duration // accumulated time running
-	ts time.Duration // accumulated time stopped
-	tt time.Time     // earliest throttle time (= time Throttle returned + tm)
-}
-
-// NewThrottle creates a new Throttle with a throttle value r and
-// a minimum allocated run time slice of dt:
-//
-//	r == 0: "empty" throttle; the goroutine is always sleeping
-//	r == 1: full throttle; the goroutine is never sleeping
-//
-// A value of r == 0.6 throttles a goroutine such that it runs
-// approx. 60% of the time, and sleeps approx. 40% of the time.
-// Values of r < 0 or r > 1 are clamped down to values between 0 and 1.
-// Values of dt < 0 are set to 0.
-//
-func NewThrottle(r float64, dt time.Duration) *Throttle {
-	var f float64
-	switch {
-	case r <= 0:
-		f = -1 // indicates always sleep
-	case r >= 1:
-		f = 0 // assume r == 1 (never sleep)
-	default:
-		// 0 < r < 1
-		f = (1 - r) / r
-	}
-	if dt < 0 {
-		dt = 0
-	}
-	return &Throttle{f: f, dt: dt, tt: time.Now().Add(dt)}
-}
-
-// Throttle calls time.Sleep such that over time the ratio tr/ts between
-// accumulated run (tr) and sleep times (ts) approximates the value 1/(1-r)
-// where r is the throttle value. Throttle returns immediately (w/o sleeping)
-// if less than tm ns have passed since the last call to Throttle.
-//
-func (p *Throttle) Throttle() {
-	if p.f < 0 {
-		select {} // always sleep
-	}
-
-	t0 := time.Now()
-	if t0.Before(p.tt) {
-		return // keep running (minimum time slice not exhausted yet)
-	}
-
-	// accumulate running time
-	p.tr += t0.Sub(p.tt) + p.dt
-
-	// compute sleep time
-	// Over time we want:
-	//
-	//	tr/ts = r/(1-r)
-	//
-	// Thus:
-	//
-	//	ts = tr*f with f = (1-r)/r
-	//
-	// After some incremental run time δr added to the total run time
-	// tr, the incremental sleep-time δs to get to the same ratio again
-	// after waking up from time.Sleep is:
-	if δs := time.Duration(float64(p.tr)*p.f) - p.ts; δs > 0 {
-		time.Sleep(δs)
-	}
-
-	// accumulate (actual) sleep time
-	t1 := time.Now()
-	p.ts += t1.Sub(t0)
-
-	// set earliest next throttle time
-	p.tt = t1.Add(p.dt)
-}
diff --git a/cmd/golangorg/godoc/util/util.go b/cmd/golangorg/godoc/util/util.go
deleted file mode 100644
index f0a26ef..0000000
--- a/cmd/golangorg/godoc/util/util.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package util contains utility types and functions for godoc.
-package util // import "golang.org/x/website/cmd/golangorg/godoc/util"
-
-import (
-	pathpkg "path"
-	"sync"
-	"time"
-	"unicode/utf8"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// An RWValue wraps a value and permits mutually exclusive
-// access to it and records the time the value was last set.
-type RWValue struct {
-	mutex     sync.RWMutex
-	value     interface{}
-	timestamp time.Time // time of last set()
-}
-
-func (v *RWValue) Set(value interface{}) {
-	v.mutex.Lock()
-	v.value = value
-	v.timestamp = time.Now()
-	v.mutex.Unlock()
-}
-
-func (v *RWValue) Get() (interface{}, time.Time) {
-	v.mutex.RLock()
-	defer v.mutex.RUnlock()
-	return v.value, v.timestamp
-}
-
-// IsText reports whether a significant prefix of s looks like correct UTF-8;
-// that is, if it is likely that s is human-readable text.
-func IsText(s []byte) bool {
-	const max = 1024 // at least utf8.UTFMax
-	if len(s) > max {
-		s = s[0:max]
-	}
-	for i, c := range string(s) {
-		if i+utf8.UTFMax > len(s) {
-			// last char may be incomplete - ignore
-			break
-		}
-		if c == 0xFFFD || c < ' ' && c != '\n' && c != '\t' && c != '\f' {
-			// decoding error or control character - not a text file
-			return false
-		}
-	}
-	return true
-}
-
-// textExt[x] is true if the extension x indicates a text file, and false otherwise.
-var textExt = map[string]bool{
-	".css": false, // must be served raw
-	".js":  false, // must be served raw
-}
-
-// IsTextFile reports whether the file has a known extension indicating
-// a text file, or if a significant chunk of the specified file looks like
-// correct UTF-8; that is, if it is likely that the file contains human-
-// readable text.
-func IsTextFile(fs vfs.Opener, filename string) bool {
-	// if the extension is known, use it for decision making
-	if isText, found := textExt[pathpkg.Ext(filename)]; found {
-		return isText
-	}
-
-	// the extension is not known; read an initial chunk
-	// of the file and check if it looks like text
-	f, err := fs.Open(filename)
-	if err != nil {
-		return false
-	}
-	defer f.Close()
-
-	var buf [1024]byte
-	n, err := f.Read(buf[0:])
-	if err != nil {
-		return false
-	}
-
-	return IsText(buf[0:n])
-}
diff --git a/cmd/golangorg/godoc/versions.go b/cmd/golangorg/godoc/versions.go
deleted file mode 100644
index f03c714..0000000
--- a/cmd/golangorg/godoc/versions.go
+++ /dev/null
@@ -1,224 +0,0 @@
-// 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.
-
-// This file caches information about which standard library types, methods,
-// and functions appeared in what version of Go
-
-package godoc
-
-import (
-	"bufio"
-	"go/build"
-	"log"
-	"os"
-	"path/filepath"
-	"strings"
-	"unicode"
-)
-
-// apiVersions is a map of packages to information about those packages'
-// symbols and when they were added to Go.
-//
-// Only things added after Go1 are tracked. Version strings are of the
-// form "1.1", "1.2", etc.
-type apiVersions map[string]pkgAPIVersions // keyed by Go package ("net/http")
-
-// pkgAPIVersions contains information about which version of Go added
-// certain package symbols.
-//
-// Only things added after Go1 are tracked. Version strings are of the
-// form "1.1", "1.2", etc.
-type pkgAPIVersions struct {
-	typeSince   map[string]string            // "Server" -> "1.7"
-	methodSince map[string]map[string]string // "*Server" ->"Shutdown"->1.8
-	funcSince   map[string]string            // "NewServer" -> "1.7"
-	fieldSince  map[string]map[string]string // "ClientTrace" -> "Got1xxResponse" -> "1.11"
-}
-
-// sinceVersionFunc returns a string (such as "1.7") specifying which Go
-// version introduced a symbol, unless it was introduced in Go1, in
-// which case it returns the empty string.
-//
-// The kind is one of "type", "method", or "func".
-//
-// The receiver is only used for "methods" and specifies the receiver type,
-// such as "*Server".
-//
-// The name is the symbol name ("Server") and the pkg is the package
-// ("net/http").
-func (v apiVersions) sinceVersionFunc(kind, receiver, name, pkg string) string {
-	pv := v[pkg]
-	switch kind {
-	case "func":
-		return pv.funcSince[name]
-	case "type":
-		return pv.typeSince[name]
-	case "method":
-		return pv.methodSince[receiver][name]
-	}
-	return ""
-}
-
-// versionedRow represents an API feature, a parsed line of a
-// $GOROOT/api/go.*txt file.
-type versionedRow struct {
-	pkg        string // "net/http"
-	kind       string // "type", "func", "method", "field" TODO: "const", "var"
-	recv       string // for methods, the receiver type ("Server", "*Server")
-	name       string // name of type, (struct) field, func, method
-	structName string // for struct fields, the outer struct name
-}
-
-// versionParser parses $GOROOT/api/go*.txt files and stores them in in its rows field.
-type versionParser struct {
-	res apiVersions // initialized lazily
-}
-
-func (vp *versionParser) parseFile(name string) error {
-	base := filepath.Base(name)
-	ver := strings.TrimPrefix(strings.TrimSuffix(base, ".txt"), "go")
-	if ver == "1" {
-		return nil
-	}
-	f, err := os.Open(name)
-	if err != nil {
-		return err
-	}
-	defer f.Close()
-
-	sc := bufio.NewScanner(f)
-	for sc.Scan() {
-		row, ok := parseRow(sc.Text())
-		if !ok {
-			continue
-		}
-		if vp.res == nil {
-			vp.res = make(apiVersions)
-		}
-		pkgi, ok := vp.res[row.pkg]
-		if !ok {
-			pkgi = pkgAPIVersions{
-				typeSince:   make(map[string]string),
-				methodSince: make(map[string]map[string]string),
-				funcSince:   make(map[string]string),
-				fieldSince:  make(map[string]map[string]string),
-			}
-			vp.res[row.pkg] = pkgi
-		}
-		switch row.kind {
-		case "func":
-			pkgi.funcSince[row.name] = ver
-		case "type":
-			pkgi.typeSince[row.name] = ver
-		case "method":
-			if _, ok := pkgi.methodSince[row.recv]; !ok {
-				pkgi.methodSince[row.recv] = make(map[string]string)
-			}
-			pkgi.methodSince[row.recv][row.name] = ver
-		case "field":
-			if _, ok := pkgi.fieldSince[row.structName]; !ok {
-				pkgi.fieldSince[row.structName] = make(map[string]string)
-			}
-			pkgi.fieldSince[row.structName][row.name] = ver
-		}
-	}
-	return sc.Err()
-}
-
-func parseRow(s string) (vr versionedRow, ok bool) {
-	if !strings.HasPrefix(s, "pkg ") {
-		// Skip comments, blank lines, etc.
-		return
-	}
-	rest := s[len("pkg "):]
-	endPkg := strings.IndexFunc(rest, func(r rune) bool { return !(unicode.IsLetter(r) || r == '/' || unicode.IsDigit(r)) })
-	if endPkg == -1 {
-		return
-	}
-	vr.pkg, rest = rest[:endPkg], rest[endPkg:]
-	if !strings.HasPrefix(rest, ", ") {
-		// If the part after the pkg name isn't ", ", then it's a OS/ARCH-dependent line of the form:
-		//   pkg syscall (darwin-amd64), const ImplementsGetwd = false
-		// We skip those for now.
-		return
-	}
-	rest = rest[len(", "):]
-
-	switch {
-	case strings.HasPrefix(rest, "type "):
-		rest = rest[len("type "):]
-		sp := strings.IndexByte(rest, ' ')
-		if sp == -1 {
-			return
-		}
-		vr.name, rest = rest[:sp], rest[sp+1:]
-		if !strings.HasPrefix(rest, "struct, ") {
-			vr.kind = "type"
-			return vr, true
-		}
-		rest = rest[len("struct, "):]
-		if i := strings.IndexByte(rest, ' '); i != -1 {
-			vr.kind = "field"
-			vr.structName = vr.name
-			vr.name = rest[:i]
-			return vr, true
-		}
-	case strings.HasPrefix(rest, "func "):
-		vr.kind = "func"
-		rest = rest[len("func "):]
-		if i := strings.IndexByte(rest, '('); i != -1 {
-			vr.name = rest[:i]
-			return vr, true
-		}
-	case strings.HasPrefix(rest, "method "): // "method (*File) SetModTime(time.Time)"
-		vr.kind = "method"
-		rest = rest[len("method "):] // "(*File) SetModTime(time.Time)"
-		sp := strings.IndexByte(rest, ' ')
-		if sp == -1 {
-			return
-		}
-		vr.recv = strings.Trim(rest[:sp], "()") // "*File"
-		rest = rest[sp+1:]                      // SetMode(os.FileMode)
-		paren := strings.IndexByte(rest, '(')
-		if paren == -1 {
-			return
-		}
-		vr.name = rest[:paren]
-		return vr, true
-	}
-	return // TODO: handle more cases
-}
-
-// InitVersionInfo parses the $GOROOT/api/go*.txt API definition files to discover
-// which API features were added in which Go releases.
-func (c *Corpus) InitVersionInfo() {
-	var err error
-	c.pkgAPIInfo, err = parsePackageAPIInfo()
-	if err != nil {
-		// TODO: consider making this fatal, after the Go 1.11 cycle.
-		log.Printf("godoc: error parsing API version files: %v", err)
-	}
-}
-
-func parsePackageAPIInfo() (apiVersions, error) {
-	var apiGlob string
-	if os.Getenv("GOROOT") == "" {
-		apiGlob = filepath.Join(build.Default.GOROOT, "api", "go*.txt")
-	} else {
-		apiGlob = filepath.Join(os.Getenv("GOROOT"), "api", "go*.txt")
-	}
-
-	files, err := filepath.Glob(apiGlob)
-	if err != nil {
-		return nil, err
-	}
-
-	vp := new(versionParser)
-	for _, f := range files {
-		if err := vp.parseFile(f); err != nil {
-			return nil, err
-		}
-	}
-	return vp.res, nil
-}
diff --git a/cmd/golangorg/godoc/versions_test.go b/cmd/golangorg/godoc/versions_test.go
deleted file mode 100644
index ad2d5e4..0000000
--- a/cmd/golangorg/godoc/versions_test.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// 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.
-
-package godoc
-
-import (
-	"go/build"
-	"testing"
-)
-
-func TestParseVersionRow(t *testing.T) {
-	tests := []struct {
-		row  string
-		want versionedRow
-	}{
-		{
-			row: "# comment",
-		},
-		{
-			row: "",
-		},
-		{
-			row: "pkg archive/tar, type Writer struct",
-			want: versionedRow{
-				pkg:  "archive/tar",
-				kind: "type",
-				name: "Writer",
-			},
-		},
-		{
-			row: "pkg archive/tar, type Header struct, AccessTime time.Time",
-			want: versionedRow{
-				pkg:        "archive/tar",
-				kind:       "field",
-				structName: "Header",
-				name:       "AccessTime",
-			},
-		},
-		{
-			row: "pkg archive/tar, method (*Reader) Read([]uint8) (int, error)",
-			want: versionedRow{
-				pkg:  "archive/tar",
-				kind: "method",
-				name: "Read",
-				recv: "*Reader",
-			},
-		},
-		{
-			row: "pkg archive/zip, func FileInfoHeader(os.FileInfo) (*FileHeader, error)",
-			want: versionedRow{
-				pkg:  "archive/zip",
-				kind: "func",
-				name: "FileInfoHeader",
-			},
-		},
-		{
-			row: "pkg encoding/base32, method (Encoding) WithPadding(int32) *Encoding",
-			want: versionedRow{
-				pkg:  "encoding/base32",
-				kind: "method",
-				name: "WithPadding",
-				recv: "Encoding",
-			},
-		},
-	}
-
-	for i, tt := range tests {
-		got, ok := parseRow(tt.row)
-		if !ok {
-			got = versionedRow{}
-		}
-		if got != tt.want {
-			t.Errorf("%d. parseRow(%q) = %+v; want %+v", i, tt.row, got, tt.want)
-		}
-	}
-}
-
-// hasTag checks whether a given release tag is contained in the current version
-// of the go binary.
-func hasTag(t string) bool {
-	for _, v := range build.Default.ReleaseTags {
-		if t == v {
-			return true
-		}
-	}
-	return false
-}
-
-func TestAPIVersion(t *testing.T) {
-	av, err := parsePackageAPIInfo()
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, tc := range []struct {
-		kind     string
-		pkg      string
-		name     string
-		receiver string
-		want     string
-	}{
-		// Things that were added post-1.0 should appear
-		{"func", "archive/tar", "FileInfoHeader", "", "1.1"},
-		{"type", "bufio", "Scanner", "", "1.1"},
-		{"method", "bufio", "WriteTo", "*Reader", "1.1"},
-
-		{"func", "bytes", "LastIndexByte", "", "1.5"},
-		{"type", "crypto", "Decrypter", "", "1.5"},
-		{"method", "crypto/rsa", "Decrypt", "*PrivateKey", "1.5"},
-		{"method", "debug/dwarf", "GoString", "Class", "1.5"},
-
-		{"func", "os", "IsTimeout", "", "1.10"},
-		{"type", "strings", "Builder", "", "1.10"},
-		{"method", "strings", "WriteString", "*Builder", "1.10"},
-
-		// Things from package syscall should never appear
-		{"func", "syscall", "FchFlags", "", ""},
-		{"type", "syscall", "Inet4Pktinfo", "", ""},
-
-		// Things added in Go 1 should never appear
-		{"func", "archive/tar", "NewReader", "", ""},
-		{"type", "archive/tar", "Header", "", ""},
-		{"method", "archive/tar", "Next", "*Reader", ""},
-	} {
-		if tc.want != "" && !hasTag("go"+tc.want) {
-			continue
-		}
-		if got := av.sinceVersionFunc(tc.kind, tc.receiver, tc.name, tc.pkg); got != tc.want {
-			t.Errorf(`sinceFunc("%s", "%s", "%s", "%s") = "%s"; want "%s"`, tc.kind, tc.receiver, tc.name, tc.pkg, got, tc.want)
-		}
-	}
-}
diff --git a/cmd/golangorg/godoc/vfs/emptyvfs.go b/cmd/golangorg/godoc/vfs/emptyvfs.go
deleted file mode 100644
index 0803206..0000000
--- a/cmd/golangorg/godoc/vfs/emptyvfs.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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 vfs
-
-import (
-	"fmt"
-	"os"
-	"time"
-)
-
-// NewNameSpace returns a NameSpace pre-initialized with an empty
-// emulated directory mounted on the root mount point "/". This
-// allows directory traversal routines to work properly even if
-// a folder is not explicitly mounted at root by the user.
-func NewNameSpace() NameSpace {
-	ns := NameSpace{}
-	ns.Bind("/", &emptyVFS{}, "/", BindReplace)
-	return ns
-}
-
-// type emptyVFS emulates a FileSystem consisting of an empty directory
-type emptyVFS struct{}
-
-// Open implements Opener. Since emptyVFS is an empty directory, all
-// attempts to open a file should returns errors.
-func (e *emptyVFS) Open(path string) (ReadSeekCloser, error) {
-	if path == "/" {
-		return nil, fmt.Errorf("open: / is a directory")
-	}
-	return nil, os.ErrNotExist
-}
-
-// Stat returns os.FileInfo  for an empty directory if the path is
-// is root "/" or error. os.FileInfo is implemented by emptyVFS
-func (e *emptyVFS) Stat(path string) (os.FileInfo, error) {
-	if path == "/" {
-		return e, nil
-	}
-	return nil, os.ErrNotExist
-}
-
-func (e *emptyVFS) Lstat(path string) (os.FileInfo, error) {
-	return e.Stat(path)
-}
-
-// ReadDir returns an empty os.FileInfo slice for "/", else error.
-func (e *emptyVFS) ReadDir(path string) ([]os.FileInfo, error) {
-	if path == "/" {
-		return []os.FileInfo{}, nil
-	}
-	return nil, os.ErrNotExist
-}
-
-func (e *emptyVFS) String() string {
-	return "emptyVFS(/)"
-}
-
-func (e *emptyVFS) RootType(path string) RootType {
-	return ""
-}
-
-// These functions below implement os.FileInfo for the single
-// empty emulated directory.
-
-func (e *emptyVFS) Name() string {
-	return "/"
-}
-
-func (e *emptyVFS) Size() int64 {
-	return 0
-}
-
-func (e *emptyVFS) Mode() os.FileMode {
-	return os.ModeDir | os.ModePerm
-}
-
-func (e *emptyVFS) ModTime() time.Time {
-	return time.Time{}
-}
-
-func (e *emptyVFS) IsDir() bool {
-	return true
-}
-
-func (e *emptyVFS) Sys() interface{} {
-	return nil
-}
diff --git a/cmd/golangorg/godoc/vfs/emptyvfs_test.go b/cmd/golangorg/godoc/vfs/emptyvfs_test.go
deleted file mode 100644
index 8f5926d..0000000
--- a/cmd/golangorg/godoc/vfs/emptyvfs_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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 vfs_test
-
-import (
-	"testing"
-	"time"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-	"golang.org/x/website/cmd/golangorg/godoc/vfs/mapfs"
-)
-
-func TestNewNameSpace(t *testing.T) {
-
-	// We will mount this filesystem under /fs1
-	mount := mapfs.New(map[string]string{"fs1file": "abcdefgh"})
-
-	// Existing process. This should give error on Stat("/")
-	t1 := vfs.NameSpace{}
-	t1.Bind("/fs1", mount, "/", vfs.BindReplace)
-
-	// using NewNameSpace. This should work fine.
-	t2 := vfs.NewNameSpace()
-	t2.Bind("/fs1", mount, "/", vfs.BindReplace)
-
-	testcases := map[string][]bool{
-		"/":            {false, true},
-		"/fs1":         {true, true},
-		"/fs1/fs1file": {true, true},
-	}
-
-	fss := []vfs.FileSystem{t1, t2}
-
-	for j, fs := range fss {
-		for k, v := range testcases {
-			_, err := fs.Stat(k)
-			result := err == nil
-			if result != v[j] {
-				t.Errorf("fs: %d, testcase: %s, want: %v, got: %v, err: %s", j, k, v[j], result, err)
-			}
-		}
-	}
-
-	fi, err := t2.Stat("/")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if fi.Name() != "/" {
-		t.Errorf("t2.Name() : want:%s got:%s", "/", fi.Name())
-	}
-
-	if !fi.ModTime().IsZero() {
-		t.Errorf("t2.Modime() : want:%v got:%v", time.Time{}, fi.ModTime())
-	}
-}
diff --git a/cmd/golangorg/godoc/vfs/gatefs/gatefs.go b/cmd/golangorg/godoc/vfs/gatefs/gatefs.go
deleted file mode 100644
index e184857..0000000
--- a/cmd/golangorg/godoc/vfs/gatefs/gatefs.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package gatefs provides an implementation of the FileSystem
-// interface that wraps another FileSystem and limits its concurrency.
-package gatefs // import "golang.org/x/website/cmd/golangorg/godoc/vfs/gatefs"
-
-import (
-	"fmt"
-	"os"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// New returns a new FileSystem that delegates to fs.
-// If gateCh is non-nil and buffered, it's used as a gate
-// to limit concurrency on calls to fs.
-func New(fs vfs.FileSystem, gateCh chan bool) vfs.FileSystem {
-	if cap(gateCh) == 0 {
-		return fs
-	}
-	return gatefs{fs, gate(gateCh)}
-}
-
-type gate chan bool
-
-func (g gate) enter() { g <- true }
-func (g gate) leave() { <-g }
-
-type gatefs struct {
-	fs vfs.FileSystem
-	gate
-}
-
-func (fs gatefs) String() string {
-	return fmt.Sprintf("gated(%s, %d)", fs.fs.String(), cap(fs.gate))
-}
-
-func (fs gatefs) RootType(path string) vfs.RootType {
-	return fs.fs.RootType(path)
-}
-
-func (fs gatefs) Open(p string) (vfs.ReadSeekCloser, error) {
-	fs.enter()
-	defer fs.leave()
-	rsc, err := fs.fs.Open(p)
-	if err != nil {
-		return nil, err
-	}
-	return gatef{rsc, fs.gate}, nil
-}
-
-func (fs gatefs) Lstat(p string) (os.FileInfo, error) {
-	fs.enter()
-	defer fs.leave()
-	return fs.fs.Lstat(p)
-}
-
-func (fs gatefs) Stat(p string) (os.FileInfo, error) {
-	fs.enter()
-	defer fs.leave()
-	return fs.fs.Stat(p)
-}
-
-func (fs gatefs) ReadDir(p string) ([]os.FileInfo, error) {
-	fs.enter()
-	defer fs.leave()
-	return fs.fs.ReadDir(p)
-}
-
-type gatef struct {
-	rsc vfs.ReadSeekCloser
-	gate
-}
-
-func (f gatef) Read(p []byte) (n int, err error) {
-	f.enter()
-	defer f.leave()
-	return f.rsc.Read(p)
-}
-
-func (f gatef) Seek(offset int64, whence int) (ret int64, err error) {
-	f.enter()
-	defer f.leave()
-	return f.rsc.Seek(offset, whence)
-}
-
-func (f gatef) Close() error {
-	f.enter()
-	defer f.leave()
-	return f.rsc.Close()
-}
diff --git a/cmd/golangorg/godoc/vfs/gatefs/gatefs_test.go b/cmd/golangorg/godoc/vfs/gatefs/gatefs_test.go
deleted file mode 100644
index b21b4a5..0000000
--- a/cmd/golangorg/godoc/vfs/gatefs/gatefs_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.
-
-package gatefs_test
-
-import (
-	"os"
-	"runtime"
-	"testing"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-	"golang.org/x/website/cmd/golangorg/godoc/vfs/gatefs"
-)
-
-func TestRootType(t *testing.T) {
-	goPath := os.Getenv("GOPATH")
-	var expectedType vfs.RootType
-	if goPath == "" {
-		expectedType = ""
-	} else {
-		expectedType = vfs.RootTypeGoPath
-	}
-	tests := []struct {
-		path   string
-		fsType vfs.RootType
-	}{
-		{runtime.GOROOT(), vfs.RootTypeGoRoot},
-		{goPath, expectedType},
-		{"/tmp/", ""},
-	}
-
-	for _, item := range tests {
-		fs := gatefs.New(vfs.OS(item.path), make(chan bool, 1))
-		if fs.RootType("path") != item.fsType {
-			t.Errorf("unexpected fsType. Expected- %v, Got- %v", item.fsType, fs.RootType("path"))
-		}
-	}
-}
diff --git a/cmd/golangorg/godoc/vfs/httpfs/httpfs.go b/cmd/golangorg/godoc/vfs/httpfs/httpfs.go
deleted file mode 100644
index a46fa23..0000000
--- a/cmd/golangorg/godoc/vfs/httpfs/httpfs.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package httpfs implements http.FileSystem using a godoc vfs.FileSystem.
-package httpfs // import "golang.org/x/website/cmd/golangorg/godoc/vfs/httpfs"
-
-import (
-	"fmt"
-	"io"
-	"net/http"
-	"os"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-func New(fs vfs.FileSystem) http.FileSystem {
-	return &httpFS{fs}
-}
-
-type httpFS struct {
-	fs vfs.FileSystem
-}
-
-func (h *httpFS) Open(name string) (http.File, error) {
-	fi, err := h.fs.Stat(name)
-	if err != nil {
-		return nil, err
-	}
-	if fi.IsDir() {
-		return &httpDir{h.fs, name, nil}, nil
-	}
-	f, err := h.fs.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	return &httpFile{h.fs, f, name}, nil
-}
-
-// httpDir implements http.File for a directory in a FileSystem.
-type httpDir struct {
-	fs      vfs.FileSystem
-	name    string
-	pending []os.FileInfo
-}
-
-func (h *httpDir) Close() error               { return nil }
-func (h *httpDir) Stat() (os.FileInfo, error) { return h.fs.Stat(h.name) }
-func (h *httpDir) Read([]byte) (int, error) {
-	return 0, fmt.Errorf("cannot Read from directory %s", h.name)
-}
-
-func (h *httpDir) Seek(offset int64, whence int) (int64, error) {
-	if offset == 0 && whence == 0 {
-		h.pending = nil
-		return 0, nil
-	}
-	return 0, fmt.Errorf("unsupported Seek in directory %s", h.name)
-}
-
-func (h *httpDir) Readdir(count int) ([]os.FileInfo, error) {
-	if h.pending == nil {
-		d, err := h.fs.ReadDir(h.name)
-		if err != nil {
-			return nil, err
-		}
-		if d == nil {
-			d = []os.FileInfo{} // not nil
-		}
-		h.pending = d
-	}
-
-	if len(h.pending) == 0 && count > 0 {
-		return nil, io.EOF
-	}
-	if count <= 0 || count > len(h.pending) {
-		count = len(h.pending)
-	}
-	d := h.pending[:count]
-	h.pending = h.pending[count:]
-	return d, nil
-}
-
-// httpFile implements http.File for a file (not directory) in a FileSystem.
-type httpFile struct {
-	fs vfs.FileSystem
-	vfs.ReadSeekCloser
-	name string
-}
-
-func (h *httpFile) Stat() (os.FileInfo, error) { return h.fs.Stat(h.name) }
-func (h *httpFile) Readdir(int) ([]os.FileInfo, error) {
-	return nil, fmt.Errorf("cannot Readdir from file %s", h.name)
-}
diff --git a/cmd/golangorg/godoc/vfs/mapfs/mapfs.go b/cmd/golangorg/godoc/vfs/mapfs/mapfs.go
deleted file mode 100644
index e92efe0..0000000
--- a/cmd/golangorg/godoc/vfs/mapfs/mapfs.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package mapfs file provides an implementation of the FileSystem
-// interface based on the contents of a map[string]string.
-package mapfs // import "golang.org/x/website/cmd/golangorg/godoc/vfs/mapfs"
-
-import (
-	"io"
-	"os"
-	pathpkg "path"
-	"sort"
-	"strings"
-	"time"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// New returns a new FileSystem from the provided map.
-// Map keys should be forward slash-separated pathnames
-// and not contain a leading slash.
-func New(m map[string]string) vfs.FileSystem {
-	return mapFS(m)
-}
-
-// mapFS is the map based implementation of FileSystem
-type mapFS map[string]string
-
-func (fs mapFS) String() string { return "mapfs" }
-
-func (fs mapFS) RootType(p string) vfs.RootType {
-	return ""
-}
-
-func (fs mapFS) Close() error { return nil }
-
-func filename(p string) string {
-	return strings.TrimPrefix(p, "/")
-}
-
-func (fs mapFS) Open(p string) (vfs.ReadSeekCloser, error) {
-	b, ok := fs[filename(p)]
-	if !ok {
-		return nil, os.ErrNotExist
-	}
-	return nopCloser{strings.NewReader(b)}, nil
-}
-
-func fileInfo(name, contents string) os.FileInfo {
-	return mapFI{name: pathpkg.Base(name), size: len(contents)}
-}
-
-func dirInfo(name string) os.FileInfo {
-	return mapFI{name: pathpkg.Base(name), dir: true}
-}
-
-func (fs mapFS) Lstat(p string) (os.FileInfo, error) {
-	b, ok := fs[filename(p)]
-	if ok {
-		return fileInfo(p, b), nil
-	}
-	ents, _ := fs.ReadDir(p)
-	if len(ents) > 0 {
-		return dirInfo(p), nil
-	}
-	return nil, os.ErrNotExist
-}
-
-func (fs mapFS) Stat(p string) (os.FileInfo, error) {
-	return fs.Lstat(p)
-}
-
-// slashdir returns path.Dir(p), but special-cases paths not beginning
-// with a slash to be in the root.
-func slashdir(p string) string {
-	d := pathpkg.Dir(p)
-	if d == "." {
-		return "/"
-	}
-	if strings.HasPrefix(p, "/") {
-		return d
-	}
-	return "/" + d
-}
-
-func (fs mapFS) ReadDir(p string) ([]os.FileInfo, error) {
-	p = pathpkg.Clean(p)
-	var ents []string
-	fim := make(map[string]os.FileInfo) // base -> fi
-	for fn, b := range fs {
-		dir := slashdir(fn)
-		isFile := true
-		var lastBase string
-		for {
-			if dir == p {
-				base := lastBase
-				if isFile {
-					base = pathpkg.Base(fn)
-				}
-				if fim[base] == nil {
-					var fi os.FileInfo
-					if isFile {
-						fi = fileInfo(fn, b)
-					} else {
-						fi = dirInfo(base)
-					}
-					ents = append(ents, base)
-					fim[base] = fi
-				}
-			}
-			if dir == "/" {
-				break
-			} else {
-				isFile = false
-				lastBase = pathpkg.Base(dir)
-				dir = pathpkg.Dir(dir)
-			}
-		}
-	}
-	if len(ents) == 0 {
-		return nil, os.ErrNotExist
-	}
-
-	sort.Strings(ents)
-	var list []os.FileInfo
-	for _, dir := range ents {
-		list = append(list, fim[dir])
-	}
-	return list, nil
-}
-
-// mapFI is the map-based implementation of FileInfo.
-type mapFI struct {
-	name string
-	size int
-	dir  bool
-}
-
-func (fi mapFI) IsDir() bool        { return fi.dir }
-func (fi mapFI) ModTime() time.Time { return time.Time{} }
-func (fi mapFI) Mode() os.FileMode {
-	if fi.IsDir() {
-		return 0755 | os.ModeDir
-	}
-	return 0444
-}
-func (fi mapFI) Name() string     { return pathpkg.Base(fi.name) }
-func (fi mapFI) Size() int64      { return int64(fi.size) }
-func (fi mapFI) Sys() interface{} { return nil }
-
-type nopCloser struct {
-	io.ReadSeeker
-}
-
-func (nc nopCloser) Close() error { return nil }
diff --git a/cmd/golangorg/godoc/vfs/mapfs/mapfs_test.go b/cmd/golangorg/godoc/vfs/mapfs/mapfs_test.go
deleted file mode 100644
index 6b7db29..0000000
--- a/cmd/golangorg/godoc/vfs/mapfs/mapfs_test.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mapfs
-
-import (
-	"io/ioutil"
-	"os"
-	"reflect"
-	"testing"
-)
-
-func TestOpenRoot(t *testing.T) {
-	fs := New(map[string]string{
-		"foo/bar/three.txt": "a",
-		"foo/bar.txt":       "b",
-		"top.txt":           "c",
-		"other-top.txt":     "d",
-	})
-	tests := []struct {
-		path string
-		want string
-	}{
-		{"/foo/bar/three.txt", "a"},
-		{"foo/bar/three.txt", "a"},
-		{"foo/bar.txt", "b"},
-		{"top.txt", "c"},
-		{"/top.txt", "c"},
-		{"other-top.txt", "d"},
-		{"/other-top.txt", "d"},
-	}
-	for _, tt := range tests {
-		rsc, err := fs.Open(tt.path)
-		if err != nil {
-			t.Errorf("Open(%q) = %v", tt.path, err)
-			continue
-		}
-		slurp, err := ioutil.ReadAll(rsc)
-		if err != nil {
-			t.Error(err)
-		}
-		if string(slurp) != tt.want {
-			t.Errorf("Read(%q) = %q; want %q", tt.path, tt.want, slurp)
-		}
-		rsc.Close()
-	}
-
-	_, err := fs.Open("/xxxx")
-	if !os.IsNotExist(err) {
-		t.Errorf("ReadDir /xxxx = %v; want os.IsNotExist error", err)
-	}
-}
-
-func TestReaddir(t *testing.T) {
-	fs := New(map[string]string{
-		"foo/bar/three.txt": "333",
-		"foo/bar.txt":       "22",
-		"top.txt":           "top.txt file",
-		"other-top.txt":     "other-top.txt file",
-	})
-	tests := []struct {
-		dir  string
-		want []os.FileInfo
-	}{
-		{
-			dir: "/",
-			want: []os.FileInfo{
-				mapFI{name: "foo", dir: true},
-				mapFI{name: "other-top.txt", size: len("other-top.txt file")},
-				mapFI{name: "top.txt", size: len("top.txt file")},
-			},
-		},
-		{
-			dir: "/foo",
-			want: []os.FileInfo{
-				mapFI{name: "bar", dir: true},
-				mapFI{name: "bar.txt", size: 2},
-			},
-		},
-		{
-			dir: "/foo/",
-			want: []os.FileInfo{
-				mapFI{name: "bar", dir: true},
-				mapFI{name: "bar.txt", size: 2},
-			},
-		},
-		{
-			dir: "/foo/bar",
-			want: []os.FileInfo{
-				mapFI{name: "three.txt", size: 3},
-			},
-		},
-	}
-	for _, tt := range tests {
-		fis, err := fs.ReadDir(tt.dir)
-		if err != nil {
-			t.Errorf("ReadDir(%q) = %v", tt.dir, err)
-			continue
-		}
-		if !reflect.DeepEqual(fis, tt.want) {
-			t.Errorf("ReadDir(%q) = %#v; want %#v", tt.dir, fis, tt.want)
-			continue
-		}
-	}
-
-	_, err := fs.ReadDir("/xxxx")
-	if !os.IsNotExist(err) {
-		t.Errorf("ReadDir /xxxx = %v; want os.IsNotExist error", err)
-	}
-}
diff --git a/cmd/golangorg/godoc/vfs/namespace.go b/cmd/golangorg/godoc/vfs/namespace.go
deleted file mode 100644
index b8a1122..0000000
--- a/cmd/golangorg/godoc/vfs/namespace.go
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vfs
-
-import (
-	"fmt"
-	"io"
-	"os"
-	pathpkg "path"
-	"sort"
-	"strings"
-	"time"
-)
-
-// Setting debugNS = true will enable debugging prints about
-// name space translations.
-const debugNS = false
-
-// A NameSpace is a file system made up of other file systems
-// mounted at specific locations in the name space.
-//
-// The representation is a map from mount point locations
-// to the list of file systems mounted at that location.  A traditional
-// Unix mount table would use a single file system per mount point,
-// but we want to be able to mount multiple file systems on a single
-// mount point and have the system behave as if the union of those
-// file systems were present at the mount point.
-// For example, if the OS file system has a Go installation in
-// c:\Go and additional Go path trees in  d:\Work1 and d:\Work2, then
-// this name space creates the view we want for the godoc server:
-//
-//	NameSpace{
-//		"/": {
-//			{old: "/", fs: OS(`c:\Go`), new: "/"},
-//		},
-//		"/src/pkg": {
-//			{old: "/src/pkg", fs: OS(`c:\Go`), new: "/src/pkg"},
-//			{old: "/src/pkg", fs: OS(`d:\Work1`), new: "/src"},
-//			{old: "/src/pkg", fs: OS(`d:\Work2`), new: "/src"},
-//		},
-//	}
-//
-// This is created by executing:
-//
-//	ns := NameSpace{}
-//	ns.Bind("/", OS(`c:\Go`), "/", BindReplace)
-//	ns.Bind("/src/pkg", OS(`d:\Work1`), "/src", BindAfter)
-//	ns.Bind("/src/pkg", OS(`d:\Work2`), "/src", BindAfter)
-//
-// A particular mount point entry is a triple (old, fs, new), meaning that to
-// operate on a path beginning with old, replace that prefix (old) with new
-// and then pass that path to the FileSystem implementation fs.
-//
-// If you do not explicitly mount a FileSystem at the root mountpoint "/" of the
-// NameSpace like above, Stat("/") will return a "not found" error which could
-// break typical directory traversal routines. In such cases, use NewNameSpace()
-// to get a NameSpace pre-initialized with an emulated empty directory at root.
-//
-// Given this name space, a ReadDir of /src/pkg/code will check each prefix
-// of the path for a mount point (first /src/pkg/code, then /src/pkg, then /src,
-// then /), stopping when it finds one.  For the above example, /src/pkg/code
-// will find the mount point at /src/pkg:
-//
-//	{old: "/src/pkg", fs: OS(`c:\Go`), new: "/src/pkg"},
-//	{old: "/src/pkg", fs: OS(`d:\Work1`), new: "/src"},
-//	{old: "/src/pkg", fs: OS(`d:\Work2`), new: "/src"},
-//
-// ReadDir will when execute these three calls and merge the results:
-//
-//	OS(`c:\Go`).ReadDir("/src/pkg/code")
-//	OS(`d:\Work1').ReadDir("/src/code")
-//	OS(`d:\Work2').ReadDir("/src/code")
-//
-// Note that the "/src/pkg" in "/src/pkg/code" has been replaced by
-// just "/src" in the final two calls.
-//
-// OS is itself an implementation of a file system: it implements
-// OS(`c:\Go`).ReadDir("/src/pkg/code") as ioutil.ReadDir(`c:\Go\src\pkg\code`).
-//
-// Because the new path is evaluated by fs (here OS(root)), another way
-// to read the mount table is to mentally combine fs+new, so that this table:
-//
-//	{old: "/src/pkg", fs: OS(`c:\Go`), new: "/src/pkg"},
-//	{old: "/src/pkg", fs: OS(`d:\Work1`), new: "/src"},
-//	{old: "/src/pkg", fs: OS(`d:\Work2`), new: "/src"},
-//
-// reads as:
-//
-//	"/src/pkg" -> c:\Go\src\pkg
-//	"/src/pkg" -> d:\Work1\src
-//	"/src/pkg" -> d:\Work2\src
-//
-// An invariant (a redundancy) of the name space representation is that
-// ns[mtpt][i].old is always equal to mtpt (in the example, ns["/src/pkg"]'s
-// mount table entries always have old == "/src/pkg").  The 'old' field is
-// useful to callers, because they receive just a []mountedFS and not any
-// other indication of which mount point was found.
-//
-type NameSpace map[string][]mountedFS
-
-// A mountedFS handles requests for path by replacing
-// a prefix 'old' with 'new' and then calling the fs methods.
-type mountedFS struct {
-	old string
-	fs  FileSystem
-	new string
-}
-
-// hasPathPrefix returns true if x == y or x == y + "/" + more
-func hasPathPrefix(x, y string) bool {
-	return x == y || strings.HasPrefix(x, y) && (strings.HasSuffix(y, "/") || strings.HasPrefix(x[len(y):], "/"))
-}
-
-// translate translates path for use in m, replacing old with new.
-//
-// mountedFS{"/src/pkg", fs, "/src"}.translate("/src/pkg/code") == "/src/code".
-func (m mountedFS) translate(path string) string {
-	path = pathpkg.Clean("/" + path)
-	if !hasPathPrefix(path, m.old) {
-		panic("translate " + path + " but old=" + m.old)
-	}
-	return pathpkg.Join(m.new, path[len(m.old):])
-}
-
-func (NameSpace) String() string {
-	return "ns"
-}
-
-// Fprint writes a text representation of the name space to w.
-func (ns NameSpace) Fprint(w io.Writer) {
-	fmt.Fprint(w, "name space {\n")
-	var all []string
-	for mtpt := range ns {
-		all = append(all, mtpt)
-	}
-	sort.Strings(all)
-	for _, mtpt := range all {
-		fmt.Fprintf(w, "\t%s:\n", mtpt)
-		for _, m := range ns[mtpt] {
-			fmt.Fprintf(w, "\t\t%s %s\n", m.fs, m.new)
-		}
-	}
-	fmt.Fprint(w, "}\n")
-}
-
-// clean returns a cleaned, rooted path for evaluation.
-// It canonicalizes the path so that we can use string operations
-// to analyze it.
-func (NameSpace) clean(path string) string {
-	return pathpkg.Clean("/" + path)
-}
-
-type BindMode int
-
-const (
-	BindReplace BindMode = iota
-	BindBefore
-	BindAfter
-)
-
-// Bind causes references to old to redirect to the path new in newfs.
-// If mode is BindReplace, old redirections are discarded.
-// If mode is BindBefore, this redirection takes priority over existing ones,
-// but earlier ones are still consulted for paths that do not exist in newfs.
-// If mode is BindAfter, this redirection happens only after existing ones
-// have been tried and failed.
-func (ns NameSpace) Bind(old string, newfs FileSystem, new string, mode BindMode) {
-	old = ns.clean(old)
-	new = ns.clean(new)
-	m := mountedFS{old, newfs, new}
-	var mtpt []mountedFS
-	switch mode {
-	case BindReplace:
-		mtpt = append(mtpt, m)
-	case BindAfter:
-		mtpt = append(mtpt, ns.resolve(old)...)
-		mtpt = append(mtpt, m)
-	case BindBefore:
-		mtpt = append(mtpt, m)
-		mtpt = append(mtpt, ns.resolve(old)...)
-	}
-
-	// Extend m.old, m.new in inherited mount point entries.
-	for i := range mtpt {
-		m := &mtpt[i]
-		if m.old != old {
-			if !hasPathPrefix(old, m.old) {
-				// This should not happen.  If it does, panic so
-				// that we can see the call trace that led to it.
-				panic(fmt.Sprintf("invalid Bind: old=%q m={%q, %s, %q}", old, m.old, m.fs.String(), m.new))
-			}
-			suffix := old[len(m.old):]
-			m.old = pathpkg.Join(m.old, suffix)
-			m.new = pathpkg.Join(m.new, suffix)
-		}
-	}
-
-	ns[old] = mtpt
-}
-
-// resolve resolves a path to the list of mountedFS to use for path.
-func (ns NameSpace) resolve(path string) []mountedFS {
-	path = ns.clean(path)
-	for {
-		if m := ns[path]; m != nil {
-			if debugNS {
-				fmt.Printf("resolve %s: %v\n", path, m)
-			}
-			return m
-		}
-		if path == "/" {
-			break
-		}
-		path = pathpkg.Dir(path)
-	}
-	return nil
-}
-
-// Open implements the FileSystem Open method.
-func (ns NameSpace) Open(path string) (ReadSeekCloser, error) {
-	var err error
-	for _, m := range ns.resolve(path) {
-		if debugNS {
-			fmt.Printf("tx %s: %v\n", path, m.translate(path))
-		}
-		tp := m.translate(path)
-		r, err1 := m.fs.Open(tp)
-		if err1 == nil {
-			return r, nil
-		}
-		// IsNotExist errors in overlay FSes can mask real errors in
-		// the underlying FS, so ignore them if there is another error.
-		if err == nil || os.IsNotExist(err) {
-			err = err1
-		}
-	}
-	if err == nil {
-		err = &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist}
-	}
-	return nil, err
-}
-
-// stat implements the FileSystem Stat and Lstat methods.
-func (ns NameSpace) stat(path string, f func(FileSystem, string) (os.FileInfo, error)) (os.FileInfo, error) {
-	var err error
-	for _, m := range ns.resolve(path) {
-		fi, err1 := f(m.fs, m.translate(path))
-		if err1 == nil {
-			return fi, nil
-		}
-		if err == nil {
-			err = err1
-		}
-	}
-	if err == nil {
-		err = &os.PathError{Op: "stat", Path: path, Err: os.ErrNotExist}
-	}
-	return nil, err
-}
-
-func (ns NameSpace) Stat(path string) (os.FileInfo, error) {
-	return ns.stat(path, FileSystem.Stat)
-}
-
-func (ns NameSpace) Lstat(path string) (os.FileInfo, error) {
-	return ns.stat(path, FileSystem.Lstat)
-}
-
-// dirInfo is a trivial implementation of os.FileInfo for a directory.
-type dirInfo string
-
-func (d dirInfo) Name() string       { return string(d) }
-func (d dirInfo) Size() int64        { return 0 }
-func (d dirInfo) Mode() os.FileMode  { return os.ModeDir | 0555 }
-func (d dirInfo) ModTime() time.Time { return startTime }
-func (d dirInfo) IsDir() bool        { return true }
-func (d dirInfo) Sys() interface{}   { return nil }
-
-var startTime = time.Now()
-
-// ReadDir implements the FileSystem ReadDir method.  It's where most of the magic is.
-// (The rest is in resolve.)
-//
-// Logically, ReadDir must return the union of all the directories that are named
-// by path.  In order to avoid misinterpreting Go packages, of all the directories
-// that contain Go source code, we only include the files from the first,
-// but we include subdirectories from all.
-//
-// ReadDir must also return directory entries needed to reach mount points.
-// If the name space looks like the example in the type NameSpace comment,
-// but c:\Go does not have a src/pkg subdirectory, we still want to be able
-// to find that subdirectory, because we've mounted d:\Work1 and d:\Work2
-// there.  So if we don't see "src" in the directory listing for c:\Go, we add an
-// entry for it before returning.
-//
-func (ns NameSpace) ReadDir(path string) ([]os.FileInfo, error) {
-	path = ns.clean(path)
-
-	var (
-		haveGo   = false
-		haveName = map[string]bool{}
-		all      []os.FileInfo
-		err      error
-		first    []os.FileInfo
-	)
-
-	for _, m := range ns.resolve(path) {
-		dir, err1 := m.fs.ReadDir(m.translate(path))
-		if err1 != nil {
-			if err == nil {
-				err = err1
-			}
-			continue
-		}
-
-		if dir == nil {
-			dir = []os.FileInfo{}
-		}
-
-		if first == nil {
-			first = dir
-		}
-
-		// If we don't yet have Go files in 'all' and this directory
-		// has some, add all the files from this directory.
-		// Otherwise, only add subdirectories.
-		useFiles := false
-		if !haveGo {
-			for _, d := range dir {
-				if strings.HasSuffix(d.Name(), ".go") {
-					useFiles = true
-					haveGo = true
-					break
-				}
-			}
-		}
-
-		for _, d := range dir {
-			name := d.Name()
-			if (d.IsDir() || useFiles) && !haveName[name] {
-				haveName[name] = true
-				all = append(all, d)
-			}
-		}
-	}
-
-	// We didn't find any directories containing Go files.
-	// If some directory returned successfully, use that.
-	if !haveGo {
-		for _, d := range first {
-			if !haveName[d.Name()] {
-				haveName[d.Name()] = true
-				all = append(all, d)
-			}
-		}
-	}
-
-	// Built union.  Add any missing directories needed to reach mount points.
-	for old := range ns {
-		if hasPathPrefix(old, path) && old != path {
-			// Find next element after path in old.
-			elem := old[len(path):]
-			elem = strings.TrimPrefix(elem, "/")
-			if i := strings.Index(elem, "/"); i >= 0 {
-				elem = elem[:i]
-			}
-			if !haveName[elem] {
-				haveName[elem] = true
-				all = append(all, dirInfo(elem))
-			}
-		}
-	}
-
-	if len(all) == 0 {
-		return nil, err
-	}
-
-	sort.Sort(byName(all))
-	return all, nil
-}
-
-// RootType returns the RootType for the given path in the namespace.
-func (ns NameSpace) RootType(path string) RootType {
-	// We resolve the given path to a list of mountedFS and then return
-	// the root type for the filesystem which contains the path.
-	for _, m := range ns.resolve(path) {
-		_, err := m.fs.ReadDir(m.translate(path))
-		// Found a match, return the filesystem's root type
-		if err == nil {
-			return m.fs.RootType(path)
-		}
-	}
-	return ""
-}
-
-// byName implements sort.Interface.
-type byName []os.FileInfo
-
-func (f byName) Len() int           { return len(f) }
-func (f byName) Less(i, j int) bool { return f[i].Name() < f[j].Name() }
-func (f byName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
diff --git a/cmd/golangorg/godoc/vfs/os.go b/cmd/golangorg/godoc/vfs/os.go
deleted file mode 100644
index 35d0509..0000000
--- a/cmd/golangorg/godoc/vfs/os.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vfs
-
-import (
-	"fmt"
-	"go/build"
-	"io/ioutil"
-	"os"
-	pathpkg "path"
-	"path/filepath"
-	"runtime"
-)
-
-// We expose a new variable because otherwise we need to copy the findGOROOT logic again
-// from cmd/godoc which is already copied twice from the standard library.
-
-// GOROOT is the GOROOT path under which the godoc binary is running.
-// It is needed to check whether a filesystem root is under GOROOT or not.
-// This is set from cmd/godoc/main.go.
-var GOROOT = runtime.GOROOT()
-
-// OS returns an implementation of FileSystem reading from the
-// tree rooted at root.  Recording a root is convenient everywhere
-// but necessary on Windows, because the slash-separated path
-// passed to Open has no way to specify a drive letter.  Using a root
-// lets code refer to OS(`c:\`), OS(`d:\`) and so on.
-func OS(root string) FileSystem {
-	var t RootType
-	switch {
-	case root == GOROOT:
-		t = RootTypeGoRoot
-	case isGoPath(root):
-		t = RootTypeGoPath
-	}
-	return osFS{rootPath: root, rootType: t}
-}
-
-type osFS struct {
-	rootPath string
-	rootType RootType
-}
-
-func isGoPath(path string) bool {
-	for _, bp := range filepath.SplitList(build.Default.GOPATH) {
-		for _, gp := range filepath.SplitList(path) {
-			if bp == gp {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-func (root osFS) String() string { return "os(" + root.rootPath + ")" }
-
-// RootType returns the root type for the filesystem.
-//
-// Note that we ignore the path argument because roottype is a property of
-// this filesystem. But for other filesystems, the roottype might need to be
-// dynamically deduced at call time.
-func (root osFS) RootType(path string) RootType {
-	return root.rootType
-}
-
-func (root osFS) resolve(path string) string {
-	// Clean the path so that it cannot possibly begin with ../.
-	// If it did, the result of filepath.Join would be outside the
-	// tree rooted at root.  We probably won't ever see a path
-	// with .. in it, but be safe anyway.
-	path = pathpkg.Clean("/" + path)
-
-	return filepath.Join(root.rootPath, path)
-}
-
-func (root osFS) Open(path string) (ReadSeekCloser, error) {
-	f, err := os.Open(root.resolve(path))
-	if err != nil {
-		return nil, err
-	}
-	fi, err := f.Stat()
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	if fi.IsDir() {
-		f.Close()
-		return nil, fmt.Errorf("Open: %s is a directory", path)
-	}
-	return f, nil
-}
-
-func (root osFS) Lstat(path string) (os.FileInfo, error) {
-	return os.Lstat(root.resolve(path))
-}
-
-func (root osFS) Stat(path string) (os.FileInfo, error) {
-	return os.Stat(root.resolve(path))
-}
-
-func (root osFS) ReadDir(path string) ([]os.FileInfo, error) {
-	return ioutil.ReadDir(root.resolve(path)) // is sorted
-}
diff --git a/cmd/golangorg/godoc/vfs/os_test.go b/cmd/golangorg/godoc/vfs/os_test.go
deleted file mode 100644
index dc968f1..0000000
--- a/cmd/golangorg/godoc/vfs/os_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.
-
-package vfs_test
-
-import (
-	"os"
-	"runtime"
-	"testing"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-func TestRootType(t *testing.T) {
-	goPath := os.Getenv("GOPATH")
-	var expectedType vfs.RootType
-	if goPath == "" {
-		expectedType = ""
-	} else {
-		expectedType = vfs.RootTypeGoPath
-	}
-	tests := []struct {
-		path   string
-		fsType vfs.RootType
-	}{
-		{runtime.GOROOT(), vfs.RootTypeGoRoot},
-		{goPath, expectedType},
-		{"/tmp/", ""},
-	}
-
-	for _, item := range tests {
-		fs := vfs.OS(item.path)
-		if fs.RootType("path") != item.fsType {
-			t.Errorf("unexpected fsType. Expected- %v, Got- %v", item.fsType, fs.RootType("path"))
-		}
-	}
-}
diff --git a/cmd/golangorg/godoc/vfs/vfs.go b/cmd/golangorg/godoc/vfs/vfs.go
deleted file mode 100644
index 5d9d591..0000000
--- a/cmd/golangorg/godoc/vfs/vfs.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package vfs defines types for abstract file system access and provides an
-// implementation accessing the file system of the underlying OS.
-package vfs // import "golang.org/x/website/cmd/golangorg/godoc/vfs"
-
-import (
-	"io"
-	"io/ioutil"
-	"os"
-)
-
-// RootType indicates the type of files contained within a directory.
-//
-// It is used to indicate whether a directory is the root
-// of a GOROOT, a GOPATH, or neither.
-// An empty string represents the case when a directory is neither.
-type RootType string
-
-const (
-	RootTypeGoRoot RootType = "GOROOT"
-	RootTypeGoPath RootType = "GOPATH"
-)
-
-// The FileSystem interface specifies the methods godoc is using
-// to access the file system for which it serves documentation.
-type FileSystem interface {
-	Opener
-	Lstat(path string) (os.FileInfo, error)
-	Stat(path string) (os.FileInfo, error)
-	ReadDir(path string) ([]os.FileInfo, error)
-	RootType(path string) RootType
-	String() string
-}
-
-// Opener is a minimal virtual filesystem that can only open regular files.
-type Opener interface {
-	Open(name string) (ReadSeekCloser, error)
-}
-
-// A ReadSeekCloser can Read, Seek, and Close.
-type ReadSeekCloser interface {
-	io.Reader
-	io.Seeker
-	io.Closer
-}
-
-// ReadFile reads the file named by path from fs and returns the contents.
-func ReadFile(fs Opener, path string) ([]byte, error) {
-	rc, err := fs.Open(path)
-	if err != nil {
-		return nil, err
-	}
-	defer rc.Close()
-	return ioutil.ReadAll(rc)
-}
diff --git a/cmd/golangorg/godoc/vfs/zipfs/zipfs.go b/cmd/golangorg/godoc/vfs/zipfs/zipfs.go
deleted file mode 100644
index eace820..0000000
--- a/cmd/golangorg/godoc/vfs/zipfs/zipfs.go
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package zipfs file provides an implementation of the FileSystem
-// interface based on the contents of a .zip file.
-//
-// Assumptions:
-//
-// - The file paths stored in the zip file must use a slash ('/') as path
-//   separator; and they must be relative (i.e., they must not start with
-//   a '/' - this is usually the case if the file was created w/o special
-//   options).
-// - The zip file system treats the file paths found in the zip internally
-//   like absolute paths w/o a leading '/'; i.e., the paths are considered
-//   relative to the root of the file system.
-// - All path arguments to file system methods must be absolute paths.
-package zipfs // import "golang.org/x/website/cmd/golangorg/godoc/vfs/zipfs"
-
-import (
-	"archive/zip"
-	"fmt"
-	"go/build"
-	"io"
-	"os"
-	"path"
-	"path/filepath"
-	"sort"
-	"strings"
-	"time"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-// zipFI is the zip-file based implementation of FileInfo
-type zipFI struct {
-	name string    // directory-local name
-	file *zip.File // nil for a directory
-}
-
-func (fi zipFI) Name() string {
-	return fi.name
-}
-
-func (fi zipFI) Size() int64 {
-	if f := fi.file; f != nil {
-		return int64(f.UncompressedSize)
-	}
-	return 0 // directory
-}
-
-func (fi zipFI) ModTime() time.Time {
-	if f := fi.file; f != nil {
-		return f.ModTime()
-	}
-	return time.Time{} // directory has no modified time entry
-}
-
-func (fi zipFI) Mode() os.FileMode {
-	if fi.file == nil {
-		// Unix directories typically are executable, hence 555.
-		return os.ModeDir | 0555
-	}
-	return 0444
-}
-
-func (fi zipFI) IsDir() bool {
-	return fi.file == nil
-}
-
-func (fi zipFI) Sys() interface{} {
-	return nil
-}
-
-// zipFS is the zip-file based implementation of FileSystem
-type zipFS struct {
-	*zip.ReadCloser
-	list zipList
-	name string
-}
-
-func (fs *zipFS) String() string {
-	return "zip(" + fs.name + ")"
-}
-
-func (fs *zipFS) RootType(abspath string) vfs.RootType {
-	var t vfs.RootType
-	switch {
-	case exists(path.Join(vfs.GOROOT, abspath)):
-		t = vfs.RootTypeGoRoot
-	case isGoPath(abspath):
-		t = vfs.RootTypeGoPath
-	}
-	return t
-}
-
-func isGoPath(abspath string) bool {
-	for _, p := range filepath.SplitList(build.Default.GOPATH) {
-		if exists(path.Join(p, abspath)) {
-			return true
-		}
-	}
-	return false
-}
-
-func exists(path string) bool {
-	_, err := os.Stat(path)
-	return err == nil
-}
-
-func (fs *zipFS) Close() error {
-	fs.list = nil
-	return fs.ReadCloser.Close()
-}
-
-func zipPath(name string) (string, error) {
-	name = path.Clean(name)
-	if !path.IsAbs(name) {
-		return "", fmt.Errorf("stat: not an absolute path: %s", name)
-	}
-	return name[1:], nil // strip leading '/'
-}
-
-func isRoot(abspath string) bool {
-	return path.Clean(abspath) == "/"
-}
-
-func (fs *zipFS) stat(abspath string) (int, zipFI, error) {
-	if isRoot(abspath) {
-		return 0, zipFI{
-			name: "",
-			file: nil,
-		}, nil
-	}
-	zippath, err := zipPath(abspath)
-	if err != nil {
-		return 0, zipFI{}, err
-	}
-	i, exact := fs.list.lookup(zippath)
-	if i < 0 {
-		// zippath has leading '/' stripped - print it explicitly
-		return -1, zipFI{}, &os.PathError{Path: "/" + zippath, Err: os.ErrNotExist}
-	}
-	_, name := path.Split(zippath)
-	var file *zip.File
-	if exact {
-		file = fs.list[i] // exact match found - must be a file
-	}
-	return i, zipFI{name, file}, nil
-}
-
-func (fs *zipFS) Open(abspath string) (vfs.ReadSeekCloser, error) {
-	_, fi, err := fs.stat(abspath)
-	if err != nil {
-		return nil, err
-	}
-	if fi.IsDir() {
-		return nil, fmt.Errorf("Open: %s is a directory", abspath)
-	}
-	r, err := fi.file.Open()
-	if err != nil {
-		return nil, err
-	}
-	return &zipSeek{fi.file, r}, nil
-}
-
-type zipSeek struct {
-	file *zip.File
-	io.ReadCloser
-}
-
-func (f *zipSeek) Seek(offset int64, whence int) (int64, error) {
-	if whence == 0 && offset == 0 {
-		r, err := f.file.Open()
-		if err != nil {
-			return 0, err
-		}
-		f.Close()
-		f.ReadCloser = r
-		return 0, nil
-	}
-	return 0, fmt.Errorf("unsupported Seek in %s", f.file.Name)
-}
-
-func (fs *zipFS) Lstat(abspath string) (os.FileInfo, error) {
-	_, fi, err := fs.stat(abspath)
-	return fi, err
-}
-
-func (fs *zipFS) Stat(abspath string) (os.FileInfo, error) {
-	_, fi, err := fs.stat(abspath)
-	return fi, err
-}
-
-func (fs *zipFS) ReadDir(abspath string) ([]os.FileInfo, error) {
-	i, fi, err := fs.stat(abspath)
-	if err != nil {
-		return nil, err
-	}
-	if !fi.IsDir() {
-		return nil, fmt.Errorf("ReadDir: %s is not a directory", abspath)
-	}
-
-	var list []os.FileInfo
-
-	// make dirname the prefix that file names must start with to be considered
-	// in this directory. we must special case the root directory because, per
-	// the spec of this package, zip file entries MUST NOT start with /, so we
-	// should not append /, as we would in every other case.
-	var dirname string
-	if isRoot(abspath) {
-		dirname = ""
-	} else {
-		zippath, err := zipPath(abspath)
-		if err != nil {
-			return nil, err
-		}
-		dirname = zippath + "/"
-	}
-	prevname := ""
-	for _, e := range fs.list[i:] {
-		if !strings.HasPrefix(e.Name, dirname) {
-			break // not in the same directory anymore
-		}
-		name := e.Name[len(dirname):] // local name
-		file := e
-		if i := strings.IndexRune(name, '/'); i >= 0 {
-			// We infer directories from files in subdirectories.
-			// If we have x/y, return a directory entry for x.
-			name = name[0:i] // keep local directory name only
-			file = nil
-		}
-		// If we have x/y and x/z, don't return two directory entries for x.
-		// TODO(gri): It should be possible to do this more efficiently
-		// by determining the (fs.list) range of local directory entries
-		// (via two binary searches).
-		if name != prevname {
-			list = append(list, zipFI{name, file})
-			prevname = name
-		}
-	}
-
-	return list, nil
-}
-
-func New(rc *zip.ReadCloser, name string) vfs.FileSystem {
-	list := make(zipList, len(rc.File))
-	copy(list, rc.File) // sort a copy of rc.File
-	sort.Sort(list)
-	return &zipFS{rc, list, name}
-}
-
-type zipList []*zip.File
-
-// zipList implements sort.Interface
-func (z zipList) Len() int           { return len(z) }
-func (z zipList) Less(i, j int) bool { return z[i].Name < z[j].Name }
-func (z zipList) Swap(i, j int)      { z[i], z[j] = z[j], z[i] }
-
-// lookup returns the smallest index of an entry with an exact match
-// for name, or an inexact match starting with name/. If there is no
-// such entry, the result is -1, false.
-func (z zipList) lookup(name string) (index int, exact bool) {
-	// look for exact match first (name comes before name/ in z)
-	i := sort.Search(len(z), func(i int) bool {
-		return name <= z[i].Name
-	})
-	if i >= len(z) {
-		return -1, false
-	}
-	// 0 <= i < len(z)
-	if z[i].Name == name {
-		return i, true
-	}
-
-	// look for inexact match (must be in z[i:], if present)
-	z = z[i:]
-	name += "/"
-	j := sort.Search(len(z), func(i int) bool {
-		return name <= z[i].Name
-	})
-	if j >= len(z) {
-		return -1, false
-	}
-	// 0 <= j < len(z)
-	if strings.HasPrefix(z[j].Name, name) {
-		return i + j, false
-	}
-
-	return -1, false
-}
diff --git a/cmd/golangorg/godoc/vfs/zipfs/zipfs_test.go b/cmd/golangorg/godoc/vfs/zipfs/zipfs_test.go
deleted file mode 100644
index 70899ad..0000000
--- a/cmd/golangorg/godoc/vfs/zipfs/zipfs_test.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.package zipfs
-package zipfs
-
-import (
-	"archive/zip"
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"reflect"
-	"testing"
-
-	"golang.org/x/website/cmd/golangorg/godoc/vfs"
-)
-
-var (
-
-	// files to use to build zip used by zipfs in testing; maps path : contents
-	files = map[string]string{"foo": "foo", "bar/baz": "baz", "a/b/c": "c"}
-
-	// expected info for each entry in a file system described by files
-	tests = []struct {
-		Path      string
-		IsDir     bool
-		IsRegular bool
-		Name      string
-		Contents  string
-		Files     map[string]bool
-	}{
-		{"/", true, false, "", "", map[string]bool{"foo": true, "bar": true, "a": true}},
-		{"//", true, false, "", "", map[string]bool{"foo": true, "bar": true, "a": true}},
-		{"/foo", false, true, "foo", "foo", nil},
-		{"/foo/", false, true, "foo", "foo", nil},
-		{"/foo//", false, true, "foo", "foo", nil},
-		{"/bar", true, false, "bar", "", map[string]bool{"baz": true}},
-		{"/bar/", true, false, "bar", "", map[string]bool{"baz": true}},
-		{"/bar/baz", false, true, "baz", "baz", nil},
-		{"//bar//baz", false, true, "baz", "baz", nil},
-		{"/a/b", true, false, "b", "", map[string]bool{"c": true}},
-	}
-
-	// to be initialized in setup()
-	fs        vfs.FileSystem
-	statFuncs []statFunc
-)
-
-type statFunc struct {
-	Name string
-	Func func(string) (os.FileInfo, error)
-}
-
-func TestMain(t *testing.M) {
-	if err := setup(); err != nil {
-		fmt.Fprintf(os.Stderr, "Error setting up zipfs testing state: %v.\n", err)
-		os.Exit(1)
-	}
-	os.Exit(t.Run())
-}
-
-// setups state each of the tests uses
-func setup() error {
-	// create zipfs
-	b := new(bytes.Buffer)
-	zw := zip.NewWriter(b)
-	for file, contents := range files {
-		w, err := zw.Create(file)
-		if err != nil {
-			return err
-		}
-		_, err = io.WriteString(w, contents)
-		if err != nil {
-			return err
-		}
-	}
-	zw.Close()
-	zr, err := zip.NewReader(bytes.NewReader(b.Bytes()), int64(b.Len()))
-	if err != nil {
-		return err
-	}
-	rc := &zip.ReadCloser{
-		Reader: *zr,
-	}
-	fs = New(rc, "foo")
-
-	// pull out different stat functions
-	statFuncs = []statFunc{
-		{"Stat", fs.Stat},
-		{"Lstat", fs.Lstat},
-	}
-
-	return nil
-}
-
-func TestZipFSReadDir(t *testing.T) {
-	for _, test := range tests {
-		if test.IsDir {
-			infos, err := fs.ReadDir(test.Path)
-			if err != nil {
-				t.Errorf("Failed to read directory %v\n", test.Path)
-				continue
-			}
-			got := make(map[string]bool)
-			for _, info := range infos {
-				got[info.Name()] = true
-			}
-			if want := test.Files; !reflect.DeepEqual(got, want) {
-				t.Errorf("ReadDir %v got %v\nwanted %v\n", test.Path, got, want)
-			}
-		}
-	}
-}
-
-func TestZipFSStatFuncs(t *testing.T) {
-	for _, test := range tests {
-		for _, statFunc := range statFuncs {
-
-			// test can stat
-			info, err := statFunc.Func(test.Path)
-			if err != nil {
-				t.Errorf("Unexpected error using %v for %v: %v\n", statFunc.Name, test.Path, err)
-				continue
-			}
-
-			// test info.Name()
-			if got, want := info.Name(), test.Name; got != want {
-				t.Errorf("Using %v for %v info.Name() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
-			}
-			// test info.IsDir()
-			if got, want := info.IsDir(), test.IsDir; got != want {
-				t.Errorf("Using %v for %v info.IsDir() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
-			}
-			// test info.Mode().IsDir()
-			if got, want := info.Mode().IsDir(), test.IsDir; got != want {
-				t.Errorf("Using %v for %v info.Mode().IsDir() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
-			}
-			// test info.Mode().IsRegular()
-			if got, want := info.Mode().IsRegular(), test.IsRegular; got != want {
-				t.Errorf("Using %v for %v info.Mode().IsRegular() got %v wanted %v\n", statFunc.Name, test.Path, got, want)
-			}
-			// test info.Size()
-			if test.IsRegular {
-				if got, want := info.Size(), int64(len(test.Contents)); got != want {
-					t.Errorf("Using %v for %v inf.Size() got %v wanted %v", statFunc.Name, test.Path, got, want)
-				}
-			}
-		}
-	}
-}
-
-func TestZipFSNotExist(t *testing.T) {
-	_, err := fs.Open("/does-not-exist")
-	if err == nil {
-		t.Fatalf("Expected an error.\n")
-	}
-	if !os.IsNotExist(err) {
-		t.Errorf("Expected an error satisfying os.IsNotExist: %v\n", err)
-	}
-}
-
-func TestZipFSOpenSeek(t *testing.T) {
-	for _, test := range tests {
-		if test.IsRegular {
-
-			// test Open()
-			f, err := fs.Open(test.Path)
-			if err != nil {
-				t.Error(err)
-				return
-			}
-			defer f.Close()
-
-			// test Seek() multiple times
-			for i := 0; i < 3; i++ {
-				all, err := ioutil.ReadAll(f)
-				if err != nil {
-					t.Error(err)
-					return
-				}
-				if got, want := string(all), test.Contents; got != want {
-					t.Errorf("File contents for %v got %v wanted %v\n", test.Path, got, want)
-				}
-				f.Seek(0, 0)
-			}
-		}
-	}
-}
-
-func TestRootType(t *testing.T) {
-	tests := []struct {
-		path   string
-		fsType vfs.RootType
-	}{
-		{"/src/net/http", vfs.RootTypeGoRoot},
-		{"/src/badpath", ""},
-		{"/", vfs.RootTypeGoRoot},
-	}
-
-	for _, item := range tests {
-		if fs.RootType(item.path) != item.fsType {
-			t.Errorf("unexpected fsType. Expected- %v, Got- %v", item.fsType, fs.RootType(item.path))
-		}
-	}
-}
